Add reference docs for Rokojori base/GameState/Dialog/Simulation, update outline
Document the systems implemented this session (per-system reference pages under workspace/reference/), and bring outline/index.page's Current State and What's Next back in sync with actual project state instead of the stale project-creation placeholders.
This commit is contained in:
parent
d684ad0355
commit
ff41b7bef4
|
|
@ -1 +1 @@
|
||||||
{"version":2,"activePortraitPanel":"center","panels":{"left":{"weight":0.138075,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"file-tree-gh70t3rm1nf","tabs":[{"id":"file-tree-gh70t3rm1nf","label":"/","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"","openPaths":[".roject"],"selectedPath":".gitignore","scrollTop":0}},{"id":"file-tree","label":"Scripts","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"Assets/Scripts","openPaths":["Assets/Scripts/Project","Assets/Scripts/Rokojori/Dialog","Assets/Scripts/Rokojori/Dialog/Conditions","Assets/Scripts/Rokojori/Dialog/Testing"],"selectedPath":"Assets/Scripts/Rokojori","scrollTop":0}},{"id":"file-tree-lo16p0vjz1f","label":"workspace","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"workspace","openPaths":["workspace/actions","workspace/actions/tave-over-session","workspace/boards","workspace/guides","workspace/outline","workspace/outline/tech","workspace/rojos","workspace/rojos/local-claude"],"selectedPath":"workspace/boards/tasks.page","scrollTop":0}}]}]}]},"center":{"weight":0.320084,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"code-panel-fmsze866lks","tabs":[{"id":"page-editor","label":"tasks.page","panelType":"page-editor","tag":"page-editor-panel","openFile":"workspace/boards/tasks.page","state":{"scroll":{"x":0,"y":0}}},{"id":"code-panel-fmsze866lks","label":"global.json","panelType":"code-panel","tag":"code-panel","openFile":"global.json","state":{"scroll":{"left":0,"top":0}}}]}]}]},"right":{"weight":0.541841,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"terminal-panel-91mi0dc51p5","tabs":[{"id":"rojo-chat-yo0k9ambmqa","label":"Code Claude · 3c3cb234","panelType":"rojo-chat","tag":"rojo-chat-panel","openFile":null,"state":{"rojoId":"6bcb4a78-54ea-43bd-a67d-c231049a056e","sessionId":"3c3cb234-3120-44f1-81d0-ae90bc92c8da","promptRatio":0.25472747497219134}},{"id":"terminal-panel-91mi0dc51p5","label":"Terminal","panelType":"terminal-panel","tag":"terminal-panel","openFile":null,"state":{"cwd":"C:\\rokojori\\projects\\unity-projects\\Unity-Roject-Test","shellId":"powershell","legacyMiddleClick":false}},{"id":"rojo-chat-hou9naf0lus","label":"Code Claude · 77e12657","panelType":"rojo-chat","tag":"rojo-chat-panel","openFile":null,"state":{"rojoId":"6bcb4a78-54ea-43bd-a67d-c231049a056e","sessionId":"77e12657-114e-470b-a22f-c05509121c80","promptRatio":0.11123470522803114}}]}]}]}}}
|
{"version":2,"activePortraitPanel":"center","panels":{"left":{"weight":0.138075,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"file-tree-gh70t3rm1nf","tabs":[{"id":"file-tree-gh70t3rm1nf","label":"/","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"","openPaths":[".roject"],"selectedPath":".gitignore","scrollTop":0}},{"id":"file-tree","label":"Scripts","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"Assets/Scripts","openPaths":["Assets/Scripts/Project","Assets/Scripts/Rokojori/Dialog","Assets/Scripts/Rokojori/Dialog/Conditions","Assets/Scripts/Rokojori/Dialog/Testing"],"selectedPath":"Assets/Scripts/Rokojori","scrollTop":0}},{"id":"file-tree-lo16p0vjz1f","label":"workspace","panelType":"file-tree","tag":"file-tree-panel","openFile":null,"state":{"rootPath":"workspace","openPaths":["workspace/actions","workspace/actions/tave-over-session","workspace/boards","workspace/guides","workspace/outline","workspace/outline/tech","workspace/rojos","workspace/rojos/local-claude"],"selectedPath":"workspace/boards/tasks.page","scrollTop":0}}]}]}]},"center":{"weight":0.320084,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"code-panel-fmsze866lks","tabs":[{"id":"page-editor","label":"tasks.page","panelType":"page-editor","tag":"page-editor-panel","openFile":"workspace/boards/tasks.page","state":{"scroll":{"x":0,"y":0}}},{"id":"code-panel-fmsze866lks","label":"global.json","panelType":"code-panel","tag":"code-panel","openFile":"global.json","state":{"scroll":{"left":0,"top":0}}}]}]}]},"right":{"weight":0.541841,"sections":[{"weight":1,"tabContainers":[{"weight":1,"activeTabId":"rojo-chat-yo0k9ambmqa","tabs":[{"id":"rojo-chat-yo0k9ambmqa","label":"Code Claude · 3c3cb234","panelType":"rojo-chat","tag":"rojo-chat-panel","openFile":null,"state":{"rojoId":"6bcb4a78-54ea-43bd-a67d-c231049a056e","sessionId":"3c3cb234-3120-44f1-81d0-ae90bc92c8da","promptRatio":0.25472747497219134}},{"id":"terminal-panel-91mi0dc51p5","label":"Terminal","panelType":"terminal-panel","tag":"terminal-panel","openFile":null,"state":{"cwd":"C:\\rokojori\\projects\\unity-projects\\Unity-Roject-Test","shellId":"powershell","legacyMiddleClick":false}},{"id":"rojo-chat-hou9naf0lus","label":"Code Claude · 77e12657","panelType":"rojo-chat","tag":"rojo-chat-panel","openFile":null,"state":{"rojoId":"6bcb4a78-54ea-43bd-a67d-c231049a056e","sessionId":"77e12657-114e-470b-a22f-c05509121c80","promptRatio":0.11123470522803114}}]}]}]}}}
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
<full--width--block data--page--block>
|
<full--width--block data--page--block>
|
||||||
<full--width--area data--page--area contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>History</h1></full--width--area>
|
<full--width--area data--page--area contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>History</h1></full--width--area>
|
||||||
</full--width--block>
|
</full--width--block>
|
||||||
|
<full--width--block data--page--block>
|
||||||
|
<full--width--area data--page--area contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>25 September 2026 - Reference & Outline Update</h2><div>Wrote four reference pages documenting the systems built earlier today: <a href="../reference/rokojori-base/index.page">reference/rokojori-base</a> (Unique, EventSlot, Locale, RJLog, extensions), <a href="../reference/game-state/index.page">reference/game-state</a>, <a href="../reference/dialog/index.page">reference/dialog</a>, and <a href="../reference/simulation/index.page">reference/simulation</a>. Linked all four from reference/index.page under a new "By System" section.</div><div><br></div><div>Each page leads with the non-obvious part rather than restating the code: for Game State, the asset/runtime-value split and why <code>key</code> exists separately from the inherited <code>name</code>; for Dialog, the per-block-type behaviour table and the DialogList flow assumption; for Simulation, that <code>playerCount</code> and the renderer are placeholders with nothing wired up yet.</div><div><br></div><div>Ran the Update Outline action: <a href="../outline/index.page">outline/index.page</a>'s "Current State" and "What's next" sections had been stale since project creation ("It just started, only the first initial files exist") - replaced with the actual state (three singletons implemented, not yet Editor-verified, no real UI) and a concrete next-steps list. No code changed in this entry - documentation only.</div></full--width--area>
|
||||||
|
</full--width--block>
|
||||||
<full--width--block data--page--block>
|
<full--width--block data--page--block>
|
||||||
<full--width--area data--page--area contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>25 September 2026 - Implementation Session</h2><div>Took over the "Session Hand-Over: Tech Outline Normalization" task, confirmed the Dialog Manager section of <a href="../outline/tech/index.page">outline/tech/index.page</a> read correctly, then implemented all three Tech Areas from that outline: Game State Management, Dialog Management, and Simulation Management. Code lives under Assets/Scripts/Rokojori/GameState/, Dialog/, and Simulation/ (about 28 files). Removed the stale "Get Initial Picture" board task (its description no longer matched what had actually happened) and closed out the hand-over task.</div><div><br></div><h3>Compile Toolchain</h3><div>Set up a way to verify C# compiles without opening the Unity Editor - see <a href="../guides/compiling-without-unity/index.page">guides/compiling-without-unity/index.page</a>. Two things were needed: a <code>global.json</code> pinning the SDK to 8.0.417 (the default .NET 10.0.401 SDK crashes compiling Unity's generated csproj on this machine - a Windows/CET incompatibility, not a project issue), and a hand-written <code>CompileCheck.csproj</code> that globs Assets/Scripts/Rokojori and Assets/Scripts/Project directly, since Unity's own generated Assembly-CSharp.csproj only lists files present at its last sync and won't pick up files written outside the Editor. All new code compiles clean against this (2 pre-existing, harmless serialization-analyzer warnings on EventSlot fields, unrelated to this session's code). This has only been compile-checked, never run in Unity - see the new "Verify in Unity Editor" board task.</div><div><br></div><h3>Coding Convention Correction</h3><div>Wrote the first pass without noticing <a href="../guides/Writing-C#/index.page">guides/Writing-C#/index.page</a> - it exists but wasn't linked from guides/index.page (now fixed, and linked here alongside the new compiling guide). Had to go back and fix: no bare <code>private</code> fields (use public with an underscore prefix, or protected), no parameterized constructors (DialogProcessor changed to a static <code>Create()</code> factory), switch statements replaced with if/else-if chains (CompareInt, ListCondition), and explicit initial values added to all fields that lacked them.</div><div><br></div><h3>Decisions</h3><div>Kept GameStateManager's per-type value dictionaries as the runtime source of truth (marked <marked-text>[NonSerialized]</marked-text>), with GameStateVariable ScriptableObjects only holding the initial value and a stable <marked-text>key</marked-text> field for JSON save/load - editor-facing "name" (inherited from UnityEngine.Object) stays separate from save identity.</div><div><br></div><div>DialogManager.Show() throws NotImplementedException rather than faking a response - there is no UI to wire it to yet (Assets/UI is empty). SimulationRenderer.Enqueue() is a similar placeholder that completes instantly. Both are flagged as open To Do items rather than silently pretending to work.</div><div><br></div><h3>Assumptions Needing Sign-off</h3><div>The tech outline left several implementation details unspecified. Filled them in with the simplest defensible choice and flagged all five in outline/tech/index.page under "Implementation Status" rather than guessing silently: DialogList's flow semantics (flat sequence, ignores children's own "next"), PlayerChoice options gaining an optional GameStateAction, HasObject modelled as a bool flag (no inventory system exists), SimulationManager.playerCount as a plain int (no Player type is defined anywhere), and GameStateVariable.key replacing the outline's literal (but already-inherited) "name" field. See the new "Sign Off Implementation Assumptions" board task.</div><div><br></div><h3>Not Done</h3><div>SimulateWorld and ShowTurnStartConditions (the example GamePhase subclasses) were described only narratively in the outline with no code contract, so they weren't written - see the "Example Simulation Phases" board task. DialogPhase was written since GamePhase now exists, closing a gap from last session.</div></full--width--area>
|
<full--width--area data--page--area contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>25 September 2026 - Implementation Session</h2><div>Took over the "Session Hand-Over: Tech Outline Normalization" task, confirmed the Dialog Manager section of <a href="../outline/tech/index.page">outline/tech/index.page</a> read correctly, then implemented all three Tech Areas from that outline: Game State Management, Dialog Management, and Simulation Management. Code lives under Assets/Scripts/Rokojori/GameState/, Dialog/, and Simulation/ (about 28 files). Removed the stale "Get Initial Picture" board task (its description no longer matched what had actually happened) and closed out the hand-over task.</div><div><br></div><h3>Compile Toolchain</h3><div>Set up a way to verify C# compiles without opening the Unity Editor - see <a href="../guides/compiling-without-unity/index.page">guides/compiling-without-unity/index.page</a>. Two things were needed: a <code>global.json</code> pinning the SDK to 8.0.417 (the default .NET 10.0.401 SDK crashes compiling Unity's generated csproj on this machine - a Windows/CET incompatibility, not a project issue), and a hand-written <code>CompileCheck.csproj</code> that globs Assets/Scripts/Rokojori and Assets/Scripts/Project directly, since Unity's own generated Assembly-CSharp.csproj only lists files present at its last sync and won't pick up files written outside the Editor. All new code compiles clean against this (2 pre-existing, harmless serialization-analyzer warnings on EventSlot fields, unrelated to this session's code). This has only been compile-checked, never run in Unity - see the new "Verify in Unity Editor" board task.</div><div><br></div><h3>Coding Convention Correction</h3><div>Wrote the first pass without noticing <a href="../guides/Writing-C#/index.page">guides/Writing-C#/index.page</a> - it exists but wasn't linked from guides/index.page (now fixed, and linked here alongside the new compiling guide). Had to go back and fix: no bare <code>private</code> fields (use public with an underscore prefix, or protected), no parameterized constructors (DialogProcessor changed to a static <code>Create()</code> factory), switch statements replaced with if/else-if chains (CompareInt, ListCondition), and explicit initial values added to all fields that lacked them.</div><div><br></div><h3>Decisions</h3><div>Kept GameStateManager's per-type value dictionaries as the runtime source of truth (marked <marked-text>[NonSerialized]</marked-text>), with GameStateVariable ScriptableObjects only holding the initial value and a stable <marked-text>key</marked-text> field for JSON save/load - editor-facing "name" (inherited from UnityEngine.Object) stays separate from save identity.</div><div><br></div><div>DialogManager.Show() throws NotImplementedException rather than faking a response - there is no UI to wire it to yet (Assets/UI is empty). SimulationRenderer.Enqueue() is a similar placeholder that completes instantly. Both are flagged as open To Do items rather than silently pretending to work.</div><div><br></div><h3>Assumptions Needing Sign-off</h3><div>The tech outline left several implementation details unspecified. Filled them in with the simplest defensible choice and flagged all five in outline/tech/index.page under "Implementation Status" rather than guessing silently: DialogList's flow semantics (flat sequence, ignores children's own "next"), PlayerChoice options gaining an optional GameStateAction, HasObject modelled as a bool flag (no inventory system exists), SimulationManager.playerCount as a plain int (no Player type is defined anywhere), and GameStateVariable.key replacing the outline's literal (but already-inherited) "name" field. See the new "Sign Off Implementation Assumptions" board task.</div><div><br></div><h3>Not Done</h3><div>SimulateWorld and ShowTurnStartConditions (the example GamePhase subclasses) were described only narratively in the outline with no code contract, so they weren't written - see the "Example Simulation Phases" board task. DialogPhase was written since GamePhase now exists, closing a gap from last session.</div></full--width--area>
|
||||||
</full--width--block>
|
</full--width--block>
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
<full--width--block>
|
<full--width--block>
|
||||||
<full--width--area><h2>Vision</h2><div><font color="#929caf">A project I can open to showcase a small simulation game that has some story during a simulation game for Unity</font></div></full--width--area>
|
<full--width--area><h2>Vision</h2><div><font color="#929caf">A project I can open to showcase a small simulation game that has some story during a simulation game for Unity</font></div></full--width--area>
|
||||||
</full--width--block><two--columns--block data--page--block="">
|
</full--width--block><two--columns--block data--page--block="">
|
||||||
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Current State</h2><div>It just started, only the first initial files exist</div></two--columns--area>
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Current State</h2><div>The three core singletons all have code now: <marked-text>GameStateManager</marked-text>, <marked-text>DialogManager</marked-text> (with a full DialogProcessor/DialogBlock graph engine), and <marked-text>SimulationManager</marked-text> (turn loop over GamePhases). See <a href="../reference/index.page">reference/index.page</a> for how each one works.</div><div><br></div><div>None of it has been opened in the Unity Editor yet - only compile-checked outside it (see <a href="../guides/compiling-without-unity/index.page">guides/compiling-without-unity/index.page</a>). There is no real UI - DialogManager's Show() throws, and the SimulationRenderer is a stub that completes instantly.</div></two--columns--area>
|
||||||
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>What's next</h2><div>Building the singletons</div></two--columns--area>
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>What's next</h2><div>1. Open the project in the Unity Editor and verify the new scripts actually work there (create test assets, check the console).</div><div>2. Sign off on a handful of implementation assumptions the tech outline left open - see <a href="tech/index.page">outline/tech/index.page</a>, "Implementation Status".</div><div>3. Build real dialog UI and wire it into DialogManager.</div><div>4. Write concrete example GamePhases (turn-start conditions, world simulation) once the state they need to track is clearer.</div></two--columns--area>
|
||||||
</two--columns--block>
|
</two--columns--block>
|
||||||
<two--columns--block>
|
<two--columns--block>
|
||||||
<two--columns--area><h2 style="letter-spacing: -0.3px;">MVP/Core Features</h2><div style="color: rgb(146, 156, 175); letter-spacing: -0.3px;">Demonstrating mainly the code needed for a narrivative heavy simulation game</div></two--columns--area>
|
<two--columns--area><h2 style="letter-spacing: -0.3px;">MVP/Core Features</h2><div style="color: rgb(146, 156, 175); letter-spacing: -0.3px;">Demonstrating mainly the code needed for a narrivative heavy simulation game</div></two--columns--area>
|
||||||
<two--columns--area><h2 style="letter-spacing: -0.3px;">Highlights & Details</h2><div style="letter-spacing: -0.3px; color: rgb(146, 156, 175);">Nothing there yet</div></two--columns--area>
|
<two--columns--area><h2 style="letter-spacing: -0.3px;">Highlights & Details</h2><div style="letter-spacing: -0.3px; color: rgb(146, 156, 175);">A data-driven dialog graph (branching, conditions, actions, all as ScriptableObject assets) that runs standalone or as a phase inside the turn loop - see <a href="../reference/dialog/index.page">reference/dialog/index.page</a>.</div></two--columns--area>
|
||||||
</two--columns--block><two--columns--block>
|
</two--columns--block><two--columns--block>
|
||||||
<two--columns--area><h2>Tech Stack</h2><div><font color="#929caf">There are more pages about this, since this will be created:<br><a href="tech/index.page">workspace/outline/tech/index.page</a></font></div></two--columns--area>
|
<two--columns--area><h2>Tech Stack</h2><div><font color="#929caf">There are more pages about this, since this will be created:<br><a href="tech/index.page">workspace/outline/tech/index.page</a></font></div></two--columns--area>
|
||||||
<two--columns--area><h2 style="letter-spacing: -0.3px;">Misc</h2><div style="color: rgb(146, 156, 175); letter-spacing: -0.3px;"><span style="letter-spacing: -0.3px;">Additions</span></div></two--columns--area>
|
<two--columns--area><h2 style="letter-spacing: -0.3px;">Misc</h2><div style="color: rgb(146, 156, 175); letter-spacing: -0.3px;"><span style="letter-spacing: -0.3px;">Additions</span></div></two--columns--area>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"><head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dialog — Unity-Roject-Test</title>
|
||||||
|
<style>
|
||||||
|
@import url('/fonts/barlow.css');
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body data-theme="default-roject">
|
||||||
|
<page--header></page--header>
|
||||||
|
|
||||||
|
<page--root data-theme="default-roject">
|
||||||
|
<full--width--block data--page--block="">
|
||||||
|
<full--width--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>Dialog</h1><div><marked-text>Assets/Scripts/Rokojori/Dialog</marked-text> - a standalone dialog engine plus a UI-facing singleton on top of it. See <a href="../../outline/tech/index.page">outline/tech/index.page</a> for the design intent and the open assumptions this implementation made.</div></full--width--area>
|
||||||
|
</full--width--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>The Three Layers</h2><div><code>DialogProcessor</code> is the engine - it only knows about <code>IDialogDisplay</code>, nothing about UI or DialogManager. <code>DialogManager</code> is the UI-facing singleton - implements <code>IDialogDisplay</code>, and <code>StartDialog()</code> is the only entry point anyone outside this folder should call. <code>DialogPhase</code> (in Simulation/) is a thin wrapper so a dialog can be one step in a turn loop.</div><div><br></div><h2>Execution Loop</h2><div><code>DialogProcessor.Run( start )</code> repeats <code>current = await current.Run( display )</code> until <code>current</code> is null. Each <code>DialogBlock</code> decides its own next step; the base class default is simply "return <code>next</code>" (linear flow), and only <code>PlayerChoice</code> / <code>DialogBranch</code> override that to branch.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Block-by-Block Behaviour</h2><div><strong>DialogLine</strong> - calls <code>display.Show(this)</code>, awaits it, returns <code>next</code>.</div><div><strong>PlayerChoice</strong> - calls <code>display.Show(this)</code>, reads <code>answer.selectedOptionIndex</code>, runs that option's <code>action</code> if set, returns that option's <code>next</code>.</div><div><strong>DialogBranch</strong> - no display call. Returns <code>branch</code> if <code>condition.Evaluate()</code> is true, else the inherited <code>next</code>.</div><div><strong>DialogList</strong> - runs its own <code>blocks</code> in flat order, <marked-text>ignoring each child's own "next"</marked-text> while inside the list, then returns its own <code>next</code>. This is an assumption, not confirmed - see outline/tech "Implementation Status". Practical effect: don't put a PlayerChoice/DialogBranch directly inside a DialogList's <code>blocks</code>, its branch target will be silently discarded.</div><div><strong>ReturnBlock</strong> - always returns null, ending the whole dialog (even if nested inside a DialogList).</div><div><strong>CommentBlock</strong> - editor-only, no override, just falls through to <code>next</code> like the default.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Conditions & Actions</h2><div><code>GameStateCondition</code> (CompareInt, HasObject, ListCondition) and <code>GameStateAction</code> (SetProperty, ModifyProperty, ActionList) both read/write through <code>GameStateManager.instance</code> - they never touch DialogBlock state directly. <code>HasObject</code> currently checks a <code>GameStateBoolVariable</code> flag since there's no inventory/object system to check membership against yet.</div><div><br></div><div><code>PlayerChoice.options[i].action</code> is not in the original design outline - added to give choices a way to change game state, since Conditions and Actions were described as a pair but no block explicitly triggered an Action.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Testing Without UI</h2><div><code>HeadlessDialogDisplay</code> implements <code>IDialogDisplay</code> without any Unity UI - it logs every block it's shown into <code>visitedBlocks</code> and answers PlayerChoice via the <code>chooseOption</code> delegate (defaults to always picking option 0). Drive a dialog with <code>DialogProcessor.Create( new HeadlessDialogDisplay() ).Run( start )</code> to test branching logic in isolation.</div><div><br></div><h2>Gotcha</h2><div><code>DialogManager.Show()</code> currently <marked-text>throws NotImplementedException</marked-text> - there's no real UI wired up yet (Assets/UI is empty). Use HeadlessDialogDisplay for anything that doesn't need to render.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
</page--root>
|
||||||
|
|
||||||
|
<page--footer></page--footer>
|
||||||
|
|
||||||
|
</body></html>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"><head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Game State — Unity-Roject-Test</title>
|
||||||
|
<style>
|
||||||
|
@import url('/fonts/barlow.css');
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body data-theme="default-roject">
|
||||||
|
<page--header></page--header>
|
||||||
|
|
||||||
|
<page--root data-theme="default-roject">
|
||||||
|
<full--width--block data--page--block="">
|
||||||
|
<full--width--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>Game State</h1><div><marked-text>Assets/Scripts/Rokojori/GameState</marked-text> - the shared state layer everything else reads and writes through. See also <a href="../../outline/tech/index.page">outline/tech/index.page</a> for the design intent.</div></full--width--area>
|
||||||
|
</full--width--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>The Split: Asset vs Runtime Value</h2><div>This is the one non-obvious thing about this system. <code>GameStateVariable</code> (and its subtypes <code>GameStateNumberVariable</code> / <code>GameStateBoolVariable</code>) are ScriptableObject <marked-text>assets</marked-text> - shared, on-disk config. They only hold an <code>initialValue</code> and a <code>key</code>. They do not hold the live, current value.</div><div><br></div><div>The actual mutable game state lives in two dictionaries on <code>GameStateManager</code> - <code>_numberValues</code> and <code>_boolValues</code>, both marked <code>[NonSerialized]</code> since they're pure runtime cache, rebuilt from the <code>variables</code> list in <code>Awake()</code>. Never read or write these dictionaries directly - always go through <code>GameStateManager.instance.GetValue(...)</code> / <code>SetValue(...)</code>, which are overloaded per variable type.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>key vs name</h2><div>ScriptableObjects already have a <code>name</code> (inherited from UnityEngine.Object - the asset's filename). <code>GameStateVariable.key</code> is a separate, deliberately-added field used as the stable identifier in JSON save data, so renaming an asset in the editor doesn't silently break old save files.</div><div><br></div><h2>SetValue Also Fires onChanged</h2><div><code>SetValue</code> updates the dictionary <marked-text>and</marked-text> dispatches the variable's own <code>onChanged</code> EventSlot in the same call - there's no separate notify step. Reading via <code>GetValue</code> never fires anything.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Save / Load</h2><div><code>ToJson()</code> / <code>FromJson( json )</code> use Unity's <code>JsonUtility</code>, which can't serialize a <code>Dictionary</code> directly - hence the private <code>NumberEntry</code> / <code>BoolEntry</code> / <code>SaveData</code> classes that flatten the dictionaries into lists of key/value pairs first.</div><div><br></div><div><marked-text>Gotcha:</marked-text> if <code>FromJson</code> finds a saved key that no longer matches any variable in the current <code>variables</code> list, that entry is silently skipped - no error, no warning.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Cheat Sheet</h2><div><code>GameStateManager.instance</code> - the singleton (via Unique<T>).</div><div><code>.GetValue( GameStateNumberVariable )</code> / <code>.GetValue( GameStateBoolVariable )</code></div><div><code>.SetValue( variable, value )</code> - updates + fires onChanged</div><div><code>.ToJson()</code> / <code>.FromJson( json )</code></div><div><br></div><div>To add a new variable type (e.g. string), mirror <code>GameStateNumberVariable</code>: a new <code>GameStateVariable</code> subclass, a new dictionary + Get/SetValue overload pair on GameStateManager, and a new Entry class for JSON.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
</page--root>
|
||||||
|
|
||||||
|
<page--footer></page--footer>
|
||||||
|
|
||||||
|
</body></html>
|
||||||
|
|
@ -18,6 +18,9 @@
|
||||||
</full--width--block><two--columns--block>
|
</full--width--block><two--columns--block>
|
||||||
<two--columns--area><h2>Complicated Code</h2><div>Some code is more complicated that other code. Some has a lot of dependencies or unusal connections. Everything that helps <marked-text>to understand complex code</marked-text> better, can be here.</div><div><br></div></two--columns--area>
|
<two--columns--area><h2>Complicated Code</h2><div>Some code is more complicated that other code. Some has a lot of dependencies or unusal connections. Everything that helps <marked-text>to understand complex code</marked-text> better, can be here.</div><div><br></div></two--columns--area>
|
||||||
<two--columns--area><h2>Cheat Sheets</h2><div><span style="color: rgb(146, 156, 175); letter-spacing: -0.3px;">Not everything needs to complex that can have listing. Some things are trivial but are <marked-text>needed all the time</marked-text>. Conventions, paths, entry points etc.</span></div></two--columns--area>
|
<two--columns--area><h2>Cheat Sheets</h2><div><span style="color: rgb(146, 156, 175); letter-spacing: -0.3px;">Not everything needs to complex that can have listing. Some things are trivial but are <marked-text>needed all the time</marked-text>. Conventions, paths, entry points etc.</span></div></two--columns--area>
|
||||||
|
</two--columns--block><two--columns--block>
|
||||||
|
<two--columns--area><h2>By System</h2><div><a href="rokojori-base/index.page">Rokojori Base</a></div><div>The generic library layer - Unique<T>, EventSlot, Locale, RJLog, extensions.</div><div><br></div><div><a href="game-state/index.page">Game State</a></div><div>GameStateManager and the GameStateVariable asset types.</div></two--columns--area>
|
||||||
|
<two--columns--area><h2> </h2><div><a href="dialog/index.page">Dialog</a></div><div>DialogManager, DialogProcessor, the DialogBlock graph, Conditions and Actions.</div><div><br></div><div><a href="simulation/index.page">Simulation</a></div><div>GamePhase, SimulationManager's turn loop, and the current renderer stub.</div></two--columns--area>
|
||||||
</two--columns--block></page--root>
|
</two--columns--block></page--root>
|
||||||
|
|
||||||
<page--footer></page--footer>
|
<page--footer></page--footer>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"><head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Rokojori Base — Unity-Roject-Test</title>
|
||||||
|
<style>
|
||||||
|
@import url('/fonts/barlow.css');
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body data-theme="default-roject">
|
||||||
|
<page--header></page--header>
|
||||||
|
|
||||||
|
<page--root data-theme="default-roject">
|
||||||
|
<full--width--block data--page--block="">
|
||||||
|
<full--width--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>Rokojori Base</h1><div>The generic library layer under <marked-text>Assets/Scripts/Rokojori</marked-text> - no project code may be referenced from here, only Unity core. Everything else (GameState, Dialog, Simulation) is built on top of this.</div></full--width--area>
|
||||||
|
</full--width--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>Unique<T></h2><div><code>Unique<T>.Get()</code> is the singleton locator used everywhere (<code>GameStateManager.instance</code>, <code>DialogManager.instance</code>, <code>SimulationManager.instance</code>, <code>SimulationRenderer.instance</code>). It searches the root game objects of all open scenes for a component of type T on first access and caches the result statically - there is no manual registration step. This means exactly one instance is expected to exist in the open scenes; a second instance is never detected or warned about.</div><div><br></div><h2>EventSlot<T></h2><div>A plain pub/sub slot - <code>AddAction</code>, <code>RemoveAction</code>, <code>Once</code>, <code>DispatchEvent( value )</code>. Listeners added or removed <marked-text>during</marked-text> a dispatch are queued and only applied after the current dispatch finishes (<code>_canModify</code> guards this) - safe to unsubscribe yourself from inside your own callback.</div><div><br></div><div>Used directly as the type of <code>GameStateNumberVariable.onChanged</code> / <code>GameStateBoolVariable.onChanged</code>.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>EventProperty<T> / ReadonlyEventProperty<T></h2><div>An observable value built on EventSlot. Setting <code>.value</code> only dispatches if the new value differs from the old one (via <code>EqualityComparer<T>.Default</code>) - assigning the same value twice fires nothing. <code>SetSilent()</code> changes the backing value without dispatching. Not currently used by GameState/Dialog/Simulation - those roll their own change tracking (GameStateManager's dictionaries + each variable's own EventSlot) instead.</div><div><br></div><h2>Locale / LocaleText / LocaleCode</h2><div><code>Locale</code> is the abstract base (a ScriptableObject with <code>GetLocale( LocaleCode )</code>); <code>LocaleText</code> is the only concrete implementation and currently just returns its <code>en</code> field <marked-text>regardless of the requested LocaleCode</marked-text> - there is no real per-language switching yet. <code>LocaleManager.currentLocale</code> exists but nothing reads it. DialogLine/PlayerChoice reference Locale assets for their text, so localization can be wired in later without touching Dialog code.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>RJLog</h2><div>Static wrapper over <code>Debug.Log/LogWarning/LogError</code>. Takes a leading object plus a <code>params object[]</code> and space-joins everything into one string - <code>RJLog.Log( "value:", 5, someObject )</code>.</div><div><br></div><h2>ListExtensions</h2><div><code>list.Has( item )</code> (index-based, works without <code>IEquatable</code>) and <code>list.RemoveList( removals )</code> (removes every item in one list from another).</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>SceneExtensions</h2><div><code>scene.Get<T>()</code> and <code>SceneExtensions.GetInOpenScenes<T>()</code> search root game objects (and their children) for a component - this is what <code>Unique<T></code> calls internally.</div><div><br></div><h2>Null</h2><div>An empty marker class with a private constructor - not referenced by anything yet.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
</page--root>
|
||||||
|
|
||||||
|
<page--footer></page--footer>
|
||||||
|
|
||||||
|
</body></html>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"><head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Simulation — Unity-Roject-Test</title>
|
||||||
|
<style>
|
||||||
|
@import url('/fonts/barlow.css');
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body data-theme="default-roject">
|
||||||
|
<page--header></page--header>
|
||||||
|
|
||||||
|
<page--root data-theme="default-roject">
|
||||||
|
<full--width--block data--page--block="">
|
||||||
|
<full--width--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h1>Simulation</h1><div><marked-text>Assets/Scripts/Rokojori/Simulation</marked-text> - the turn loop that drives GamePhases. The least finished of the three systems - see <a href="../../outline/tech/index.page">outline/tech/index.page</a> for what's still missing.</div></full--width--area>
|
||||||
|
</full--width--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>The Turn Loop</h2><div><code>SimulationManager.Run()</code>:</div><div>intro → while not finished: preTurn → playerTurn ×playerCount → postTurn → (loop) → outro.</div><div><br></div><div>Each list is run by <code>RunPhases()</code>, which executes phases in order and checks <code>phase.gameFinished</code> after each one. If any phase sets it, <code>RunPhases</code> returns immediately (skipping the rest of <marked-text>that</marked-text> list) and <code>Run()</code> skips straight to <code>outro</code> instead of continuing the while-loop.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>playerCount Is a Placeholder</h2><div>There is no <code>Player</code> type anywhere in the codebase yet. <code>SimulationManager.playerCount</code> is a plain <code>int</code> defaulting to 1 - nothing currently sets it automatically. An intro phase is expected to set it (e.g. from a GameState variable) before the turn loop needs it, but that phase doesn't exist yet either.</div><div><br></div><h2>GamePhase</h2><div>Abstract ScriptableObject. <code>Execute( GameStateManager, SimulationRenderer )</code> does the work; set <code>gameFinished = true</code> from inside it to end the game early. No concrete example phases exist yet (ShowTurnStartConditions / SimulateWorld were only described narratively in the outline, no code contract given).</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
<two--columns--block data--page--block="">
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>SimulationRenderer / SimulationCommand - Stubs</h2><div><code>SimulationRenderer.Enqueue( command )</code> currently just returns <code>Task.CompletedTask</code> immediately - there's no rendering/animation pipeline behind it. <code>SimulationCommand</code> is an empty abstract base with no concrete commands defined. A GamePhase can call <code>Enqueue</code> today and it will compile and "work" (complete instantly), but nothing will actually happen on screen.</div></two--columns--area>
|
||||||
|
<two--columns--area data--page--area="" contenteditable="true" spellcheck="false" autocorrect="off" autocapitalize="off" style="outline: none;"><h2>DialogPhase</h2><div>Lives here, not in Dialog/, because it's a GamePhase, not part of the dialog engine itself. Just awaits <code>DialogManager.instance.StartDialog( start )</code> - all real logic stays in Dialog/.</div></two--columns--area>
|
||||||
|
</two--columns--block>
|
||||||
|
</page--root>
|
||||||
|
|
||||||
|
<page--footer></page--footer>
|
||||||
|
|
||||||
|
</body></html>
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
{
|
{
|
||||||
"sessionId": "3c3cb234-3120-44f1-81d0-ae90bc92c8da",
|
"sessionId": "3c3cb234-3120-44f1-81d0-ae90bc92c8da",
|
||||||
"startedAt": 1790366226373,
|
"startedAt": 1790366226373,
|
||||||
"lastUsedAt": 1790366817332,
|
"lastUsedAt": 1790368437683,
|
||||||
"firstMessagePreview": "Can you use the action \"take-over-session\"?"
|
"firstMessagePreview": "Can you use the action \"take-over-session\"?"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1871,5 +1871,10 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tokenTotal": 28229
|
"tokenTotal": 28229
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"timestamp": 1790368437684,
|
||||||
|
"text": "You are fast! Very good. \n\nCan you write for every thing something into the reference? \nUse one for the Rokojori base things, like events, locales, and than for each of your field like game state, dialog, simulation. \n\nAfter that run the action \"Update Outline\" to update the state of the project, you can also add some details when you think it makes sense. \n\nAfterwards use the action \"Update History\", use today for the entry, 25th sept. \n\nI pushed all files already, but when you are finished with the refernece and history add all, commit and push. No need to ask again for pushing"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Loading…
Reference in New Issue