Time to multithread?

I am in the process of working out a way to handle entities in my game. I decided to go with a Factory class that handles this stuff.

It will be responsible for updating and deleting entites from the world, from drops, bullets, particles etc etc.

Problem being, it seems to freeze my game when doing large operations. I have a Grenade class that you can throw, it explodes and creates around 45 Shrapnel objects around it (box2d) and accelerates them away from the explosion point.

This does 3 things, it first loops through the Explosives array of Shrapnel, fires them all in there direction.
It adds these shrapnels objects to another array in the Factory class which updates them, then removes them if needed
The renderer, well it renderes the graphics.

This means there is pretty much 3 loops running, only 1 of which handles any graphics. Should I move my logic onto a seperate thread? I have the thread setup and ready to go but is there something else I can do?

Here is some code for you to gander over:

Player presses G, it calls this method and creates a small rectangle which acts as a grenade

/**
	 * Throw this explosive in the direction of the thrower
	 * 
	 * @param postion
	 *            the starting position
	 * @param angle
	 *            the angle to be thrown, used to calculate the trajectory
	 * @param power
	 *            power of the throw
	 */
	public void throwExplosive(Vector2 postion, float angle, float power) {
		createBody(BodyType.DynamicBody, postion.x, postion.y, angle);
		createPolyFixture(0.10f, 0.10f, 0.10f, 0.10f, 0.15f, false);

		createTime = TimeUtils.nanoTime();

		body.applyLinearImpulse(power * MathUtils.cos(angle),
				power * MathUtils.sin(angle), 0, 0, true);

		body.setUserData(this);
		isThrown = true;
	}

Then this grenade gets added to an array for updating



/**
	 * Update this explosive object, keeps detonation timers in check
	 */
	public void update() {
		if (isThrown) {
			if (TimeUtils.nanoTime() - createTime > fragTime) {
				detonate(body.getPosition());
				isThrown = false;
			}
		}

	}


Then this is called

/**
	 * Detonate this explosive and send shrapnel flying out
	 */
	public void detonate(Vector2 position) {
		for (Shrapnel shrapnel : this.shrapnel) {
			shrapnel.fire(position);
		}

	}

Which basically does this



/**
	 * Fire this shrapnel in its assigned direction, call this to create an
	 * explosion type effect
	 */
	public void fire(Vector2 position) {
		createBody(BodyType.DynamicBody, position.x, position.y, angle);
		createPolyFixture(0.1f, 0.1f, 0.75f, 0, 0.2f, true);
		createTime = TimeUtils.nanoTime();
		body.applyLinearImpulse(speed * MathUtils.cos(angle),
				speed * MathUtils.sin(angle), 0, 0, true);
		
		Level.factory.projectiles.add(this);

		body.setUserData(this);
	}


If you are wondering when the shrapnel gets added to the array, it happens in the constructor of whatever explosive class is being called, currently I just have a Grenade class:



public Grenade() {

		fragTime = MathUtility.secondToNano(3);

		float angle = 0;
		for (int count = 0; count < 45; count++) {
			Shrapnel shrapnel = new Shrapnel(this, true, position, angle,
					MathUtility.secondToNano(5), 0.05f, 3);
			this.shrapnel.add(shrapnel);
			angle += 8 * MathUtils.degRad;
		}

	}


This is one of “those” kinds of replies but… if you’re asking others whether it’s time to multithread… it’s not.

Cas :slight_smile:

Ah right I guess it is one of those things that “if it’s time, you will know”.

However I shall define my question into a more general one…

I have like 3 for loops that run on the same thread, as well as the rendering…should I multithread in order to prevent lockups? Considering in the future I intend to have plenty of shit flying around (bullets, bombs, particles etc etc)

You’re having performance problems with 45 entities?

As Cas said, if you think multithreading is the right direction, it’s not. I won’t deny that you might alleviate the initial performance issue while going down this route but you really haven’t solved your problem. You now have multithreading (adding huge complexity) while the underlying root problem (why 45 entities cannot be processed in one frame) is still not solved.

should I multithread in order to prevent lockups?

No. Chances are you’ll introduce new lockups (deadlocks) and erroneous behavior that’s going to be a bitch to debug because of the multiple threads.

After looking at your code, allocating each shrapnel object on the heap is not going to scale properly. A grenade is going to explode anyway right? It’s going to have shrapnel? Why not when creating the grenade ensure that its data includes its shrapnel.

After going down this route, ask yourself, should each individual grenade be allocated on the heap too?

At this stage yes, my code is ofc not refactored at all. However I have the fear that with thousands of entities I might have the problem.

Saying this, by the time I wrote the OP and replied to this I fixed the performance issue by fixing how the collision, creation and destruction of the shrapnel is handled.

Right, got it. I will read further however to learn why these things can happen. Thanks.

Ok regarding how it is allocated, unless my game is taking up several gigs of ram while running, it should be ok right?

Currently as it stands, upon creation of a grenade, as in if one is lying on the ground ready to be picked up, in the inventory of an entity or whatever…each grenade object has an array that holds all it’s shrapnel (this makes sense, since this is technically what grenades do). So upon explosion I simply loop through this array, toss every piece of shrapnel out and remove each peice from that array and hand it to the factory to update and process/remove them from the world.

Don’t worry about threads right now as they really are a monumental pain to get right. Single-threaded you should be good for a couple of thousand “things” all doing their business in your game loop, and time enough for rendering too.

Single-threaded you’ll have no chance of lock-ups at all.

Cas :slight_smile:

What I am saying is that having dynamically allocated memory (new) and manipulating dynamic collections (e.g. Lists) comes with a performance cost. For example, removing a shrapnel piece from a basic list can be on the order of O(n). That’s a price you won’t want to be paying every frame.

Others may disagree but I don’t believe that classic OOP should used to the same extent in games. Before OOP imagine writing a game where performance and memory usage was a huge concern. Most games can be written to manipulate a fixed set of data. Think data-driven instead of OO.

Take for example grenades and shrapnel. Let’s put a reasonable limit… no more than 200 grenades on screen at once.

The grenade structure looks like this:


class Shrapnel {
  boolean visible;
  int x;
  int y;
}

class Grenade {
  boolean visible;
  int x;
  int y;
  Shrapnel[45] shrapnel;
}

Now allocate it all just once at the start of the game:


Grenade[200] grenades = new ...

During your game loop you can iterate over the grenades array updating data as needed. No allocation is happening, no list insertion, no list deletion, no GC worries.

What does your factory’s add and delete methods look like?

Don’t fix the problem that doesn’t exist…

I agree with the multithreading isn’t a good question here, but some comments.

You don’t want to call nanoTime at a high rate. Not an issue here, but worth noting. (serializing instruction)

dead-locks: they’re dead easy to avoid. Never use locks. That way you avoid starvation as well and the main reason why multithreading has the rep of being hard.

Lock-free multi-threaded programming is a different kind of hard, though…

Cas :slight_smile:

This is very good, I never though of it like that.

At the moment it is mainly just an update method, it runs constantly looping through currently 2 arrays:



/* If the world is not in a timestep, start removing bodies */
			if (!world.isLocked()) {
				for (Box2DObject object : toDelete) {
					if (object.getBody() != null)
						world.destroyBody(object.getBody());
					toDelete.removeValue(object, true);
				}

			}
			/*
			 * Update all the bullets currently in flight and remove as
			 * necessary
			 */
			for (int projectile = 0; projectile < projectiles.size; projectile++) {
				Projectile p = projectiles.get(projectile);
				p.update();
				if (p.isCanExpire()) {
					toDelete.add(p);
					this.projectiles.removeValue(p, true);

				}
			}


This is not optimal however, there is no need to loop over arrays like this, for instance there is no real need to update things that are not moving and such, if that makes sense. It needs greatly optimized but as it stands, it is doing the job.

I will later add a timer/check mechanics that only runs when needed, spread it out via methods.

Usually removing something from a Collection such as a List is a very expensive process.

Try this e.g.: http://www.java-gaming.org/index.php?topic=27017.0

But fascinating and kind of fun. I recommend perusing principles of “Functional Programming” for ideas.

It’s quite a new concept to me, and I like what I see so far. Unfortunately Java “the language” doesn’t have a lot of sugar to support it like it had for old-fashioned synchronization.

Cas :slight_smile:

I would like to thank everyone for their replies, I have taken a step back to have a look at my code and fixed quite a few badly (very) written bits that were the main cause for lock ups.

The main one was upon explosion of my grenade, I was setting the shrapnels collision data…So briefly every single piece of shrapnel was overlapping for 1 frame before they were told “don’t hit each other”.

Fixed that.

But this is just some fun stuff I am screwing with on the side while I implement path finding, just to give me a break from debugging that code.

Really enjoying it so far :smiley: