Turret library


Used as library for my other mods

Internal
1 year, 6 months ago
2.0
30.7K

b 2.1 patch for this and dependent mods, including two bug fixes

3 days ago

All four of your mods run on Factorio 2.1 with nothing but the version declaration changed, so I didn't bother to include diffs for that. While testing that change, I found two real bugs in turret-library, neither of them new in 2.1, one of which can kill a save. Patches below if you want them.

AI Disclosure This was primarily created by Claude Opus 5. I have fully reviewed everything in it, understand it, and endorse it.

Bug 1: the ammo loop asks the wrong turret about itself. In turret-library/control.lua, the branch that tops up turret B reads value.turretA.type. Once turret A is gone, that indexes nil and takes the game down on the next multiple of thirty ticks:

Error while running event Armored-train::on_tick (ID 0)
__turret-library__/control.lua:557: attempt to index field 'turretA' (a nil value)

So a combat-platform-mk2 that loses its first turret to biters kills the save. The same line also decides wrongly while both turrets are alive: with a repair arm in slot A and a gun turret in slot B, B is never given ammo, because the question was asked about A.

Line 557:

-                               elseif value.turretA.type ~= "container" then
+                               elseif value.turretB.type ~= "container" then
                                    InsertAmmoStack(entityInventory, value.turretB, stack)

Note the error names Armored Train rather than turret-library, because the library's control.lua is required into each consumer and runs in its Lua state. Anyone hitting this reports it to the wrong mod.

Bug 2: modular-ifv replaces turret-library's on_init. modular-ifv requires the library, which registers script.on_init, then registers one of its own. Only the last registration survives, so the library's never runs and neither storage.entityTurretData nor storage.turretDrawData is created for a new save. Nothing crashes today, because every place the library writes those tables re-checks for nil first, so they appear the first time a turret is built. But RemoveTurretDrawData iterates storage.turretDrawData with no such guard, so the mod is one ordering away from an error on a table that should have existed all along.

In modular-ifv/control.lua, inside its OnInit:

    storage.playerTick = storage.playerTick or {}
+   -- turret-library registers an on_init of its own, and only the last registration
+   -- survives, so this one replaces it. Set up the tables it would have created.
+   storage.entityTurretData = storage.entityTurretData or {}
+   storage.turretDrawData = storage.turretDrawData or {}
 end

What I checked. 27 tests through factorio-test, run in a real headless Factorio 2.1.17 with all four mods loaded together: that the equipment dictionary's ten entries all resolve to prototypes that exist, the orientation to direction mapping across the full range, turret equipment in a grid creating the paired turret on the vehicle and taking it away again with the equipment, a combat platform on rail carrying two turrets at its two offsets, the ammo loop feeding turrets from the wagon, and the naval turrets registering draw data only for the three that need it.

Reverting patch 1 turns the two turret ammo test from green into the crash quoted above.

Three smaller things, not patched.

naval-turrets' turretDictionary lists repair-arm-mk1-g with drawType 4, but data.lua has --require("assets.prototypes.repair-arm-mk1") commented out, so that entity never exists. Harmless dead configuration, since the name never matches anything built.

naval-turrets registers on_built_entity and on_robot_built_entity but not script_raised_built, so a turret placed by another mod's script, or by a script-driven blueprint, is drawn without its overlay.

More generally: because each mod does require("__turret-library__.control"), the library's handlers and its storage exist separately in all four Lua states. That is what makes the on_init clash above possible, and it means any consumer registering an event the library also registers will silently replace it.

On the repository. https://github.com/pandamiami80s/FactorioArmoredTrain is still Armored Train 0.4.6 for Factorio 1.1, last commit 2022-10-28, from before turret-library existed. If you pushed current sources there, this and anything like it could come as pull requests instead of a wall of text.

Let me know if you'd like me to give exact per-mod per-file full diffs instead.

New response