[0.14.22] My mod can cause a full game crash
Posted: Fri Feb 17, 2017 1:17 am
Found a crash while testing a mod I've been making.
Log/stack trace (on Windows, singleplayer): http://pastebin.com/q66BWpDj
Log/stack trace (on Linux, multiplayer): http://pastebin.com/Si2zRuPG
Broken version of the mod is attached to this post, it's the only mod you need to load.
Steps to reproduce:
1. Create a new world
2. Use this command to give you everything you need:
3. Place the "Factory building" on the ground
4. Walk to the doorway and press your pick up item key to enter the factory
5. Place the car inside the factory
6. Destroy the car with your gun (this seems to work with any building entity, I just happened to use a car)
7. Exit the factory by walking to the exit and pressing the pick up item key again
(Do these both quickly, I'm guessing the crash probably won't occur if the temporary entities expire)
8. Pick up the factory building
9. Place it down again. The game should crash.
What's happening?
The crash is occurring in the Factory:restore_entities() function. Factory buildings should not perform any action while the player has picked it up in their inventory, so when you pick up a factory all the entities in the factory are set to
operable: false
active: false
minable: false
destructible: false
The state of these flags before changing them is stored in a .restore = {} array. When the factory is placed again, each of these entities, if valid, has their state restored to how it was before.
The restore function in question:
I can prevent the crash by simply not storing or changing these flags for any entities which have the type: corpse, smoke, particle. I've already done this, but obviously a crash is a crash and should still be reported.
Log/stack trace (on Windows, singleplayer): http://pastebin.com/q66BWpDj
Log/stack trace (on Linux, multiplayer): http://pastebin.com/Si2zRuPG
Broken version of the mod is attached to this post, it's the only mod you need to load.
Steps to reproduce:
1. Create a new world
2. Use this command to give you everything you need:
Code: Select all
/c game.player.clear_items_inside() game.player.insert({name='fre_factory', count=1}) game.player.insert('car') game.player.insert('steel-axe') game.player.insert('submachine-gun') game.player.insert('piercing-rounds-magazine') game.player.force.set_ammo_damage_modifier('bullet', 1.0)
4. Walk to the doorway and press your pick up item key to enter the factory
5. Place the car inside the factory
6. Destroy the car with your gun (this seems to work with any building entity, I just happened to use a car)
7. Exit the factory by walking to the exit and pressing the pick up item key again
(Do these both quickly, I'm guessing the crash probably won't occur if the temporary entities expire)
8. Pick up the factory building
9. Place it down again. The game should crash.
What's happening?
The crash is occurring in the Factory:restore_entities() function. Factory buildings should not perform any action while the player has picked it up in their inventory, so when you pick up a factory all the entities in the factory are set to
operable: false
active: false
minable: false
destructible: false
The state of these flags before changing them is stored in a .restore = {} array. When the factory is placed again, each of these entities, if valid, has their state restored to how it was before.
The restore function in question:
Code: Select all
function Factory:restore_entities()
local surface = game.surfaces['free_real_estate']
for entity, flags in pairs(self.restore) do
-- entity can be invalid here if we caught something temporary like smoke
if(entity.valid) then
entity.operable = flags[1]
entity.active = flags[2]
entity.minable = flags[3]
entity.destructible = flags[4]
end
end
self.restore = nil
...
end