docs: project CLAUDE.md for native-Windows Claude Code handoff
CI / quality (push) Failing after 46s
CI / quality (push) Failing after 46s
Pure ASCII (PS 5.1 reads non-ASCII as ANSI and desyncs the parser).
Records the aux-lane suppression invariant, the verified 6e50f97 baseline,
the read/write channel split, and the probe scripts that check each metric.
This commit is contained in:
@@ -0,0 +1,139 @@
|
|||||||
|
# CLAUDE.md -- Tokyo Wangan Racing
|
||||||
|
|
||||||
|
Guidance for Claude Code running **natively on `windows-gpu`**, the same machine
|
||||||
|
as Roblox Studio. Pure ASCII on purpose (PowerShell 5.1 reads non-ASCII as ANSI
|
||||||
|
and desyncs the parser).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Read this before touching MapBuilder
|
||||||
|
|
||||||
|
`src/server/MapBuilder.luau` generates the map procedurally. The user also edits
|
||||||
|
geometry **by hand in Studio**. Those two facts collide, and that collision is
|
||||||
|
the single most important thing about this repo:
|
||||||
|
|
||||||
|
> **A rebuild regenerates anything the source still describes.**
|
||||||
|
> If the user deleted geometry by hand and you rebuild without teaching the
|
||||||
|
> source about that deletion, you silently put it back.
|
||||||
|
|
||||||
|
The user WILL notice, immediately, and will say so ("you just added back the X
|
||||||
|
that I deleted"). When that happens: **stop editing, run a read-only probe,
|
||||||
|
report exact numbers.** Do not "fix" it with another rebuild.
|
||||||
|
|
||||||
|
### The live invariant: aux-lane suppression
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local AUX_SUPPRESS_FROM = 525 -- samples 525..550 have NO aux lane
|
||||||
|
local AUX_SUPPRESS_TO = 550 -- because the user deleted that run by hand
|
||||||
|
local AUX_BLEND = 5 -- smoothstep width ramp, do not hard-cut
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Do not remove or widen this range.** Re-enabling it resurrects deleted geometry.
|
||||||
|
- `AUX_BLEND = 5` is not cosmetic. A hard cut produced a **26-stud lateral fence
|
||||||
|
jog**. The smoothstep removes it.
|
||||||
|
- The parapet is force-closed across the same range (~line 1031). Normally the
|
||||||
|
parapet OPENS along a speed-change lane because the aux lane re-fences the
|
||||||
|
outer edge -- with no aux lane there is nothing to re-fence with, leaving the
|
||||||
|
deck edge bare. That was the measured barrier gap at samples 527..548.
|
||||||
|
|
||||||
|
Any change touching aux lanes, parapets, or barriers must re-run
|
||||||
|
`tools/probe_regression.luau` and match the baseline below.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Verified baseline (commit 6e50f97)
|
||||||
|
|
||||||
|
Measured in the live datamodel, not inferred from source:
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|---|---|
|
||||||
|
| total parts | 16788 |
|
||||||
|
| PAWestSlip | 60 segs, 34.4 deg total bend, worst 1.4, 0 kinks >5 |
|
||||||
|
| PAEastSlip | 60 segs, 30.7 deg total bend, worst 1.3, 0 kinks >5 |
|
||||||
|
| AuxLane parts | 30 (samples 525-550 deliberately absent) |
|
||||||
|
| barrier coverage | 823 samples, 0 unguarded |
|
||||||
|
| fence jogs >10 studs | 0 |
|
||||||
|
|
||||||
|
`AuxLane = 30` is the **user's hand-edited count**, not the source's original 52.
|
||||||
|
If a probe reports 52, a rebuild has undone the suppression -- that is a
|
||||||
|
regression, not progress.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Two channels, different jobs
|
||||||
|
|
||||||
|
```
|
||||||
|
[A] MCP bridge (roblox_studio) -> READ run Luau in Studio, measure, screenshot
|
||||||
|
[B] Rojo -> WRITE push .luau source into Studio (~1 s)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Use [A] to verify what [B] did. Never assume a sync landed.**
|
||||||
|
|
||||||
|
Rojo syncs **scripts, not built geometry**. Editing MapBuilder replaces the
|
||||||
|
ModuleScript instantly, but `workspace.Map` still holds parts from a PREVIOUS
|
||||||
|
`build()` run. The map looks stale until you re-run the build. Do not tell the
|
||||||
|
user "you'll see it live" about map geometry.
|
||||||
|
|
||||||
|
**Rojo version must match the Studio plugin.** The plugin auto-updates from the
|
||||||
|
Marketplace without asking. Server older than plugin fails the handshake with a
|
||||||
|
cryptic `attempt to index number with 'protocolVersion'`. Both are pinned at
|
||||||
|
**7.7.0** (`rokit.toml`). If the user reports a connect error, check this first.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Workflow
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make check # stylua --check + selene + rojo build
|
||||||
|
make build # rojo build --output build.rbxl
|
||||||
|
make serve # rojo serve (Studio: Rojo -> Connect)
|
||||||
|
make fmt # stylua src/
|
||||||
|
```
|
||||||
|
|
||||||
|
Probe scripts in `tools/` are **read-only** -- they measure the live datamodel
|
||||||
|
and never build. Run them through the MCP bridge.
|
||||||
|
|
||||||
|
| Script | Answers |
|
||||||
|
|---|---|
|
||||||
|
| `probe_regression.luau` | full baseline check vs the table above |
|
||||||
|
| `verify_auxlane.luau` | is the 525-550 suppression intact? |
|
||||||
|
| `verify_slips.luau` | slip-road bend angles / kink count |
|
||||||
|
| `probe_barriergap.luau` | any unguarded deck edge? |
|
||||||
|
| `probe_jog.luau` | lateral fence jogs |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Hard-won rules
|
||||||
|
|
||||||
|
- **Measure, then fix.** Do not infer a bug from symptoms. One inverted
|
||||||
|
convention can produce three unrelated-looking symptoms; fixing each symptom
|
||||||
|
leaves the root cause intact.
|
||||||
|
- **A metric derived from a constant cannot fail.** Ask: would this number
|
||||||
|
differ between the broken and fixed build? If not, it is not a test.
|
||||||
|
- **An empty result set must FAIL, never pass.** Count what you actually
|
||||||
|
exercised; `if tested == 0 then return "NOTHING TESTED -- FAILURE" end`.
|
||||||
|
- **Verification in Play mode proves nothing.** Play is a disposable sandbox
|
||||||
|
discarded on stop. Verify in Edit mode.
|
||||||
|
- **require() caches stale bytecode after a Rojo edit.** The cache still holds
|
||||||
|
old bytecode even though `.Source` is new -- no error, no warning. Clone the
|
||||||
|
module and require the clone.
|
||||||
|
- **Enumerate part names, don't just count.** A raw total hides partial removals
|
||||||
|
(deleted the tall barrier, missed the kerb). Tally what should be gone vs
|
||||||
|
what should remain, and report both.
|
||||||
|
- **AutoRecovery places are silently stale.** After a crash Studio reopens
|
||||||
|
`*_AutoRecovery_1.rbxl` holding pre-crash state. Check the title bar.
|
||||||
|
- **Creator Store assets: 50+ scripts or 1M+ tris is zero-tolerance.** Get exact
|
||||||
|
counts before inserting anything.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Shell
|
||||||
|
|
||||||
|
Git Bash (`C:\Program Files\Git\bin\bash.exe`) is present -- prefer it.
|
||||||
|
PowerShell over a non-interactive pipe mangles quoting. `&` is not a statement
|
||||||
|
separator in PowerShell. When PowerShell is unavoidable non-interactively, use
|
||||||
|
`-EncodedCommand` with UTF-16LE base64.
|
||||||
|
|
||||||
|
`StudioMCP.exe` lives inside the versioned Studio install and **moves on every
|
||||||
|
update**. Never hardcode it; `~/claude-tools/studio-mcp.bat` resolves it
|
||||||
|
dynamically.
|
||||||
Reference in New Issue
Block a user