Mark Abent takes us through a fatal error that happens when an AI Constellation loads.
As per usual, anything said during the show is subject to change by CIG and may not always be accurate at the time of posting. Also any mistakes you see that I may have missed, please let me know so I can correct them. Enjoy the show!
Crash when bringing in an AI Constellation
A Constellation is composed of a bunch of entities(physics, geometry,etc) and if they want to do an update it goes through this batch updater to get batched and then updated, you’re not supposed to register these updates if the entity is shutting down and if you’re trying to register an update during this phase, things go wrong
When something gets deleted it’s marked as garbage, but doesn’t mean it’s going to be removed, the code is only checking to see if it’s in the garbage bin
You could register during an update but it should just abort out and only go wrong during the the actual shutdown phase
Fix is to change the code that when something is thrown in the garbage and someone registers for an update, it’ll just get ignored
Mark Abent: Hey everyone, welcome to Bugsmashers. I’m your host Mark Abent, I’m here to take you behind the scenes on how we smash bugs.
Hey you guys, I am here in another fun test level and got a report of a bug, I should say a crash when we bring in an AI Constellation so let’s give this a try. Woo Constellation, drag that guy in, let it load… oh, big ship. Building all the shaders for him, all right so let’s pop in the game. Pop out of the game and see if we can get that crash and crash? Ah, crash.
So this is actually a specialty crash, we have these things known as fatal errors when the code gets into a specific section of code the programmer may add this fatal errors saying you should never get here, if you get here… here is a complete call stack so we can log it and try to figure out how we got to that spot and so this specific call stack or should I say crash. Saved, not saved level, hit the break point.
We’ll go to here, so this is our component batch updater so we have an entity or this Constellation and then maybe composed of a bunch of entities… I’m sorry, components like physics, geometry, interactions, all sorts of things and if they want to do an update they go through this batch updater so they can get batched and then multi threaded update or in the regular main thread update.
You’re not supposed to be able to register these updates when the entity is shutting down, cause when we shut down the entity we remove all the components, remove all the updates and so if you’re trying to register an update during this phase… well, bad things will happen. So we want to know when people get to this point and unfortunately the editor is a little special child where on the same frame that we destroy… the interior or should I say all the entities in the level we actually created again.
So what we have is the Constellation getting deleted and then getting created and when something gets deleted we mark it as garbage, and that’s how we know it’s going away. Doesn’t necessarily mean it’s going to be removed, it’s basically ‘oh I have some trash cans, I throw some trash away. Garbageman hasn’t picked it up yet, but he might tomorrow, he might today, might sometimes later’. This bit of code was only checking to see if it’s in the garbage bin, technically you shouldn’t be able to register when you’re in an update… when you’re in the garbage but it shouldn’t be a fatal error either because you could register but it should abort out and only during the actual shutdown phase should this go south.
We’re going to change this bit of code so if we’re in the garbage and our entity is actually really, really shutting down the garbage man is coming to pick him up. Then we’ll fatal error because something seriously has gone wrong, otherwise we’ll just skip out because… and we only want, actually we just want to skip out all the time. We only want the fatal error if we’re shutting down the actual entity.
So we threw it in the garbage bin, if someone registers for an update, it’ll just get ignored because this thing is going to get deleted. It’s just one of those funky things where, yeah you marked it as deleted but none of the components on there know it’s getting deleted yet because well, we’re not in the process. So for now we just go, ‘yeah we’ll just ignore this update because trust us it’s going to get removed’ and we won’t crash the game horribly. Instead we’ll just softly ignore it and the game code will delete it sometime later and everyone will be happy.
So, let’s give this a compile. All right, we’re back in the amazing test level see what happens when we plop down another AI Constellation… let it load. Ha, there we go and now we’ll hop in game mode, and then pop out of game mode and no crash, right? Ah, no crash, perfect. So, in the deletion phase is a little bit tricky cause you always have to inform certain systems some things are getting deleted but you don’t want to inform certain things until you’re in the actual, ‘yes, this is the deleted phase’.
Since this is one of those lower end systems it needs to know exactly where we’re at and then once we get to the actual shutdown then the components can know where they’re at too. So that in between phase is kind of one of those weird things you have to get just right especially when editor and game code which do things a little bit differently. Hope you guys enjoyed, til next time.
So, as you guys saw we had a little bit of issue with the designers, they were hitting a part of the code that would stop the game cause they were hitting a spot we did not want the code to run in that area. At the same the editor was doing something special where getting to that section of the error was technically a legit path, so we had change to the code a bit so that it still will not hit that specific section while still allowing the editor to do its little specialty. Just another day in game development, hope you guys enjoyed. Til next time.