The Bridge Between Two Engines

The poc dependency had been on borrowed time for months. casehub-core:1.0.0-SNAPSHOT — the retired proof-of-concept — was still running every game tick, dispatching plugins via createAndSolve() and...

Trust Routing is Degenerate CBR

The question going in: is QuarkMind actually using CaseHub, or just wearing it as a label? We’d built six layers — connection, physics, the plugin pipeline, scouting, economics, and trust-weighted ...

Wiring playerResult to L6 Trust Routing

L6 trust routing shipped two weeks ago. The machinery was correct — Bayesian Beta model, four-phase maturity, designated fallback tiebreaker. The problem was that GameOutcomeRecorder always wrote A...

Pulling out ocraft's Vert.x heart

The original plan for the real SC2 connection was to use ocraft-s2client-bot — the only Java library that speaks the SC2 Remote API. It did the job for a while: ocraft handles the WebSocket handsha...

Layer 4: the ledger watches the plugins

Two things shipped today. The first was small — a null correctness fix in InMemoryCaseFile that we’ve known about since #172 surfaced the problem. The second was the Layer 4 milestone: every agent ...

Layer 5: The Gate That Works

Layer 5 is done. TacticsTask now activates only when scouting has found a threat and strategy has set a course of action. In the early game — no enemy contact — tactics never runs.

canProduce Was Never Just a Query

The last entry ended with #165 tracked but deferred — canProduce() read-only contract was doc-only. Making PlayerState public was the right call, but it left the plugin seam in an awkward position:...

Three races, one seam

The EmulatedGame has been Protoss since the day it was built. Twelve probes, a Nexus, 15 supply — all hardcoded. Adding Terran and Zerg (#138) forced a decision I’d been putting off: where does rac...

Two Extractors, One State

Issue #162 was filed yesterday during the #160 review — not a bug, just a duplication I didn’t want to leave in place. AbilityMapping.onSelection() and IEM10CommandExtractor.applySelectionDelta() b...

ZeroIndices Doesn't Mean Zero

Three issues in one branch: unit tests for IEM10CommandExtractor.applySelectionDelta (#160), a SimulatedGame.isComplete() base-contract test (#161), and Terran ability IDs in AbilityMapping (#140)....

Three Ways to Extract Nothing

The IEM10 dataset has 30 tournament replays from 2016. Until now we’d used them for tracker events only — building state, counting units, tracking births. The gameEvents array was sitting there the...

Two Wrong Build Times

The sub-tick timing fix for unit training had one known gap: buildings still used integer tick counts, no loop offset, whatever we’d written down.

Two Precision Fixes

The previous entry ended with a ±1 tick residual in the replay validation — Stalkers completing one tick early because drainBuildingQueues passes 0L to startTraining for the next queued unit, losin...

The Vespene Fix

The previous entry ended with gas units as the remaining divergence: EmulatedGame starts with 0 vespene and earns none, so every TrainIntent for a Stalker (50 gas) or Immortal (100 gas) is silently...

A Tick Too Early

The last entry ended with a claim: the ≤ 2 unit delta was the mining model. That turned out to be wrong — or at least, incomplete.

What the Smart Command Hides

Phase 6 was about feeding real player commands into EmulatedGame and watching the unit counts match the replay. The question was how to get those commands out.

The Engine Fights Back

Phase 6 requires the emulated engine to behave like real SC2 — fixing independent building queues, supply reservation timing, building type validation, and an enemy AI that generated fake building ...

Accurate, Not Just Working

A tier-4 health check before Phase 6 finds the README still naming replaced stubs and the emulated mode guide completely absent — accuracy over progress.

Clean Desk, Bigger Picture

Clearing the backlog before Phase 6 — ADRs written, PixiJS bundle removed, scouting threshold recalibrated, and documentation that had described stubs instead of real implementations finally fixed.

Both Sides of the Board

The scouting calibration was quick — ran the replay dataset, updated three string constants to match the live DRL thresholds, done. The real work was the enemy AI.

Seeing Is Believing

I asked for visual verification three times. Each time Claude reported it done. When I sent a screenshot showing blank terrain where minerals should be, the gap was obvious.

The Map Fills In

The replay was navigable but half-blind. Units moved. Buildings appeared. But the economy was invisible — no mineral patches, no geysers, no enemy Hatcheries expanding across the map. For a Protoss...

E18–E19: The Full Roster

When we added Zerg sprites and looked at the replay parser, there was a gap nobody had noticed: SCV, Drone, Overlord, Baneling, Phoenix, Oracle, Tempest, Mothership, Warp Prism, Locust, Broodling, ...

E12: Stalker Blink

E12 turned out to be exactly the session I'd predicted: thorough, mechanical in parts, with a couple of genuinely non-obvious moments.

E11: The Strategy Question

Before touching E11, we ran the post-E10 benchmark baseline. Stalker kiting, focus-fire, and cooldown tracking all in — game loop still at 0ms mean, 1ms p95. Good.

High Ground

The wall works. E7 fixed pathfinding through the chokepoint, with a physics

The Enemy Gets a Brief

E3 left us with a working combat loop: units fight, shields absorb, units die. The enemy Zealots still marched from spawn to nexus on a script — at frame 200, regardless of what the player bot was ...

Watching the Game Without Playing It

No live SC2 binary. No immediate path to get one. The bot could reason about StarCraft II and dispatch commands — but to test that against anything real, I needed SC2 running. Rather than wait, I d...

The Game Has Stakes Now

There was a budget bug I'd been carrying. The economics decision service was overcommitting resources every tick — hand it 110 minerals and watch it queue both a Pylon (costs 100) and a Probe (cost...

QuarkusMind — Making the Bot Play

Four plugins working. All four emit intents from real game state — `BuildIntent`, `TrainIntent`, `AttackIntent`, `MoveIntent`. But `SC2BotAgent.onStep()` drained the queue and logged every entry as...

StarCraft II Quarkus Agent — Day Zero

I've been building CaseHub — a Blackboard/CMMN framework for Quarkus — and it's reached the stage where I need something demanding to build against. Not a toy. Not a contrived demo. Something that ...