sots-re/campaign/open-questions.md

6.8 KiB
Raw Blame History

Open questions

Each links to the finding that raised it. Promoted to backlog or closed by re-quartermaster.

  • Compiler archive mismatch — imports say MSVCR100/MSVCP100 (VS2010), but Ghidra applied windows_vs12_32 datatypes (closest available). Confirm the exact toolchain from the PE Rich header; decide which datatype archive best fits. (from 01-fingerprint)
  • Battle-load root cause — inferred as single-threaded engine + core-count-sensitive code; must be confirmed by a ForceSingleCore=0 vs =1 diff once the main loop is mapped. (from 00-strategy)
  • Save-editor struct coverage — community editors cover players/tech/systems; fleet/combat state coverage may be partial. Treat as strong hints, verify each field against real saves.
  • Lockstep determinism — @SYNC ERROR DETECTED: Frame %d indicates a deterministic lockstep sim. Big for reimplementation + old-vs-new differential (determinism makes equivalence checkable frame-by-frame). Confirm scope. (from strings-and-config)
  • Mods override mechanism — .gob = gobio::ZipFileSystem with a NativeFileSystem loose-file override; this is how ./Mods wins over archived files. Verify load order. (from strings-and-config)
  • Battle-load root cause — the shipped fix is a blunt process-affinity pin (FUN_0089ee70) with NO CPU-topology detection, so there is no adaptive branch. The real cause is emergent multi-core contention: which thread(s)? Investigate the 3 CreateThread sites (FUN_00902350, FUN_00736e30, startup FUN_008a0e50), the streaming-sound thread, and lockstep sync waits. (from ghidra-recon)
  • Save-struct contradictions (R1 vs R2) — field widths (Abdn/Dstyd/ltis Int16 vs Int32; Bats2), R2's OID = PID*16 owner-handle claim, species id 4 (_NPC vs 'AI Rebellion'). Resolve against the binary's Streamable read code. (from save-editor-structs)
  • Unlabeled save blocks — CdPlayer (unknown1..35), empty SimSystemDetailSpy, opaque ~2500 B RNG blob. Analyst targets once the Streamable readers are located. (from save-editor-structs)
  • Missing HUD scripts — exe references GUI/Combat/CombatHUD.script, SensorHUD.script, NoHUD.script but none ship in the gobs or loose; likely dev-only overrides via the gobio native-FS fallback. Confirm via CombatScreen load path. Also: .script files are display configs, not widget layouts (corrects round-one note). (from ui-screen-map)
  • Tech allows default per-race % — tech_tree.json edges only carry races written in the allows string; the default for an unlisted race (believed 100%) is engine code. Ghidra target in the tech loader. (from data-parsers)
  • Engine parser leniency — 12 shipped shipsections are syntactically broken (unclosed {, extra }) yet load; keys and identifiers are case-insensitive. Reimplementation must match this leniency. .effect is its own TXT/BEGIN-END format, not brace-block (corrects round one). (from data-parsers)
  • Struct recovery leftovers — PlayerColorID exact on-disk width (writer FUN_008b9cb0 undecompiled); ServerSystem+0x10 owner type; TechTree per-tech body; CdPlayer block. R2's OID = PID*16 is an id-allocation pattern, not in this code. (from struct-recovery)
  • Resolved (R1/R2 contradictions) — Bats2/rcex are int64 (R2 wrong); Abdn/Dstyd bools, ltis int; TRM/CstR/E/T/shrm/RefCap/RepCap/PlayerView Infra are floats; pswd string; TShn/ETS/diplomacy counters int16 in memory, int32 on disk; Nexp carries xid/xmin/xmax/xper; FtOrig is Vector3. (from struct-recovery)
  • Battle-load, narrowed — sim/combat load run on the main thread; the only other threads are net watchdog, TIME_CRITICAL audio streaming (g_musicCS), and a star-map mesh builder. Hypothesis: audio-thread critical-section contention or D3D9 runtime/driver threads on many cores. Needs a dynamic profile (x32dbg / ETW) under the software-GPU stack. (from turn-spine)
  • Spine leftovers — StrategyServer struct partial (41 fields); static-initialiser region 0x009be000–0x009c1400 undisassembled; Mars::Stream vftable not located; several small ProcessTurn phase fns unnamed. (from turn-spine)
  • Save framing ambiguities (settle on first real save) — padding joint [len][name][value][pad] vs split; bool vs int for names with len%4==0 (no type byte); on-disk tags for Summary/CreateParameters and count/element tags inside framed arrays unknown (positional for now). A real 3-char bool tag (NPC,Dep,hsp) settles padding. (from SAVE_FORMAT)
  • Strict-parse gaps vs real save (verifier output, round 3) — (1) ServerSystem: 7/28 systems carry VFlags where Name/vnh were expected — a conditional layout (uncolonized/special systems?); (2) halt[].haltv is a 31/35-byte struct, not a bool; (3) optional indi (IndependenceInfo?) precedes NVE/PID in some systems; (4) PrisonerHold.prisoners[] entries lack PrNSp; (5) /createParams/key is int; (6) turnstats.hist.stats.tch is int; (7) optional trailing zdsi/zdst. Padding = joint (settled). 7 resyncs / 2728 raw bytes ≈ RNG blob. (from turn2-strict-issues)
  • RESOLVED: strict-parse gaps — 5/8 were reader bugs (ASCII plausibility test applied to string values; empty string == int 0), 3 real: PrNSp only when PrMax>0; indi unconditional in NVO nodes (system-level gated by hindi); zdsi/zdst pairs under zdsc. Key is an empty string; tch int. Summary/CreateParams tag lists confirmed. Reader patch in flight. (from schema-gaps-resolved)
  • RESOLVED: save framing — padding is joint; "." = NULL tag (VectorHelper count+elements, Vector3 bodies); empty strings are 4 zero bytes; CDT is a tagged frame + opaque CD frames. All three real saves parse --strict clean. Note: SvSctOb IS present in all saves (patch doc §7 was wrong). (from SAVE_FORMAT)
  • (parked) Combat loader job API — does tactical-battle loading go through the job helpers 0x8fc160/0x8fa5b0 with the TryEnterCriticalSection→Sleep(1000) completion poll (0x0071ea60)? If yes, that is a plausible many-core stall (lost try-lock = +1 s per poll). End Turn also has a deliberate Sleep(computed) ≈0.85 s at 0x00838da9. (from battle-load-profile)
  • Ship-design code rules (Ghidra, from SHIP_DESIGN_RULES.md §8) — hidden default rider designs are built WITHOUT tech gating (where?); is section class-equality enforced or merely unoffered; confirm the turret class-accept table (standard ← {standard,missile,grapple}, strafe ← {standard}; grapple weakest); hull-class tech injection (IND_CruisCon/IND_DreadCon) + station exemption; option defaults/auto-upgrade and what option_cost multiplies; weapon cost per bank vs per mount; mass/speed formulas; faiDes/dWep meaning. (from SHIP_DESIGN_RULES)