refactor: replace stat system with variable system

Replaces the specialized `stat` system with a more general-purpose
variable system. This includes:

- Renaming `ReactiveStatManager` to `ReactiveVariableManager`
- Changing template syntax from `${key}` to `{{$key}}`
- Replacing `StatsView` with `VariableView` to show declared, plain,
  and tag-typed variables
- Updating command `/stat` to `/set`
- Refactoring the reactivity engine to support variable declarations
  and tag modifiers via `csv role=declare` blocks
This commit is contained in:
2026-07-12 17:29:03 +08:00
parent 2983aa4440
commit 894f1735e5
18 changed files with 464 additions and 1063 deletions
+4 -4
View File
@@ -44,7 +44,7 @@ export interface JournalStreamState {
myRole: "gm" | "player" | "observer";
brokerUrl: string | null;
players: Record<string, { role: string }>;
stats: Record<string, string>;
variables: Record<string, string>;
}
export interface SessionMeta {
@@ -96,7 +96,7 @@ const [state, setState] = createStore<JournalStreamState>({
myRole: (persisted.myRole as "gm" | "player" | "observer") || "gm",
brokerUrl: persisted.brokerUrl,
players: {},
stats: {},
variables: {},
});
if (initialName && !urlParams.playerName) syncUrlParam("player", initialName);
@@ -126,7 +126,7 @@ function runReducer(msg: StreamMessage): void {
function replayReducers(): void {
// Reset derived state
setState("revealedPaths", {});
setState("stats", {});
setState("variables", {});
for (const msg of state.messages) {
runReducer(msg);
}
@@ -160,7 +160,7 @@ function handlePatch(patch: WorkerPatch): void {
syncUrlParam("player", patch.state.myName);
}
saveRole(patch.state.myRole);
// Rebuild derived state (revealedPaths, stats) by replaying reducers
// Rebuild derived state (revealedPaths, variables) by replaying reducers
replayReducers();
break;
}