Browse sections

root@kaus.com:~/projects$ cat pulse-court.md

Pulse Court

active

Personal

Kbit · page guide
  1. 1 / 4

    Use the section map on long studies.

    Jump between methodology, results, experiments, limitations, and related writing without losing your place.

  2. 2 / 4

    The narrative carries the claim.

    Read each section as problem, method, evidence, and boundary. Negative results remain part of the story.

  3. 3 / 4

    Inspect figures alongside the narrative.

    Read figures in place, scroll wide charts or tables horizontally, and follow any source links for the underlying evidence.

  4. 4 / 4

    Keep exploring the corpus.

    Return to Projects or open Writing for the next thread.

A deterministic arena game where policy execution is checked against recorded inputs and replayed state, rather than inferred from a successful load.

I built a fixed-point C++20 arena simulator, native viewer, and policy execution path around reproducible matches. An integration audit found that loading a policy could still leave scripted actions in control. The repaired preview records native network decisions, and a later local ruleset migration matches the reference on synthetic contract probes. Trained-policy certification remains open.

  • 120 Hz fixed-point simulation with a separate 10 Hz policy cadence
  • 6 synthetic-policy preview games, 9,483 network decisions, all 6 replays verified (September 18, 2026)
  • 4 CTest suites passed in both Release and Debug at source commit 661f35d

Did the network actually play?

Pulse Court is a local arena game in which two players try to send a moving core into the opposing goal. It also asks a less visible engineering question: when a match is described as policy-controlled, what proves that the policy selected its actions? During the integration audit, the smoke runner could load a policy and then continue playing from a scripted action stream. A successful load and a completed match could both be true while the intended test had never happened.

The repair made execution explicit. Policy preview drives a native controller, records network decisions, and produces matches whose inputs and state hashes can be checked independently. The resulting evidence establishes that the network ran. The policy used for this check is synthetic and untrained. A later local simulator migration addresses the ruleset mismatch described below, while certification remains a separate unfinished step.

Arena background art from the repo: the top-down court the Win32 viewer renders, goal pockets left and right, core spawn at center
arena background art · pulse-court · repo asset

A match needs an authoritative clock

Replay is only useful if the same inputs mean the same game. A collision resolved in a different order, a cooldown tied to drawing frames, or an input interpreted under another ruleset can change the outcome while leaving a plausible-looking match on screen. I made simulation state, timing, resolution order, and replay versions explicit so those differences can be detected.

The game offers three original characters with different abilities, but the authoritative rules live below the viewer. Positions, velocities, cooldowns, and tuning use integer fixed-point arithmetic. The simulation advances at 120 Hz, with defined ordering for players, contacts, goals, and wall reflections. This makes the state transitions inspectable without claiming universal cross-platform equivalence from one Windows test environment.

Keep presentation outside the rules

The pulse_core library has no windowing or rendering dependency. The native viewer and headless runner consume the same simulation, while each owns the concerns of its interface. A state hash covers authoritative fields and match configuration. The replay verifier runs the recorded inputs through a fresh simulation and reports the first divergent tick, rather than merely checking the final score.

Optional events let strikes, abilities, bounces, and goals trigger animation or tracing without affecting the solver. The event buffer is excluded from state hashing. Rendering can then change without becoming another source of game rules, and headless replay checks can run without loading art or creating a graphics surface.

A policy file is only the start

The native policy layer runs an FP32 multilayer perceptron. A controller refreshes its decision every 12 simulation ticks, with extra refreshes on initialization and phase changes. That is a 10 Hz decision cadence over the faster simulation clock. Observations, legal actions, inference, and controller state remain outside pulse_core, and the controller supplies actions through the same boundary as other inputs.

The original integration gap sat after loading: the runner could discard the loaded policy and keep using scripted actions. The repaired runner selects scripted or network mode explicitly and counts fresh network decisions. Regression tests separately step a policy controller, reproduce the bot inputs and state hashes, and check that the network action stream differs from the scripted stream. That links the loaded artifact to what actually happened in the match.

Repair the game behind the policy

The September preview ran ruleset v2, while the strict policy contract required v4. Its compatibility shim lost touch-kind information. A network could execute successfully and still receive observations that did not match the reference game. Preview made that integration path inspectable, but could not make the rules equivalent.

The September 20 audit made the mismatch concrete. Both encoders return 64 numbers, but an identical core velocity becomes a different network input because the speed caps differ. A strike also changes the core’s motion differently. Body contact can produce matching motion while v2 loses who touched the core. Matching vector length and action mappings therefore cannot establish that a policy is playing the same game.

The subsequent local migration ports the v4 simulation and observation semantics together, removes the lossy shim, and preserves touch ownership and the touch recorded before a goal reset. All 34 synthetic fixtures, covering 78 snapshots, now match the identified v4 reference in observations, actions, masks, touch state and same-ruleset hashes. Native adapter tests also exercise generated, untrained policies. These checks close the measured compatibility gap without certifying a trained model.

Replay history needs its own boundary. A separate verifier retains the exact v2 core and still verifies the unchanged 5,720-tick preview replay. The active v4 loader keeps the hardened admission checks and rejects foreign-ruleset files. Neither rewriting an old replay header nor obtaining a v4 match would establish certification, so strict deployment stays disabled until accepted certification and policy-artifact identity are checked.

Matching actions, different simulator behavior

All 648 decoded action mappings matched across both seats, including horizontal mirroring. The same native probe still found differences in encoded inputs, strike motion and touch ownership. These are synthetic fixtures, not policy runs.

September 20, 2026. Native v2 3a3fe53 / reference v4 9a5dfef. Velocity uses raw fixed-point units; observation values are unitless.
Fixture and scopev2v4
Same velocity, different inputBefore stepping: core velocity (160, -80) in fixed-point units; seat 0 observation slots 2/3 are unitless.Different normalization caps change the input despite equal observation width.(0.421052635, -0.210526317)(0.5, -0.25)
Ordinary strikeOne tick from zero core velocity; resulting vx in fixed-point velocity units.Strike motion and recorded touch type differ.vx 209; seat 0; PlayerBody shimvx 179; seat 0; Strike
Player-body contactOne tick from core vx -200; resulting vx in fixed-point velocity units.Equal resulting motion does not preserve who touched the core.vx 174; seat -1; Nonevx 174; seat 0; PlayerBody

Seat -1 means no recorded owner. v2 touch kinds come from a compatibility shim. This earlier audit measured the mismatch without migrating the core or executing the policy adapter. The later integration check is separate.

Keep the simulator identity through teardown

The September 21 repair follows simulator identity through the evaluator's lifetime. A DLL pathname alone leaves two questions open: which library did the wrapper actually use, and did that ownership last until native state was destroyed? The wrapper now uses the same loaded library whose receipt, source and configuration were checked, and retains a Windows handle that blocks file replacement. Both evaluator paths expose completed identity only after teardown. The report producer rejects missing or mismatched evidence.

Failure changes what the report may say. If native destruction raises an error, the wrapper cannot assume that the native state is gone. It retains the library and its protection until process exit, without retrying destruction or producing completed identity. The software tests exercise this failure path with a fake native dependency.

The evidence covers 62 software test methods and a separate native probe that called five identity and ABI getters. That probe never created an environment or ran a policy. The new checks concern the library used for a future evaluation. They do not identify the DLL that trained a historical checkpoint, and strict deployment remains disabled.

Implemented contract · source 8e4c1ef · September 21, 2026
  1. Pin the inputs

    Require an explicit build receipt, independently supplied receipt hash, DLL, source and configuration.

  2. Keep the same library

    The environment uses the protected loaded library. A Windows file handle prevents writing or replacing its file during that lifetime.

  3. Complete teardown

    Destroy native state, check identity again, then release protection. Uncertain destruction retains ownership and produces no completed identity.

  4. Require completed evidence

    The evaluator reads identity after close. The report producer rejects missing or mismatched evidence before writing its result.

The execution check and its control

Six preview games with the synthetic, untrained policy exercised both bot seats and recorded 9,483 native network decisions. All six replays passed verification. Six explicitly scripted control games recorded zero network decisions. This comparison checks controller selection, not the relative playing strength of two agents.

The included replay is the smallest of the set, a 5,720-tick match that the synthetic policy lost. Its recorded inputs reproduce the saved hashes. Choosing it for portability rather than as a representative performance sample is part of the artifact description. The result closes the execution gap without claiming a trained champion, a human challenge, or competitive ability.

The same September checkpoint passed all four automated suites in both Release and Debug. The suites cover simulation and replay contracts, policy behavior, logging, and challenge paths. Launcher argument checks also passed for spaced and relative Windows paths. These are distinct checks on the path into a run and the evidence coming out of it, with no new inference-latency claim.

Synthetic policy execution, with replay evidence

This untrained development policy exercises native inference and replay integrity. It is not certified, and these diagnostics do not establish learned strength, human performance or inference latency.

Recorded September 18, 2026, ruleset 2, source 661f35d. Preview and scripted modes are explicit.
CheckRecorded result
Release regression suites4 passed
Debug regression suites4 passed
Synthetic preview replays verified6 / 6
Native network decisions in preview9,483
Scripted control6 games, 0 network decisions
Missing strict policy inputsRejected
Evidence created after strict failureNone

The included native replay has 5,720 ticks and 478 network decisions. It was selected for its small file size, and the synthetic policy lost. Strict trained-policy play, certification and graphical acceptance remain outside this checkpoint.

September 20, 2026: local replay admission repair

Source 596d1f5 checks the exact replay size before allocating tick storage, rejects trailing bytes and preserves the destination on failure. The owning project passed 4/4 suites in each of Release and Debug plus 14 native checks. A separate verification passed 4/4 Release suites and seven native cases.

The repair is locally committed and unpushed. These structural checks establish no physics validation, ruleset-v4 certification, graphical acceptance or learned strength. The historical preview above is unchanged.

A viewer built for inspection

The viewer exposes pause, single-step simulation, hitbox and animation overlays, an action trace, and separate simulation-speed and render-cap controls. Its fixed simulation accumulator ties animation events to simulation ticks. Focus loss clears held input and pauses play. Those controls are intended to make a questionable action inspectable at the point it happened.

Art goes through a manifest-driven pipeline: poses are cleaned into a consistent grid, sheets are baked near their draw sizes, and the runtime supplies procedural fallback when an asset is missing. The images here are repository art. They show the assets used by the viewer, rather than proving that the latest native runtime passed visual acceptance.

Gallery and character setup use Direct2D, while gameplay still uses GDI/GDI+. Keeping the old gameplay renderer during the migration provides a reference for the remaining conversion. Resize behavior, visual parity, alpha edges, and device-loss recovery need their own checks. An isolated rendering spike therefore does not become a gameplay frame-rate claim.

One of the 32 manifest-driven sprite sheets: Bastion's 4x4 idle cycle, cleaned by scripts/clean_sprites.py, rendered with a procedural fallback if a sheet is missing
bastion idle sheet · pulse-court · 1 of 32 sprite sheets

What replay settles, and what it leaves open

The headless results answer a concrete chain of questions: a controller made network decisions, those decisions produced recorded inputs, and replaying those inputs reproduced the saved state. They do not establish that a human played a challenge or that the viewer handles every input and rendering condition. Headless smoke sessions and viewer challenge sessions still have separate implementations, so their protocols cannot be treated as interchangeable.

The current game is a local 1v1 prototype. Larger teams would change state layout, input frames, collision handling, observations, and tests together. Networking, gamepad support, and audio remain deferred. A new GUI and device-loss acceptance pass was not part of the September evidence, and the requested self-play and earlier-champion replay browser remains unimplemented.

The next boundary is certification

The local v4 integration now supplies a simulator, observation adapter and replay contract that agree on the exercised fixtures. The next policy step is to bind an accepted trained artifact to its certification and golden-reference evidence, then check it in the actual deployment path. No trained policy was loaded for the migration checks, and the local branch is not merged or deployed. A candidate checkpoint or a successful file parse is still insufficient.

Rendering has its own path: convert gameplay, check visual and device-loss behavior, and then retire the legacy renderer. Keeping these follow-ups separate preserves the value of the current result. Policy execution is now observable through the match evidence, and the project can state exactly which part of deployment remains unproved.

notes

  • The local v4 migration passes synthetic simulator and native-adapter checks, but is not merged or deployed. Strict deployment remains disabled pending accepted certification and artifact-identity checks.
  • Synthetic development policies exercise loading, inference, and replay plumbing. They are untrained and provide no evidence of competitive strength or certification.
  • Release and Debug builds, automated suites, native policy execution, and replay verification passed at the September 18 checkpoint. Fresh GUI/input, rendering, and device-loss acceptance remain unverified.
  • Local Windows prototype only. Networking and team sizes beyond 1v1 remain deferred, and gameplay rendering has not migrated to Direct2D.
← All projects