Abandoned Ruins - Updated (core)

by Keysivi

This mod doesn't do anything by itself. You need to install ruin-set mods or no ruin will be spawned. It then can spawn randomly choosen ruins in the world. These ruins are destroyed fragments of bases, forts, small oases, and more. (Now co-authored with roland77)

Content
9 days ago
2.0
8.34K

b [PARTLY-ACCEPTED] Debug/Test World fixes for 1.5.5

14 days ago

Hey,

I tested the included Debug/Test World scenario from AbandonedRuins_updated_fork 1.5.5.

This is specifically the scenario available from Factorio's scenario menu which creates the dedicated debug-ruins surface and places the registered ruins there for inspection.

Normal Freeplay spawning is not affected by the issues described below.

I found several independent problems in the Test World. I attached a unified diff against the unmodified 1.5.5 sources.

After applying these fixes, the Test World starts successfully and the registered ruins are displayed correctly.

  1. Test World fails to parse

Initial error:

level/control.lua:83: ')' expected (to close '(' at line 50) near 'if'

File:

scenarios/debug/control.lua

Cause:

The script.on_event(defines.events.on_player_created, function(event) block contains an additional end after the debug surface creation/logging code.

This closes the function body too early while the surrounding script.on_event(...) call is still waiting for its closing ).

Fix:

Remove the stray end and let the event handler continue normally until the final end).

  1. Invalid remote interface call

The Test World contains:

remote_call("AbandonedRuins", "get_ruin_sizes")

Factorio's remote interface API uses:

remote.call(...)

Fix:

remote_call(...) -> remote.call(...)

  1. Registered ruin count uses the table instead of its length

The scenario calculates the total number of ruins using:

total_ruins_amount = total_ruins_amount + ruin_set[size]

However, get_ruin_set() returns a table containing arrays of ruin definitions for each size.

So ruin_set[size] is a table, not a numeric value.

Fix:

Count the entries in the array instead:

total_ruins_amount = total_ruins_amount + #ruin_set[size]

The patched version also checks that the size entry actually exists before counting it.

  1. Debug surface is accepted by spawn_ruin() but rejected by clear_area()

After fixing the scenario script, the Test World started but failed while placing the first ruins with:

AbandonedRuins_updated_fork/lua/spawning.lua:386: surface.name='debug-ruins' is a debug surface, no clearing needed.

Call stack:

Test World -> spawn_ruin() -> clear_area() -> error()

The dedicated debug surface is already supported by spawn_ruin(), but clear_area() explicitly throws an error when it encounters the same surface:

surface.name == constants.DEBUG_SURFACE_NAME

The message itself already states that no clearing is required.

Fix:

Instead of raising an error, the debug-surface branch now skips the clearing step and returns success:

return true

This allows spawn_ruin() to continue normally on the Test World surface.

Normal surfaces still use the existing clearing logic unchanged.

Additional improvement: weighted ruin sets in the Test World

This is not required to fix the original Test World crashes, but I added it because it makes the scenario much more useful with ruin packs that use weighted registration.

Some ruin packs intentionally register the same ruin definition multiple times in the ruin set to influence normal random spawn probability.

For example:

ruin_A, ruin_A, ruin_A, ruin_B

is a valid way to give ruin_A three times the selection weight of ruin_B.

That behavior is correct for normal Freeplay spawning.

However, the Test World iterates over the registered selection entries directly. With weighted registrations, this means it would physically place the same ruin multiple times instead of showing each actual ruin definition once.

The patch therefore creates a display-only de-duplicated ruin list for the Test World.

This de-duplication:

only affects the Debug/Test World,
does not modify the registered ruin set,
does not change spawn probabilities,
and does not affect normal Freeplay spawning.
Additional cleanup

The patch also:

uses the ruin-size order returned by get_ruin_sizes(),
guards against an empty ruin set,
and removes the direct runtime-setting modification from the scenario.
Result

With all of the above changes applied, I can successfully start the Debug/Test World and inspect the registered ruins.

I used it afterwards to verify the Angel ruin integration in AbandonedRuins-Combined, and the ruins are displayed/spawned correctly.

The attached patch only changes:

scenarios/debug/control.lua

and

lua/spawning.lua

The normal Freeplay ruin spawning logic and spawn weights are otherwise unchanged.

If useful, we can also provide the fully patched 1.5.5 build we used for testing, so you can compare it directly against the original version.

Greetings

MoSII2710

9 days ago
(updated 9 days ago)

Thank you so much for all your findings. I appreciate it always when people send in fixes. If you want, you can send in a PR so your author's name is included in the commit and not mine.

I have remove the stray end and applied also other fixes, including remote_call() -> remote.call() and added missing # for counting array size. I also added an additional debug line in spawn_ruin() which logs current surface's name and the contents of constants.DEBUG_SURFACE_NAME for manual comparison/check if the code works as expected.

Instead of raising an error, the debug-surface branch now skips the clearing step and returns success:

I would rather prevent an "illegal" invocation of clear_area() rather than invoking it and then later "silently" quit it. So a test for surface's name against constants.DEBUG_SURFACE_NAME is the proper way for my taste.

The test world is supposed to not randomly spawn any ruin, it is supposed to show all ruins aligned to a grid for a good overview.

Unfortunately, LUA has no built-in code-linting like PHP has, so I cannot add a pre-commit hook where the scripts are being checked for syntax errors.

9 days ago

A new release 1.5.6 is up with your proposed fixes.

9 days ago

Hi Roland77,

I created a pull request on GitHub for the Debug/Test World fixes.

Besides the 1.5.6 debug-surface condition fix, I also included the weighted-ruin handling we discussed.

The reason is that AbandonedRuins-Combined uses weighted registrations by intentionally inserting the same ruin definition multiple times into the runtime ruin pool. That is correct for normal spawning, because those duplicate entries are the selection weights.

The Debug/Test World has a different purpose though: it should display the actual ruin definitions for inspection.

Without de-duplication, Combined currently expands to thousands of weighted selection slots, so the Debug World tries to render thousands of ruins instead of the roughly 200 actual unique ruin definitions. In my full K2/SE setup this resulted in over 6,000 ruin placements and effectively locked the game during world creation.

The PR therefore de-duplicates identical ruin table references only for the Debug/Test World display. Normal spawning and all ruin weights remain completely unchanged.

I tested the resulting version successfully with Factorio 2.0.77 and my full K2/SE mod stack.

greetings MoSII

8 days ago

Hi Roland77,
I moved the Debug/Test World weighting workaround into AbandonedRuins-Combined itself.

Combined now detects the core debug scenario and registers the unique ruin set there, while normal gameplay still uses the full weighted pool.

That means the Debug World no longer tries to place thousands of weighted duplicates, and your core control.lua does not need any Combined-specific de-duplication logic.

Greetings MoSII

8 days ago

Okay, thank you for the feedback. With the ruin weight feature, I have added some more ideas how this can be implemented "type-safe" for ruin-set authors.

This thread has been locked.