Combat Log

by chriswa

Keeps a log of combat alerts.

Utilities
1 year, 9 months ago
1.1
357
Combat

b gui-window.lua:121: attempt to index field '?' (a nil value)

9 months ago

I just clicked on the Combat Log button while playing SE and repairing a stranded spaceship, and it crashed with the following error:

The mod Combat Log (1.0.0) caused a non-recoverable error.
Please report this error to the mod author.

Error while running event combat-log::on_gui_click (ID 1)
combat-log/control/gui-window.lua:121: attempt to index field '?' (a nil value)
stack traceback:
combat-log/control/gui-window.lua:121: in function 'append_cluster_row'
combat-log/control/gui-window.lua:223: in function 'render_content'
combat-log/control/gui-window.lua:285: in function 'show'
combat-log/control/gui-window.lua:315: in function 'handler'
combat-log/control/gui-window.lua:326: in function 'wrapper'
flib/gui-lite.lua:139: in function 'handler'
flib/gui-lite.lua:169: in function <flib/gui-lite.lua:152>

9 months ago

Screenshot, in case this is helpful: https://imgur.com/a/FKMPI0f

9 months ago

I've started to add some debug code - the problem seems to have to do with disappearing surfaces. I bet that the fact that I'm repairing spaceships is related - parked spaceships (e.g. when the ship is stranded, or when I board a ship from another one) are probably temporary surfaces for SE, and after I've repaired the ship and sent it on its way again, the temporary surface is probably gone. The mod doesn't seem to expect surfaces to disappear, and therefore crashes.

9 months ago
(updated 9 months ago)

Here are the changes I made to fix the most obvious crashes:

martin@DESKTOP-Q6QP05F ~ % diff -Nur combat-log combat-log-fixed
diff -Nur combat-log/combat-log_1.0.0/control/gui-window.lua combat-log-fixed/combat-log_1.0.0/control/gui-window.lua
--- combat-log/combat-log_1.0.0/control/gui-window.lua  2023-03-06 06:32:40.000000000 +0100
+++ combat-log-fixed/combat-log_1.0.0/control/gui-window.lua    2024-02-28 23:08:50.000000000 +0100
@@ -118,7 +118,13 @@
     })

     -- Where
-    local surface_fancy_name = game.surfaces[cluster.surface_index].name
+    local surface = game.surfaces[cluster.surface_index]
+    local surface_fancy_name
+    if surface == nil then
+      surface_fancy_name = "non-existing surface"
+    else
+      surface_fancy_name = surface.name or "surface without name"
+    end
     if surface_fancy_name == "nauvis" then surface_fancy_name = "Nauvis" end
     flib_gui.add(data_flow, {
         type = "frame",
@@ -178,7 +184,13 @@
     button.tags = new_button_tags

     local where_label = data_flow.children[(row_index - 1) * COLUMN_COUNT + 2].children[1]
-    local surface_fancy_name = game.surfaces[cluster.surface_index].name
+    local surface = game.surfaces[cluster.surface_index]
+    local surface_fancy_name
+    if surface == nil then
+      surface_fancy_name = "non-existing surface"
+    else
+      surface_fancy_name = surface.name or "surface without name"
+    end
     if surface_fancy_name == "nauvis" then surface_fancy_name = "Nauvis" end
     where_label.caption = surface_fancy_name .. " (" .. cluster.pos.x .. ", " .. cluster.pos.y .. ")"

diff -Nur combat-log/combat-log_1.0.0/control/space-exploration-integration.lua combat-log-fixed/combat-log_1.0.0/control/space-exploration-integration.lua
--- combat-log/combat-log_1.0.0/control/space-exploration-integration.lua       2023-03-03 17:45:06.000000000 +0100
+++ combat-log-fixed/combat-log_1.0.0/control/space-exploration-integration.lua 2024-02-28 23:27:00.000000000 +0100
@@ -29,9 +29,14 @@
     if surface_index == player.surface.index then
         player.zoom_to_world(pos, 0.31)
     else
-        player.print(
-            "Unable to focus map on alternate surface without SE available. Fallback is to give you a gps tag: [gps=" ..
-            pos.x .. "," .. pos.y .. "," .. game.surfaces[surface_index].name .. "]")
+        if game.surfaces[surface_index] == nil then
+            player.print(
+                "Unable to focus map on alternate surface because the surface no longer exists.")
+        else
+            player.print(
+                "Unable to focus map on alternate surface without SE available. Fallback is to give you a gps tag: [gps=" ..
+                pos.x .. "," .. pos.y .. "," .. game.surfaces[surface_index].name .. "]")
+        end
     end
     -- player.zoom = 0.315 -- farthest zoom without engaging map mode

There might be more (just check every place where you access game.surfaces[surface_index]), but these are the ones I noticed where my game crashed.

The fallback for surface.name is probably not needed; I just made that initially because I wasn't sure what part of that line caused the crash. I believe the root issue is that your code relies on game.surfaces[surface_index] to be valid, but I have a feeling that SE likes to create temporary surfaces (for the ship docking maybe) that may no longer exist when you try to access them later.

New response