🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Payloads, fires, and button materials

Published October 23, 2013
Advertisement
aVYIQTc.jpg

Not a huge day today. Only got to spend about an hour on it at work. Since I didn't really want to get too involved in anything big, instead I just ported over a couple projectile payload components, including the flame burst component above. Also, I made a Loot button icon, and in the process fiddled a little bit with the materials to render the buttons, making them a little less flat. They're not production buttons, but at least they don't really annoy me too bad anymore.

While doing the payloads, I did run into some issues with certain objects being kept alive when they shouldn't be. I haven't gotten entirely to the bottom of it yet, but I suspect it has to do with garbage collection. I'll probably want to review my policies on object destruction to make sure that things are being handled correctly. While I've fixed the outward issues, I have a nagging fear that somehow I'm leaking memory.

The issue was with nodes being removed, but not actually being removed. That is, you can call Remove() on a node and it will remove itself from the scene. However, if there is something keeping the node alive (a shared pointer somewhere) then it doesn't get deleted, and its components will keep updating. I discovered the issue when porting the flame burst payload. I'm having my payloads fire when they receive the Stop() call, called by the Lua scripting system when a node is deleted. As long as the node is properly deleted, Stop() gets called on all ScriptObjects belonging to it, so if one of those is a Payload then it will fire, spawning whatever objects it needs to spawn to do its thing before the node goes out of existence.

However, I noticed that if I fired a fireball a long ways away, it would properly trigger its payload when the fireball was deleted, but if I fired it nearby, then not only would it fail to trigger the payload (indicating the fireball projectile wasn't being properly deleted) but it would also interfere with the floating combat text indicating the resources spent to cast the fireball. The key was if the projectile hit while that combat text was still alive; if this happened, then neither the combat text nor the projectile would die properly, and the result would be a piece of combat text zipping up the screen until it shot out of sight, and a blazing particle fireball cascading through the ground and plunging down, down, down into infinity rather than exploding into a burst of flame like a good fireball should do. The payload was never being triggered.

This leads me to believe that something, somewhere, is causing references to be stored for these two objects when they occur together, but it only happens when both exist at the same time. You can imagine, it's kind of a baffling bug. I "fixed" it by implementing a Node remover, a system that lives on the scene itself and which handles node removal at a certain point during the update cycle. Any node that wants to be removed is no longer allowed to remove itself; instead, it sends an event that is picked up by the Node Remover, with itself as payload data for the event. The Node Remover queues up all nodes, then iterates the list of nodes to remove, removes all of their components and children, then removes them.

I did it this way, since it is not a good idea to call RemoveComponents() on a Node during Update, since that will remove all components, even the component that is currently executing and calling RemoveComponents. Crash. So instead, I have to clear the components at a safe time, when no component on the node is executing any method. With this implementation, projectiles correctly trigger their payloads, flame bursts correctly spawn, burn for awhile and then die.

However... I get the sneaking suspicion that, while I might be removing components, whatever references were keeping the Nodes alive and preventing them from dying properly are still holding those references. While the components are being removed, I think the nodes themselves might be sticking around somehow, and that means I'm leaking.

So, that'll probably be my project for tomorrow: see if I can track down whoever is guilty of hanging onto node references, and ensure that they are suitably punished.
5 likes 3 comments

Comments

MARS_999

coming along very nicely!

How are you making those GUI widget buttons? What art program or by hand?

Thanks!

October 23, 2013 06:34 AM
JTippetts

I use Blender, and the Cycles renderer for the buttons.

Turns out, with the change to dispose of nodes outside of the update event, I'm not leaking nodes as I feared. I wrote code to dump ref counts of objects when they are disposed through the node remover, and it shows that all the nodes that are getting dumped go into it with a single ref count, so I feel fairly confident that they are being properly disposed of now.

Tomorrow, work schedule willing, I'm going to start bringing back in the actual stats and combat systems.

October 24, 2013 03:48 AM
JTippetts
8Ga4eEv.jpg
October 24, 2013 04:00 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement