Memory slowly ticks up despite removing entities from the world [Solved]


(Ethan) #1

Basically I have an entity called ArrowTrap which uses a ticker to send out a constant stream of arrows. After an arrow entity exists for so many ticks, I remove it from the world.

world.remove(this);

This means that the first arrow created by the ArrowTrap is also the first arrow removed from the world. As such, the rate at which the arrows are created means that with one ArrowTrap the entity count maxes out and staggers between 103-104.

However, my memory slowly ticks up despite removing these entities (0.01 every second). Despite the arrow count maxing out. Is there a way to prevent the memory from constantly rising.


(Justin Wolf) #2

Use world.create() and world.recycle() instead. I imagine flash is storing references to all these new objects you’re creating at every interval - thus increasing your memory usage. When you recycle an Entity, it will be stored for later use using the create() function. So instead of constantly creating brand new Entities, you are simply pulling recycled entities from a pool of objects that were removed previously. If there aren’t any objects in that pool, it will simply make a new one with no trouble.

Here’s a common way to utilize this method:


(Ethan) #3

To implement that solution, would I have to completely rewrite how the parameters of my entities are passed in? Because I don’t see a way to use world.create with a class that takes arguments.

Currently I have constructors that take relevant information (position, the entity it is created from, it’s facing, etc…) to create each individual entity. For example, this is a function in my ArrowTrap entity that handles the creation of the arrows. It chooses a different case depending on the direction the trap is facing and then adds and arrow of the appropriate direction and passes itself as the entity the arrows will come from.

private function shootArrow():void
	{
		
		switch(facing) 
		{
			case "down":
				world.create(Arrow(this, "down"), true);
				break;
			case "up":
				world.add(new Arrow(this, "up"));
				break;
			case "right":
				world.add(new Arrow(this, "right"));
				break;
			case "left":
				world.add(new Arrow(this, "left"));
				break;
				
		}
		
	}

(Jacob Albano) #4

The usual approach is to create a method on your entity called setup() or something, and use that to do the work your constructor would usually do.

Arrow(world.create(Arrow)).setup(this, facing);

There is a way we could add support for constructor arguments in create(), but it’s not in yet. I plan to bring it up for discussion pretty soon.


(Ethan) #5

I adjusted it to use create and recycle but I ran into an issue. It creates the entities correctly up until it hits what should be the first recycled entity (right after the first arrow times out and is world.recycle(this);). The entity counter goes down at that point until every arrow has timed out and been recycled but not reused.

My create call looks like this

Arrow(world.create(Arrow, true)).init(“down”, this);


(Jacob Albano) #6

So the problem is that it doesn’t add the recycled entity? Are you doing anything in the removed() function, perhaps?


(Ethan) #7

Correct. It will reach 103 entities (which is how many arrows get created before the first arrow times out) and then ticks down until all the arrows have been removed. The arrows aren’t being reused by the create call.

My remove function looks like this and I call it on every tick of the arrows update()

private function arrowTimeout():void
	{
		if (timer >= 1000)
		{
			world.recycle(this);
			
			//graphic = null;
		}
		else if (timer < 1000)
			timer++;
	}

(Jacob Albano) #8

I meant the function on Entity that you override. removed(). :wink:


(Ethan) #9

Oh, I never touched removed(). So I haven’t overridden it.


(Jacob Albano) #10

Okay, just making sure.

You may have thought of this already, but are you ever resetting the timer variable? If it stays at 1000 when you re-add it, it’ll just get removed right away.


(Ethan) #11

Hah, no I didn’t consider that actually. I had thought about the position not resetting but not that. Turns out that was the issue.

Now I have an entertaining bug. The recycled arrows that have collided with a block now are spawned without moving and then they get linked to the block as soon as it is moved (because I coded arrows to stop and then stick to blocks upon collision). It should be pretty easy to fix.

Thanks for the help!


(Jacob Albano) #12

Sure, I’m glad we figured it out!