ugly-game 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import type { DeterministicSim } from '../moat';
2
2
  import type { ControlView } from './controlBlock';
3
- import type { CommandQueue } from './commandQueue';
3
+ import type { CommandQueue, Stamped } from './commandQueue';
4
4
  export interface SimClock {
5
5
  now(): number;
6
6
  }
@@ -21,10 +21,11 @@ export interface CoopStepOpts<S, I> {
21
21
  tickOf: (s: S) => number;
22
22
  maxCatchUpFrames?: number;
23
23
  onLate?: (count: number) => void;
24
- /** Called once per tick, with the commands due THIS tick, immediately before `sim.tick`. The seam a game uses
25
- * to drive per-tick co-op diagnostics (a command journal + a checkpoint hash trail) without the primitive
26
- * needing to know their shape. `state` is passed so a checkpoint can hash it (at the top of the tick). */
27
- beforeTick?: (due: I[], state: S) => void;
24
+ /** Called once per tick, with the STAMPED commands due THIS tick (carrying `at`/`seq`/`by`), immediately before
25
+ * `sim.tick`. The seam a game drives per-tick co-op diagnostics through — a command journal (whose digest must
26
+ * fold in `at`/`seq`, so a relay reorder reads as a relay bug, not a sim bug) + a checkpoint hash trail. `state`
27
+ * is passed so a checkpoint can hash it at the top of the tick. */
28
+ beforeTick?: (due: Stamped<I>[], state: S) => void;
28
29
  }
29
30
  export interface SoloStepOpts<S, I> {
30
31
  sim: SimHostSim<S, I>;
@@ -39,7 +40,7 @@ export interface SoloStepOpts<S, I> {
39
40
  fps?: number;
40
41
  maxCatchUpFrames?: number;
41
42
  onLate?: (count: number) => void;
42
- beforeTick?: (due: I[], state: S) => void;
43
+ beforeTick?: (due: Stamped<I>[], state: S) => void;
43
44
  }
44
45
  /** Single-player stepping: derive a target tick from elapsed wall time (a free-run 60-UPS accumulator, clamped by
45
46
  * maxCatchUpFrames), publish it to `ctl.targetTick`, then reuse `coopStepBatch` — so solo and co-op run the identical
@@ -45,12 +45,12 @@ export function coopStepBatch(opts) {
45
45
  if (late && opts.onLate)
46
46
  opts.onLate(late);
47
47
  }
48
- const inputs = due.map((d) => d.c);
49
- // Per-tick diagnostics seam: the game records the applied stream + a checkpoint hash of the top-of-tick state,
50
- // BEFORE the tick mutates it. Fires every tick (solo + co-op) so a journal can't silently skip history.
48
+ // Per-tick diagnostics seam: the game records the applied (stamped) stream + a checkpoint hash of the
49
+ // top-of-tick state, BEFORE the tick mutates it. Fires every tick (solo + co-op) so a journal can't silently
50
+ // skip history. The sim itself only needs the bare commands.
51
51
  if (opts.beforeTick)
52
- opts.beforeTick(inputs, opts.state);
53
- opts.sim.tick(opts.state, inputs);
52
+ opts.beforeTick(due, opts.state);
53
+ opts.sim.tick(opts.state, due.map((d) => d.c));
54
54
  stepped++;
55
55
  };
56
56
  // STEP_BUDGET burst first (forced, deterministic — independent of the target).
@@ -1,6 +1,7 @@
1
1
  import type { Layout } from './layout';
2
2
  import { type ControlView } from './controlBlock';
3
3
  import { type SimHostSim } from './simCore';
4
+ import { type Stamped } from './commandQueue';
4
5
  /** A reply a worker posts back to the main thread. Must be structured-cloneable. Echo the originating request's
5
6
  * `rid` so the main thread's `host.request()` Promise resolves on it; any other fields are the game's payload. */
6
7
  export interface SimWorkerReply {
@@ -17,7 +18,7 @@ export interface SimWorkerConfig<S, I> {
17
18
  layout: Layout<S> | ((init: Record<string, unknown>) => Layout<S>);
18
19
  tickOf: (s: S) => number;
19
20
  mirror?: (s: S, ctl: ControlView<string>) => void;
20
- beforeTick?: (due: I[], state: S) => void;
21
+ beforeTick?: (due: Stamped<I>[], state: S) => void;
21
22
  onMessage?: (m: Record<string, unknown>, ctx: SimWorkerContext<S>) => void;
22
23
  }
23
24
  export declare function runSimWorker<S, I>(cfg: SimWorkerConfig<S, I>): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-game",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {