Skip to content

Research index

One row per filed report. [BUILD-ON]/[RISK] lists below are merged across all reports — see each file for full detail and citations.

# File Topic Sources Status
01 01-skyrim-modding-substrate.md Skyrim modding substrate (Mantella/CHIM/SkyrimNet/SKSE) 2 independent reports filed — contains an unresolved disagreement, see below
02 02-social-simulation-literature.md Social-sim literature for game-scale belief systems 1 report filed
03 03-hybrid-llm-symbolic-architecture.md Hybrid LLM + symbolic simulation architectures 3 reports (high overlap) filed
04 04-voice-pipeline.md Voice/dialogue pipeline for procedural NPCs 1 report filed
05 05-save-reload-sync-protocol.md Save/reload timeline consistency — protocol design 1 report (batch 2) filed
06 06-save-reload-timeline-sync.md Save/reload timeline consistency — DAG model and wire protocol 1 report (batch 2) filed
07 07-skyrimnet-substrate.md SkyrimNet ecosystem due-diligence — resolves ADR-0003 1 report (batch 3) filed
08 08-social-sim-literature-v2.md Social simulation literature v2 — implementable specification 1 report (batch 3) filed
09 09-save-sync-forensics.md Save/reload sync — third independent pass, repository forensics 1 report (batch 4) filed — supersedes 05/06 on specifics
10 10-skyrimnet-health.md SkyrimNet health deep-dive — inverts ADR-0003's provider priority 1 report (batch 5) filed — amends ADR-0003
11 11-version-pin-and-transport.md Game version pin + HTTP/WebSocket bridge survey — resolves ADR-0008 3 reports (batch 6, merged) filed — new ADR-0008
12 12-whiterun-dashboard-map-data.md Whiterun debug-dashboard map assets, coordinates, telemetry, licensing 3 reports (batch 7, merged) + 1 session pass filed — license claims verified directly
13 13-dashboard-prior-art-source-read.md Dashboard prior art at source level — WS protocol, replay schema, projection 1 source-reading pass (batch 8) filed — resolves report 12's SkyrimWebSocket uncertainty
14 14-isometric-render-foundations.md 2.5D/isometric render foundations — real Whiterun geometry without building a renderer 1 session pass (batch 8) + hands-on smoke test filed — fo76utils verified on this machine 2026-08-22
15 15-skyrim-social-reactivity-mods.md Skyrim reactive-NPC / social-consequence mod prior art — reputation, life-sim, rumor-propagation mods and their engine walls 2 independent reports (batch 9, merged) filed
16 16-skyrim-economy-mods.md Skyrim economy-simulation mod prior art — pricing/merchant mods, vendor-gold/barter engine limits 2 independent reports (batch 9, merged) filed — economic sim itself remains deferred to v0.4
17 17-skyrim-social-reactivity-mods-v2.md Skyrim social-reactivity mod prior art — third independent pass (IntelEngine gossip chains, Town Criers, NPC Reactions' per-NPC memory timer) 1 report (batch 10) filed — see 15 for the merged first two passes
18 18-skyrim-economy-mods-v2.md Skyrim economy mod prior art — third independent pass (quantified wishlist demand, Stock Market of Skyrim, Conquest of Skyrim, Master Trader's gold-injection trick) 1 report (batch 10) filed — see 16 for the merged first two passes; economic sim itself remains deferred to v0.4
19 19-skyrim-quest-injection-machinery.md Skyrim Radiant Story internals, IntelEngine's dynamic-quest pipeline, Story-Manager-bypass faction sims (Open Civil War vs. Organic Factions), and SKSE journal/UI injection mechanisms 1 report (batch 11) filed — ahead-of-need for the deferred "prospective drama management" layer; companion to comparative-systems/ai-directors-and-drama-management.md
20 20-skyrim-quest-injection-machinery-v2.md Skyrim quest/GM-injection machinery — second independent pass (exact Story Manager event codes, alias-storage token limits, deeper IntelEngine profile, Faction Warfare/Civil War Overhaul fragility) 1 report (batch 12) filed — see 19 for the first pass; companion to comparative-systems/ai-directors-and-drama-management-v2.md
21 21-skyrim-quest-injection-machinery-v3.md Skyrim quest/GM-injection machinery — third independent pass (Undaunted precedent, exact alias-fill-type enumeration, deep IntelEngine version history, Fred Zeleny's legibility postmortem) 1 report (batch 13) filed — see 19/20 for prior passes; companion to comparative-systems/ai-directors-and-drama-management-v3.md
comparative-systems/ai-directors-and-drama-management-v4.md Drama-management/GM-agent literature — fourth independent pass, no Skyrim-specific companion this batch (Friends & Fables/ACE-1's belief-provenance-like redesign, Todd Howard's own Radiant Story design-intent quote, two new trust-failure modes) 1 report (batch 14) filed
22 22-native-skse-plugin-prior-art.md + pass 2 Native SKSE C++ plugin architecture for Chronicle's v0.2 game seam ("ChronicleBridge") — event sinks, IXWebSocket transport, threading discipline, Proton reachability risk, actor-spatial enumeration 2 independent reports (batch 15, merged) filed — resolves the notes/ideas.md v0.2 bridge-dependency action item; not ahead-of-need, targets the next build milestone directly. Verdict (both passes): first-party build, no SkyrimWebSocket install

| 23 | 23-v03-hysteresis-and-action-verbs.md | v0.3 gap survey: two-way hysteresis for Grudge/Relationship state (control-theory Schmitt-trigger pattern, RimWorld mental-break ladder, absence of purpose-built literature elsewhere) and an NPC action-verb inventory beyond rule 18's avoidance (dialogue-gating on GetRelationshipRank, vendor refusal/price, AI-package globals, SkyrimNet's AttackTarget/Action Repository) | 1 web-research pass (batch 16) | filed — ahead-of-need for docs/design/next-phases-2026-08.md §2's two flagged-but-unscoped v0.3 gaps; no ADR change |

| 24 | 24-programmatic-esp-authoring.md | Verifies/refutes docs/design/chronicle-bridge-avoidance-out.md §2b's unresearched "needs the Creation Kit GUI" assumption — finds Mutagen (C#/.NET, headless) can create new PACK/CTDA records outright, xEdit scripting is a weaker fallback, the CK has no headless content-authoring mode, and RE::Actor::PutCreatedPackage offers a partial runtime-override path | 1 web-research pass (batch 17) | filed — decisive recommendation: use Mutagen headlessly; the CK-GUI-required half of the assumption was correct but non-exclusive | | 25 | 25-devbench-skse-mcp-verification.md | Verifies a secondhand claim about alandtse/devbench, an SKSE plugin running an in-process MCP+REST test bench on 127.0.0.1:8920 — confirms the repo, Nexus listing (mod 181326), and nearly all technical claims (console-command capture, main-thread marshalling, menu/save/inspect tools, C-ABI for other plugins) are real; refutes the "MIT-licensed" claim (core is GPL-3.0, only the integration glue is MIT); assesses it could automate most of docs/design/chronicle-bridge-verification-runbook.md's manual steps once a live game session exists | 1 direct-verification pass (GitHub/Nexus primary sources) | filed — no ADR change; informs future ChronicleBridge in-game test tooling |

| 26 | 26-vendor-price-markup-hook.md | ChronicleBridge C++ mechanism for grudge-driven vendor price markup at barter-menu-open — direct header verification against a local CommonLibSSE-NG checkout | 1 header-verification pass (batch 18) | filed — RE::BarterMenu/RE::MenuOpenCloseEvent give risk-free vendor detection; the actual price write needs a reverse-engineered native price-calc hook (mod 144874's pattern), the first ChronicleBridge slice needing that risk category — scoped as its own future spike, not bundled with hydration/avoidance-tier next steps | | 27 | 27-minimal-chronicle-dev-modlist.md | A concrete, from-scratch, minimal MO2 mod list for Chronicle/ChronicleBridge dev+debug (distinct from the owner's NGVO and Apostasy/Tuxborn personal lists) — 1.6.1170 downgrade tooling status, Address Library/USSEP/DevBench/CrashLoggerSSE/SkyUI selection, build order | 1 research pass (batch 19) | filed — revises this task's own premise: 2 of IdentityMap.cpp's 19 named-cast entries currently resolve against USSEP-attributed FormIDs, not just Skyrim.esm/HearthFires.esm; source-level read of TESForm::GetFile() shows this is load-order-dependent rather than settled record ownership, so the list keeps USSEP active to match the table's verified environment. Update (2026-08-27): the mechanism is now settled empirically, not just flagged — a live-capture cross-check confirmed TESForm::GetFile(0) returns whichever plugin currently wins the override chain for a record, not its static originating master; see IdentityMap.cpp's 2026-08-27 note and commit 78dd0ec | | 28 | 28-vendor-price-hook-address-library-spike.md | Address Library spike for report 26's vendor-price-markup hook — reads mod 144874's actual open-source implementation (JerryYOJ/DynamicPrices-SKSE, found via GitHub code search) directly | 1 source-reading pass (batch 20) | filed — corrects report 26: no unmapped internal price-calc function exists to find; the real technique is a vtable-slot swap on the already-Address-Library-backed RE::VTABLE_BarterMenu (documented IMenu::PostCreate, vfunc 0x2) plus a Scaleform/GFx UpdateItemCardInfo callback swap, both fully inside this project's already-vendored CommonLibSSE-NG surface — downgrades the write from [RISK — reverse-engineered hook required] to [BUILD-ON], pending one live-game caveat (does the multiplied UI value drive the real transaction gold, not just display) | | 29 | 29-crime-witness-event-extraction.md | Verifies a secondhand AI's 7 claims about Skyrim/Oblivion crime-witness mechanics and a proposed TESCrimeEvent ChronicleBridge slice, against CommonLibSSE-NG headers, UESP, and mod primary sources | 1 header-verification pass (batch 21) | filed — no RE::TESCrimeEvent exists anywhere in CommonLibSSE-NG (sharpens report 22's own flagged gap); internal Bounty::Event/AssaultCrime::Event/MurderCrime::Event sinks exist but were never wrapped into public headers, so crime/witness extraction is [RISK — reverse-engineered hook required], the same tier as report 26/28's vendor-price work, not DeathEventSink-tier; 2 of the 7 secondhand claims were refuted (no Responsibility stat in Skyrim; Skyrim's vanilla "Reputation" is a narrow Easter egg, not the described morality system) and 2 more were mischaracterized | | 30 | 30-crime-witness-prior-art-spike.md | Follow-up prior-art spike for report 29's crime/witness R&D-spike verdict, mirroring report 28's successful vendor-price downgrade play — reads 3 real open-source SKSE plugins directly | 1 source-reading pass (batch 22) | filed — split verdict, not a clean downgrade: bounty/infamy VALUE per faction (PlayerCharacter::GetCrimeValue().crimeGoldMap) is fully routine-buildable (pollable, non-virtual, already used in a real shipped plugin); the witness SET's read mechanics are hook-free but the reference plugin manually attaches its own ExtraPlayerCrimeList bookkeeping rather than reading a vanilla-populated one, leaving open whether polling the player's own list yields report 29's assumed data (a one-session live-game check, not a full spike); event-level "a crime just happened" fidelity stays genuinely R&D-spike-tier, confirmed by a real plugin's raw trampoline detours onto unnamed internal functions found via its author's own IDA work — though Actor::ModCrimeGoldValue turns out to be a named vtable slot (0xB6), cheaper (vtable-swap tier) than report 29 implied | | 31 | 31-diegetic-evidence-object-placement-spike.md | Can ChronicleBridge place/move a physical object in the world at runtime for a "diegetic evidence" slice (from docs/design/kimi-architecture-delta-audit.md's one genuinely-new idea) — verifies both pre-place-and-toggle and spawn-at-runtime against real CommonLibSSE-NG source and two real shipped SKSE plugins | 1 source-reading pass (batch 23) | filed — [BUILD-ON] for both engine mechanisms, no reverse-engineering needed: TESObjectREFR::Enable()/Disable() and PlaceObjectAtMe()/TESDataHandler::CreateReferenceAtLocation() are all plain RELOCATION_ID/vtable-backed calls, confirmed a second time by reading Styyx1/SurpriseSpawner and HarperZ9/skyrimbridge's real source; Mutagen's own schema (PlacedObject/Placement/InitiallyDisabled) independently supports pre-place-and-toggle's authoring side. The real gap this pass found is data, not mechanism: neither IdentityMap.cpp nor chronicle/claims.py's Evidence record (whose real field is strength, not the audit doc's evidentiary_strength) carries any location concept to bind evidence to — recommends spawn-at-runtime at an NPC's own live position as the cheaper first cut, and flags pre-place-and-toggle as blocked on a location-modeling decision, not an engine risk | | 32 | 32-npc-home-location-data-spike.md | Closes report 31's F5 gap: what real NPC home/workplace location data does Skyrim already have, and how cheaply can Chronicle/ChronicleBridge get at it — verifies RE::TESPackage::packLoc/PackageLocation against real headers and directly dumps Ysolda's/Amren's/Braith's real Package records from the real Skyrim.esm/HearthFires.esm data via a from-scratch Mutagen program | 1 source-and-real-data-reading pass (batch 24) | filed — real static home data exists and is [BUILD-ON]-tier where a plain LocationCell home package exists (proven for Amren/Braith, both resolving to the real WhiterunAmrensHouse cell), but coverage is uneven (Ysolda has no explicit home package, only a LocationFallback/"editor location" indirection this pass could not fully resolve against the pinned Mutagen 23.4.0 schema); recommends NOT building a home-location model now — EvidencePoller.cpp's already-shipped live-position proxy covers all 19 named-cast NPCs uniformly and no roadmap item needs scene-independent location data yet | | 33 | 33-evidence-preplace-toggle-snapshot-coordinates.md | Re-examines pre-place-and-toggle from a different angle than report 32: could adapters/skyrim/listener/whiterun-positions.json's already-captured live X/Y snapshot (from SpatialStreamer.cpp telemetry, not the AI-package system) drive it instead, sidestepping report 32's reverse-index dead end — and does Enable()/Disable() genuinely avoid the save growth PlaceObjectAtMe's a_forcePersist=true compounds, verified against real engine headers and Bethesda's save-format convention | 1 source-and-web-reading pass (batch 25) | filed — finds full 19/19 named-cast coverage (strictly better than report 32's 2/3) and confirms the save-growth/retraction benefit is real (bounded single-ChangeForm-slot toggle vs. PlaceObjectAtMe's permanent new 0xFF-prefixed "created form" entry per call), but still recommends NOT building now: the snapshot has no Z coordinate (confirmed dropped in SpatialStreamer.cpp, not an engine limitation), needs a new exterior-cell FormKey resolution step (solvable via this project's own existing floor(coord/4096) map math, not a repeat of report 32's dead end), and is diegetically staler than either the live approach or report 32's rejected home-cell idea since NPCs move on real AI-package schedules; the verified save-growth benefit is real but unmeasured against Chronicle's actual event volume, so the certain new costs aren't worth paying yet — revisit if a real playtest shows the shipped mechanism's save growth becoming an actual problem |

Source PDFs worth keeping locally (not re-reads, schema/rule-authoring references): see papers/README.md.

Merged [BUILD-ON] list

  • Belief data model: James Ryan et al.'s Talk of the Town facet model (Value/Predecessor/Evidence/Strength/Accuracy) — near-direct template for chronicle's belief dataclass, already Python. (02)
  • Rumor propagation: Daley–Kendall SIR spread (who hears it) + Bartlett/Griffiths serial-reproduction mutation (how it changes), both O(edges) per tick. (02)
  • Memory decay: ACT-R base-level activation (closed-form log-decay) + Generative Agents recency×importance×relevance score — cheap, LLM-free. (02)
  • Tier interface: LLM text → numeric scalar (opinion/stance) → symbolic update, per HiSim/RumorSphere — symbolic state stays authoritative, LLM output is an annotated view, not a source of truth. (03)
  • Write-back mechanism: constrained JSON decoding (XGrammar/Outlines/Guidance) is now near-zero-overhead and the field's dominant pattern; still needs a downstream semantic validator since format-valid ≠ content-valid. (03)
  • Local LLM tier: 1B–8B models (Qwen3/2.5, Llama-3.x, Mantella-Skyrim-Llama-3-8B fine-tune) at Q4_K_M are practical alongside Skyrim on consumer GPUs — concrete VRAM/tok-s numbers converge across all 3 hybrid-architecture reports. (03)
  • Voice design: Qwen3-TTS-VD (1.7B/0.6B, Apache 2.0) for one-time description-driven voice design; Chatterbox-Turbo (350M, MIT) as the runtime cloning engine (~75ms TTFB, <1GB VRAM, native inline tags + exaggeration slider). Adopt "design-once-then-clone": design at NPC creation, cache reference WAV by form ID, clone per line. (04)
  • Event transport: never route high-frequency events through Papyrus (script-queue lag) — a CommonLibSSE-NG SKSE plugin hooking native dispatchers, forwarding via HTTP/WebSocket, is the pattern both substrate reports converge on. (01)
  • NPC data ingestion: Mutagen or the xEdit Info NPC Extractor script, plus UESP CC-BY-SA bios. (01)
  • Save/reload identity: embed a SaveUUID + ParentSaveUUID + monotonic generation/SaveSequence in the SKSE co-save (TMNL record) — strictly stronger than any existing mod's approach (CHIM's clock-only gamets, Mantella's none, SkyrimNet's in-process-only). See ADR-0004. (05, 06)
  • Timeline model: model Skyrim's save topology as a DAG of branches keyed by (save_uuid, generation); fork on reload, never roll back; derive state by path traversal from root to head. See ADR-0004 and the chronicle/events.py branch-key change. (05, 06)
  • Sync handshake: gate writes on an explicit watermark/epoch handoff between the SKSE shim and the service, not on kPostLoadGame alone; buffer/suppress events during the load window. See ADR-0005. (05, 06, independently re-derived by 07, and superseded on specifics by 09's HELLO/RESOLVE/ACK protocol with a six-way decision table and a DEGRADED mode for service-down-at-load)
  • Save-sync forensics: report 09 goes past architecture into repository forensics (specific CHIM PRs #560/#572/#558/#681, SkyrimNet issues #251/#487/#119/#391) and resolves the SkyrimNet-reload-behavior conflict left open after 05/06: SkyrimNet asks the player before clearing (ClearTimelineMessage/msgClearHistory), confirmed via issue #251 — it neither silently ignores (05's read) nor runs a fully automatic cleanup (06's read). Agrees with 05/06/07 on architecture (event-sourced, fork-not-rollback, save-embedded UUID); upgrades ADR-0004/0005 on specifics (bitemporal columns, reachability-based GC, the manifest schema, the handshake decision table). (09)
  • Substrate Abstraction Layer: a generic Python provider interface in chronicle/, both implemented under adapters/. Resolves ADR-0003 (07); provider priority inverted by report 10 — the PO3-Extender+SKSE_HTTP standalone path is the reference implementation built first, SkyrimNet is an optional adapter pinned to one beta/API version with a startup handshake. See ADR-0003's amendment.
  • Five-layer data ownership: canonical events → claims/variants → subjective beliefs → social state → narrative/query. Only the first layer is objective. See ADR-0006. (08)
  • Sparse-graph rule: never maintain a complete N×N social matrix — sparse acquaintance/witness/family/faction edges only, evidenced by Socialog's 15-25ms→600ms per-tick cost growth from 50→450 characters. See ADR-0006. (08)
  • Observer-local reputation: Beta-distribution (alpha, beta) per (observer, subject, context), never one global score. See ADR-0006. (08)
  • Inspectability: every derived social outcome must answer "who believes this, from what evidence, through whom, since when." See ADR-0007. (08)
  • Dashboard map backdrop: no permissively-licensed Whiterun map exists; generate the backdrop yourself (CK Create Local Maps over WhiterunWorld, or esm-geometry parsing at install time) and treat the generator as the distributable artifact, never the rendered image. Whiterun is its own worldspace (0x0001A26F) with interior cells on local coordinates — the map tool needs per-cell layers. (12)
  • Dashboard frontend prior art: uesp-gamemap code is MIT (tile pyramid + marker layer); Stanford's generative_agents is Apache-2.0 and its successor StanfordHCI/genagents is MIT (both verified 2026-08-22) — contributing time-scrubbed replay, the key pattern for rumor/belief debugging. Coordinate extraction: skyrim-cell-dump (MIT — Cargo.toml declaration, verified) + Mutagen or a short xEdit script; NPC schedule targets need PACK records. WhiterunWorld FormID 0x0001A26F; cell math floor(gameX/4096), two-point affine calibration is exact for Skyrim's linear projection. (12)
  • Live telemetry channel: in-process SKSE plugin hosting a local WebSocket (SkyrimWebSocket — MIT verified, CommonLibSSE-NG multi-runtime, 1.6.1170-compatible, active 2026-08) is the adopted reference; its wire protocol and spatial JSON block are Chronicle's canonical transport/ActorLocation schema (13). Fork plan for the bulk-actor stream (RE::ProcessLists resolver) has exact hook points. Reject external memory-reading. (12, 13)
  • Sim trace/replay format: adopt Smallville's step-file schema + delta compression (only-changed agents per step) for the headless JSONL trace; dashboard adds the scrubber Smallville lacks. One frontend, two feeds (headless sim now, SkyrimWebSocket later). (13)
  • Isometric/2.5D backdrop: renderable from real game geometry without a from-scratch renderer — fo76utils (MIT, pending TES5-statics verification) or ByroRedux (MIT, verified rendering WhiterunWorld, heavier); both read the user's own game files so no Bethesda assets ship. The downloaded 1.6.1170 depot files serve as the render corpus without touching the live install. (14)

Merged [RISK] list

  • SkyrimNet build-vs-study disagreement — see Open Questions below; this is the sharpest unresolved item and bears directly on ADR-0003. (01)
  • VRAM contention: Skyrim (6–9GB) + local LLM (3.5–5GB) + TTS must coexist on a single 10–16GB consumer GPU — forces the voice tier to sub-1GB models (Chatterbox-Turbo/Nano); larger/expressive TTS models must be one-time/offline use only. (04)
  • Licensing/personality-rights: Coqui XTTS v2 (Mantella's current TTS) is CPML non-commercial-only; Nexus Mods bans non-consensual real-voice-actor clones. Fully synthetic description-driven voices (Qwen3-TTS-VD) are the only legally defensible path for a distributed free mod. (04)
  • Sparse vanilla relationship data: only ~586 relationships across 397 NPCs found in one RELA audit — most of Chronicle's social graph must be synthesized, not extracted. (01)
  • Engine-update fragility: SKSE plugins (including any custom bridge) break on Bethesda engine updates (one flagged Aug 14 2026) — keep the Python/simulation side fully decoupled from the thin in-game bridge so an update only breaks the adapter, not the sim. (01)
  • "More LLM agents degrades fidelity" is real but nuanced — it's a cost/diversity/calibration effect, not a hard population ceiling; scaling total population is fine, scaling the LLM-driven share of it is what hurts. (03)
  • Persona drift, formality collapse, memory fabrication are documented and quantified in long-running LLM agents (Multi-IF, Laban et al., Lifelong-SOTOPIA, GATSim); mitigated by provenance-typed writes and per-turn persona re-injection, not by longer context windows. (03)
  • Evaluation is the field's acknowledged bottleneck, not model capability — plan for regression scenarios against designer-defined curves plus held-out human rating from day one; never validate with an LLM judge that was also used to generate the content being judged. (03)
  • City of Gangsters' >20-rule ceiling, CK3's throttle from ~300 to ~30 AI interactions per character per century post-launch — legibility and a per-tick interaction budget cap matter more than model sophistication at ~1,000-NPC scale. (02)
  • No prior Skyrim reputation/rumor mod actually implements propagation — confirms this is a genuine gap, not reinvention, but also means there's no prior art to lean on for the game-side UX of surfacing rumors to the player. Closest exception found: SkyrimNet's community plugin IntelEngine ships "gossip chains that propagate between NPCs" — the first shipped NPC-to-NPC propagation found across four independent reports — but the payload stays textual/LLM-generated and does not re-drive AI packages or disposition. (01, 15, 17)
  • An external-process architecture bypasses Papyrus compute and save-bloat, but not the write-back walls — results still have to enter the game through the same narrow engine hooks everyone else uses (barter price calc, vendor gold, dialogue conditions, leveled-list injection), and those hooks carry their own hard limits (the 32,767 signed-16-bit vendor-gold cap; the fBarterBuyMin price floor; merchant chests only populating on barter-menu open). The open engineering question is sharpened by report 18 into two specific, named, unattempted problems: continuous event exfiltration from the engine at scale, and NPC-merchant persistent state independent of the chest-respawn timer. (15, 16, 18)
  • The 2025–2026 native-SKSE-hook pricing generation (Dynamic Pricing/Prices Frameworks, The Gilded Road) is a strong reception signal for Chronicle's own architecture bet: The Gilded Road's 1,049-upvote release thread is the most enthusiastically received economy mod in the surveyed record, and it's explicitly "no scripts, no dirty edits, no save bloat" — direct community validation that external-computation-plus-thin-engine-footprint is what players reward, not just what avoids engine walls. (18)
  • No in-engine mod can simulate off-screen NPC life at all — this is an absence-of-execution wall, not a performance wall. AI/scripts simply do not run for unloaded actors, and loaded actors have a documented one-hour position-update bug on top (NPC AI Process Position Fix - NG). Chronicle's external process bypasses an absence, not just a slowdown. (17)
  • Dynamic quest generation is bounded to combinatorial alias-matching over pre-authored templates — the engine cannot synthesize new quest logic at runtime under any architecture, since TESQuest forms must be compiled into a plugin before runtime and no SKSE plugin can construct arbitrary serialized quest forms in memory without corruption risk. Any future GM/director layer's "generation" has to mean template selection + alias binding, never new logic. (19)
  • A GM/director layer, if ever built, converges independently on the same four-stage pipeline from both the Skyrim-specific angle and the cross-game academic-literature angle: input (simulation state) → recognition/sifting (find dramatically interesting configurations) → intervention (map to an available engine verb) → presentation (surface via journal/dialogue/spawns). Provenance-anchored intervention — generating content from already-tracked simulation state rather than decorating an independently-rolled event — is the load-bearing idea across both reports and the closest thing to a validated design principle for this deferred layer. (19, 20, comparative-systems/ai-directors-and-drama-management.md, comparative-systems/ai-directors-and-drama-management-v2.md)
  • Invest in intervention vocabulary before selection intelligence — the single sharpest lesson from the academic drama-management failure record. Search-based drama management failed to transfer from Deadline to Anchorhead not because the optimizer was weak but because the authored DM actions were too weak to move story quality; a synthetic "maximally powerful" action set fixed it even with a weaker algorithm. Any future Chronicle GM should prioritize a rich, provenance-carrying action vocabulary over a clever picker. (comparative-systems/ai-directors-and-drama-management-v2.md)
  • No API exists to write arbitrary free text into Skyrim's native quest journal — only pre-authored, token-slotted templates. SetObjectiveDisplayed toggles a pre-authored objective by index; the only text-injection mechanism is <Alias=...>/stores-text token replacement, capped at 259 characters per paragraph via the community's Dynamic Book Entries workaround. Any GM-generated journal content must be authored as short, token-slotted template text, never generated prose. (20)
  • A former Bethesda designer's own postmortem is the sharpest primary-source confirmation yet that legibility, not generation quality, is the core risk of any hidden simulation: "the deep Radiant AI reactions happened off-screen and the player never noticed them… we were doing a lot of work that the players wouldn't or even couldn't appreciate" (Fred Zeleny). This upgrades Chronicle's inspectability requirement (docs/decisions/0007-inspectability.md) from a debugging/trust nicety to the specific fix for the failure mode that sank Bethesda's own original ambitions for this exact system. (21)
  • Hard 2024–2026 benchmark evidence that unconstrained LLM narration drifts badly, and three named systems that don't: NCP-Bench reports 40–68% fact-conflict rates and <14% narrative-commitment satisfaction for pure LLM narrators; TSL-automata neuro-symbolic control reaches ≥96% adherence vs. 14.67% for pure LLM; function-calling into a constraint-enforcing back-end never produced an invalid output. Slice of Life (deterministic symbolic sim + LLM restricted to surface text only, no feedback into simulation state) is the closest published analog to Chronicle's own committed architecture. (comparative-systems/ai-directors-and-drama-management-v3.md)
  • Perceived fairness is not the same as statistical fairness (Sid Meier's Civilization rubber-banding history) — a well-calibrated reprisal can still read as unfair if it violates player expectation, a distinct failure mode from "invisible decisive variables" that needs its own tuning pass, not just legibility. (comparative-systems/ai-directors-and-drama-management-v3.md)
  • A commercial AI-GM product (Friends & Fables' ACE-1) independently converged on Chronicle's belief-provenance model under production pain: after its v1 suffered LLM state-drift ("a creature narrated both dead and alive"), its redesign separated the GM (face) from a campaign engine (truth) storing atomic, provenance-carrying memory facts, plus a "View Context" transparency feature — "when an LLM lacks a source of truth, it's more prone to making things up." If Chronicle ever surfaces GM-generated content to players, an equivalent context-inspector is the concrete, shipped-precedent way to earn trust. (comparative-systems/ai-directors-and-drama-management-v4.md)
  • Deep simulation the presentation layer can't surface is wasted depth — Wildermyth's own team built and discarded a more simulationist overland map for exactly this reason. Since Chronicle's architecture bets heavily on a rich, sparse social-simulation graph, this is a direct caution: concentrate depth where the presentation layer can actually show it, not just where the simulation can compute it. (comparative-systems/ai-directors-and-drama-management-v4.md)
  • No existing mod solves save/reload consistency cleanly — Mantella ignores it (drift), CHIM prunes globally by clock comparison (not per-slot), SkyrimNet's reload story is disputed between the two batch-2 reports (in-process/no fork vs. an explicit but unverified cleanup protocol). This is now addressed by ADR-0004/0005, but remains one of the least-precedented parts of the design — expect to implement and test from scratch. (05, 06)
  • FormID instability: a stored 32-bit FormID becomes invalid if the player's load order changes (mod add/remove/reorder shifts the ModIndex bits). Chronicle must never persist raw FormIDs. (06)
  • SkyrimNet direct coupling rated HIGH RISK as a sole dependency: closed C++ core, no LICENSE file, single Ko-fi-funded maintainer, in-process design means a core exception is a crash-to-desktop. Mitigated, not eliminated, by the SAL (07).
  • API version drift, with concrete integrator damage: v6→v9 in ~1 month (Beta18→Beta20); Beta21 shipped explicit breaking changes; IntelEngine hard-gated on a specific version and once blocked on an unreleased build; SeverActions hit an init-ordering deadlock and a schema break. This concrete evidence is what moved SkyrimNet from "primary provider, hedged" (07) to "optional adapter, pinned" (10) — see ADR-0003's amendment. (07, sharpened by 10)
  • No LICENSE/continuity statement, now confirmed via exhaustive-as-possible targeted search (not just "not found in passing") across GitHub, docs, FAQ, Patreon, Ko-fi, Reddit. Action item tracked in notes/ideas.md: ask the maintainer directly. (10)
  • Dashboard asset licensing traps: every ready-made Whiterun map asset is non-redistributable (Prima-guide-derived GameMapScout map; CC BY-NC-ND DeviantArt maps; proprietary MapGenie; Bethesda-derived UESP/CK renders); modmapper/esper/SkyrimNet-GamePlugin are source-available with no LICENSE — internal use OK, no vendoring. Bulk-downloading Nexus mods violates Nexus ToS. (12)

Open questions raised

See docs/decisions/open-questions.md:

  • Resolved by direct repo verification: MinAI is deprecated (confirmed), Mantella's latest release is v0.14 published 2026-04-21 (confirmed), CHIM/HerikaServer is MIT-licensed (confirmed). Report 01 has been corrected in place.
  • Closed by research: save/reload timeline consistency — reports 05 and 06 answered the drafted prompt. ADR-0004 (timeline branching) and ADR-0005 (sync handshake) are now drafted from their recommendations, and chronicle/events.py carries a branch key. Two implementation-risk uncertainties carried forward (not fully resolved): CHIM's exact fork trigger is reconstructed, not confirmed; the save-embedded-UUID pattern has no confirmed Skyrim precedent. A third disagreement surfaced between reports 05 and 06 on how SkyrimNet itself handles reloads (implicit/none vs. an explicit but unverified cleanup protocol) — logged, not resolved, since Chronicle doesn't depend on SkyrimNet's own reload behavior for its own protocol either way.
  • Closed by research: SkyrimNet build-vs-study — report 07 resolves ADR-0003 with a Substrate Abstraction Layer, rating direct SkyrimNet coupling HIGH RISK and the SAL hedge MEDIUM RISK. ADR-0003 is now accepted.
  • Researched and deferred, not forgotten: economic simulation (prices, supply, trade ripple) — report 16 surveys the mod prior art and engine write-back limits ahead of need, but the tier itself stays out of scope until the belief tier is proven, slated v0.4.
  • Closed by research (batch 6, out of cycle): game version pin — three independent reports, fired in response to the 1.7.99 patch breaking the plugin ecosystem on 2026-08-20, unanimously recommend pinning to 1.6.1170 + SKSE 2.2.6. Resolved as ADR-0008. This was flagged as a real gap in notes/ideas.md before any report addressed it.
  • Closed by research (batch 7, dashboard): Whiterun map assets / licensing for the debug dashboard — report 12 answers "can we build and distribute a 2D Whiterun map tool" (yes: generate the backdrop, ship the generator, reuse MIT/Apache prior art, in-process SKSE WebSocket for live telemetry). Feeds the dashboard slice, not an ADR — no decision-record change needed.

Research phase: complete (pre-build); build-phase reports continue

11 reports across 6 batches covered the pre-build questions (batch 6 arrived after v0.1 was already accepted and build had started — the 1.7.99 patch forced an out-of-cycle research pass). Build-phase research continues as needed: batch 7 (report 12, dashboard map assets/licensing, 3 reports merged) arrived during the v0.1 build; batch 8 (reports 13/14, dashboard source-level prior art and isometric-render foundations), batch 9 (reports 15/16, Skyrim social-reactivity and economy mod prior art), and batch 10 (reports 17/18, third independent passes on the same two batch-9 topics) followed the same pattern — ahead-of-need surveys filed for later milestones (the dashboard and the v0.4 economy tier respectively), not blocking current build work. Every ADR the pre-build research surfaced a need for has been drafted: 0001/0002 (accepted at scaffold time), 0003 (substrate, amended once), 0004/0005 (timeline branching / sync handshake — independently confirmed four times over), 0006 (data ownership layers), 0007 (inspectability), 0008 (game version pin). The project is in build: chronicle/claims.py (layer 2/3 claim/variant/belief store) is the first code milestone, per docs/v0.1-spec.md.