Turret Shields

by OwnlyMe

Lightweight scripted shields with power consumption for all turrets (configurable or researchable)

Content
1 year, 8 months ago
0.16 - 2.0
6.87K
Combat

g Crashing

a month ago

Been getting this crash randomly mid-game. Factorio 2.0.77, Turret Shields 2.0.4:

Error while running event Turret-Shields::on_tick (ID 0)
Turret-Shields/on_tick.lua:131: attempt to index field '?' (a nil value)
stack traceback:
Turret-Shields/on_tick.lua:131: in function <Turret-Shields/on_tick.lua:1>
Dug into the code to figure out what's going on. storage.refresh_orientation holds flame turrets that were shooting or rotated when their shield got registered, so the shield bar can get repositioned later. Problem is destroy_turret() only cleans up storage.turrets and the electric updater tables, it never removes anything from refresh_orientation. So if a queued turret loses its shield before that list gets processed (happens within ~5 seconds, e.g. shields toggled off by combinator), the turret entity is still valid but storage.turrets[unit_number] is nil, and line 131 blows up indexing it. It's timing dependent, which is why it looks random.

Fixed it on my end by guarding the lookup in the refresh_orientation loop in on_tick.lua (also added a valid check on the hidden electric entity before the teleport, since that line has the same problem):

if entity.valid and entity.shooting_target == nil and entity.orientation % 0.25 == 0 then
local tracked = storage.turrets[entity.unit_number]
-- turret can be removed from storage.turrets while still queued here
if tracked then
tracked[4] = entity.orientation
if storage.energy_consumption and tracked[7] and tracked[7].valid then
local position = tracked[7].position
if entity.orientation == 0 then
position.y = position.y+0.5
elseif entity.orientation == 0.25 then
position.x = position.x-0.5
elseif entity.orientation == 0.5 then
position.y = position.y-0.5
elseif entity.orientation == 0.75 then
position.x = position.x+0.5
end
tracked[7].teleport(position)
end
end
storage.refresh_orientation[key]=nil
elseif not entity.valid then
Been running this on my (heavily modded, ~95h) save since and the crash is gone, shield bars still reposition like they should. Feel free to use it.

New response