Files
panel/modules/7dtd/nim-freeze/REMAP_RUNBOOK.md
T
dbledeez 295eb22826 panel public release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 01:26:41 -07:00

5.3 KiB

7DTD Cluster — Canonical-Compatible New World Provisioning (RUNBOOK)

Validated 2026-06-13. Tooling: this dir. Canonical: ~/nimcanon/canonical_final/{block,item}mappings.nim

WHERE TO RUN (prerequisites — read first)

Run on figaro (<user>@<agent-host>) as user refuge. Requires ~/nimcanon/{tool,canonical_final,remap} present (the .nim parser, the canonical, the cached native table). The repo remap_7dt.py hardcodes sys.path.insert(0,'/home/refuge/nimcanon/tool') and imports nimtool — it will NOT run on the Windows dev box or kaiten. (The in-container copy invoked automatically by the entrypoint is the self-contained remap_7dt.vendored.py — a different file.)

Saves live in a docker volume, not a host path — $W below is only reachable by mounting the volume. Run file ops inside a throwaway container, e.g.:

CL=/home/refuge/panel/data/7dtdcluster/cl_37e3a7f72cdc
VOL=panel-<inst>-saves          # e.g. panel-cluster-seed-test-saves
docker run --rm -v $VOL:/sv -v $CL:/cl debian:12-slim sh -c '
  W="/sv/.local/share/7DaysToDie/Saves/<World>/<GameName>"; <ops on "$W/decoration.7dt" etc.>'

STOP/START only via the panel (agent-owned; sends SIGTERM→tini→7DTD clean shutdown, which flushes the native .nim). A docker kill/docker stop would NOT flush and can corrupt the capture.

CORRECTED ROOT CAUSE

7DTD V2.6(b14) auto-assigns block ids at config-load. The cluster's CURRENT runtime (RefugeBot v1.2.39) puts the tree-decoration band at native ids 21895+, while the season10-anchored CANONICAL puts the same trees at 24141+ (season10's world was baked PRE-RefugeBot-rebuild). At world GENESIS the engine bakes decoration.7dt / multiblocks.7dt BY NUMERIC BLOCK ID using native runtime ids. The entrypoint guard then stamps the canonical .nim over the world's .nim every boot (so inventory/.ttp decode uniformly → clean transfers). MISMATCH: native-baked deco (21895) read against stamped canonical (24141) → null Block → DecoManager.TryAddToOccupiedMap NRE → world load hangs → never GameStartDone. season10/creative load clean only because their deco was baked when the runtime == canonical (pre-rebuild).

KEY FACTS

  • .nim: u32 ver=1, u32 count, recs[u16 id, u16 flag(block=0/item=1), u8 namelen, name]. Parser: ~/nimcanon/tool/nimtool.py
  • decoration.7dt / multiblocks.7dt: u8 ver=6, u32 count, count*17B recs; block id = u16@+12 & 0x7FFF; high bit + bytes +14/+16 = rotation/placement (PRESERVE).
  • Engine PRESERVES loaded deco ids on save; only writes native ids at GENERATION. So a canon-remapped decoration.7dt stays canon across reboots → STABLE.
  • The cluster runtime native table is IDENTICAL across all instances (insane==pvp deco band 33/33). One captured native table is authoritative cluster-wide: ~/nimcanon/remap/cluster_native_deco.nim
  • Remapper: remap_7dt.py (apply|analyze|decodecheck). Self-verifies byte-safety + 100% canon resolution.

PROVISION A NEW CANONICAL-COMPATIBLE WORLD (do this on a FRESH/0-region world)

CL=/home/refuge/panel/data/7dtdcluster/cl_37e3a7f72cdc ; VOL=panel--saves ; W="/"

  1. Gen the world (set seed, recreate/start). It bakes a NATIVE decoration.7dt.
  2. CAPTURE the world's native table: a. Stop the instance (panel Stop — NOT docker stop). b. First BACK UP the canonical (cp $CL/canonical/*.nim ~/canon-backup/), THEN move the originals aside so the guard skips the stamp: mv $CL/canonical/*.nim $CL/canon_test_aside/ ⚠️ The canonical is the SHARED stamp source for EVERY cluster member. While it is moved aside, do NOT boot any other member — it would stamp nothing and could append/diverge (cluster-wide inventory risk). Keep this window short; restore in step 5 and confirm by sha256sum before starting anything else. c. printf '\x01\x00\x00\x00\x00\x00\x00\x00' > "$W/blockmappings.nim" ; same for itemmappings.nim d. Start instance → loads clean on native → engine writes the world's native .nim (covers its deco blocks). Graceful-stop to flush. e. Copy out "$W/blockmappings.nim" as <native.nim>.
  3. REMAP: python3 remap_7dt.py apply <native.nim> ~/nimcanon/canonical_final/blockmappings.nim "$W/decoration.7dt" /tmp/deco.canon.7dt (repeat for multiblocks.7dt if present). Require: "byte-diff outside id field: 0" and "ids unresolved in canon: 0".
  4. Backup native (cp decoration.7dt decoration.7dt.native-bak) then apply the remapped file; chown 1000:1000.
  5. mv $CL/canon_test_aside/*.nim $CL/canonical/ # restore the stamp source
  6. Start instance → guard stamps canon → loads canon-remapped deco → GameStartDone, NRE=0, on canon.
  7. VERIFY: decoration.7dt id band = 24xxx ; GameStartDone ; NRE=0 ; .nim stamped 38626/2719 at boot.

REPAIR AN ALREADY-STUCK WORLD (canon stamped, native deco, NRE) — same as above from step 2.

CAVEATS

  • Region/.7rg voxel ids + Player/.ttp item ids are NOT remapped (codecs unsolved). Do the remap on a FRESH 0-region world BEFORE exploration. Existing 87 shared .ttp are fine (written in canon by season10/creative).
  • Deco block ids must be < 32768 (15-bit field); the tree-deco band is far under.
  • PERMANENT fix (removes the per-world remap step): pin block ids explicitly in a high-priority modlet so the runtime native table == canonical, OR freeze the RefugeBot build that season10 was baked under. Until then each new world needs this one-time remap.