Skip to content

Scope Tables clone resolution to current table#966

Merged
GregHib merged 1 commit intoGregHib:mainfrom
HarleyGilpin:fixes/scope-clone-to-table
Apr 30, 2026
Merged

Scope Tables clone resolution to current table#966
GregHib merged 1 commit intoGregHib:mainfrom
HarleyGilpin:fixes/scope-clone-to-table

Conversation

@HarleyGilpin
Copy link
Copy Markdown
Contributor

@HarleyGilpin HarleyGilpin commented Apr 29, 2026

Summary

  • readTableRow resolved clone = "rowId" against a global cross-table list, returning the first match by trailing name. Two tables with a same-named row (e.g. spells.bind /
    spell_projectiles.bind) collided; Files.newDirectoryStream order picked the winner, so boot succeeded or ArrayIndexOutOfBoundsException depending on the host filesystem.
  • Replaced with an O(1) ids["$table.$rowId"] lookup, restoring the intra-table semantics the existing error message already promised.
  • Added a regression test that loads two tables sharing a rowId and verifies the clone resolves within its own table.

Test plan

  • ./gradlew :engine:test green (existing Test loading a table still passes; new Clone resolves within own table when rowId collides across tables passes).
  • Verified the new test fails with AIOOBE against the old global-scan code, confirming it reproduces the original boot crash.
  • ./gradlew :game:compileKotlin clean.

readTableRow resolved `clone = "rowId"` via a global firstOrNull over
every row in every loaded table, keyed by `stringId.substringAfterLast('.')`.
Two tables defining a row with the same trailing name (e.g. spells.bind
and spell_projectiles.bind) silently collide; the winner is whichever
file Files.newDirectoryStream returns first, which is FS-dependent and
varies between machines. When the wrong row wins, copying its smaller
data array into the larger template throws AIOOBE during boot.

Replace the global scan with an O(1) lookup of "table.rowId" against
the existing `ids` map. The error message at this site already promises
table-scoped semantics ("not found in table '\$key'"); this just makes
the implementation match.

Adds a regression test that loads two tables sharing rowId "row" and
verifies the clone resolves to the same-table source. Without the fix
the test fails with AIOOBE, matching the production crash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@GregHib GregHib merged commit a2c0dbe into GregHib:main Apr 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants