sots-re/campaign/open-questions.md

30 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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]])