Skip to content

Implement save/restore game state - #70

Merged
corepunch merged 3 commits into
mainfrom
copilot/implement-save-game-state
Feb 23, 2026
Merged

Implement save/restore game state#70
corepunch merged 3 commits into
mainfrom
copilot/implement-save-game-state

Conversation

Copilot AI commented Feb 23, 2026

Copy link
Copy Markdown
Contributor

Game state could not be persisted between sessions. The fix moves dynamic state into mem so a mem dump captures everything, then adds SAVE/RESTORE primitives that serialize and deserialize that state.

Changes

zilscript/bootstrap.lua

  • _ZGLOBALS = {} — global registry for ZIL game variable names, populated at runtime via SETG; consumed by SAVE/RESTORE
  • SETG(name, val) / GETG(name) — new runtime functions; SETG sets the global in _G, registers its name in _ZGLOBALS, and returns the value; GETG reads from _G
  • Object FLAGS → memOBJECT() allocates 8 bytes in mem per object (o._flags_addr) for the FLAGS bitmask; FSET/FCLEAR sync changes via write_flags_to_mem() so FLAGS are included in any mem dump
  • SAVE(filename) — writes: magic header + mem bytes (object properties, locations, FLAGS) + ZIL global values from _ZGLOBALS; mem is written in 4 KiB chunks to stay within Lua's table.unpack limits
  • RESTORE(filename) — reads the save file, restores mem, re-syncs all o.FLAGS caches from mem, then restores ZIL globals

zilscript/base.lua

  • Minimal stub definitions of SETG/GETG (without _ZGLOBALS tracking) so ZIL modules loaded via the bare loader without bootstrap continue to work

zilscript/compiler/forms.lua

  • GLOBAL form now emits SETG(%q, val) — global tracking happens automatically at runtime via the SETG function; no separate _ZGLOBALS registration line needed
  • SETG form now emits SETG(%q, val) — consistent with GLOBAL, tracks globals at runtime
  • CONSTANT is a separate handler and intentionally does not use SETG (immutable at runtime)

zil/test-save.zil

  • New test: sets object location, object flags (ONBIT), and numeric/boolean globals → saves → mutates all state → restores → asserts exact match

Save file format

"ZILSAVE\1"      8 bytes  magic + version
mem_size         4 bytes  LE uint32
mem_data         N bytes  raw mem bytes (includes object FLAGS at o._flags_addr)
global_count     2 bytes  LE uint16
  name_len       1 byte
  name           N bytes
  type           1 byte   1=number, 2=boolean
  value          8 or 1 bytes

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…egistry, SAVE/RESTORE functions

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>
Copilot AI changed the title [WIP] Add functionality to save and restore game state Implement save/restore game state Feb 23, 2026
Copilot AI requested a review from corepunch February 23, 2026 15:40
@corepunch

Copy link
Copy Markdown
Owner

@copilot Do you need _ZGLOBALS? there are SETG and GETG hence you can make these
<GLOBAL TROLL-FLAG <>>
just 2 byte values (to be safe) in mem and set TROLL-FLAG to it's address
And we assume next time game is loaded, these addresses will match, right?

@corepunch

Copy link
Copy Markdown
Owner

@copilot You'll need to modify compiler to emit SETG and GETG and add these functions to bootstrap

… of compile-time _ZGLOBALS registration

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>

Copilot AI commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Do you need _ZGLOBALS? there are SETG and GETG hence you can make these
<GLOBAL TROLL-FLAG <>>
just 2 byte values (to be safe) in mem and set TROLL-FLAG to it's address
...

Good point. Replaced the compile-time _ZGLOBALS[%q] = true emission with proper SETG(name, val) and GETG(name) runtime functions. SETG now populates _ZGLOBALS automatically whenever a global is set, so the compiler doesn't need to know about the registry at all. Added minimal stubs in base.lua so ZIL modules loaded without bootstrap still work. Commit: 053ba00

Copilot AI commented Feb 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot You'll need to modify compiler to emit SETG and GETG and add these functions to bootstrap

Already done in 053ba00: SETG(name, val) and GETG(name) are defined in bootstrap.lua, and the compiler now emits SETG(%q, val) for both <GLOBAL> and <SETG> forms. Minimal stubs are also in base.lua for environments loaded without bootstrap.

@corepunch
corepunch marked this pull request as ready for review February 23, 2026 16:50
@corepunch
corepunch merged commit b496a11 into main Feb 23, 2026
2 checks passed
@corepunch
corepunch deleted the copilot/implement-save-game-state branch February 23, 2026 16:57
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