Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions yardline-rc/BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ with `import.meta.env.BASE_URL` (or a relative base) so a rebuild stays correct.
After ANY rebuild, verify no `` `/assets/ `` remain:
`grep -c '`/assets/' assets/index-*.js` must be 0.

**Phone-controller bridge (patched 2026-07-24):** the source builds embed a
bridge that (a) tells the console shell which phone pad to show per race phase
via `postMessage({type:"sc:controls", …})` and (b) receives the phone's
`sc:analog` driving frames + `sc:intent` button presses back. The 2026-07-23
deduped rebuild came from a source tree WITHOUT that bridge, so the phone fell
back to a d-pad and no input reached the car — the cars rendered but were
undrivable from a phone. Restored here without a rebuild:
- `index.html` carries an inline `<script>` bridge (mirrors the original:
per-phase `sc:controls`, analog → `setTouchDrive/Brake/Handbrake`, intents →
reset/powerup/pause/menu-nav).
- `assets/index-*.js` is patched to expose the two runtime instances the bridge
drives: `window.__scInput=this` in the input-controller constructor and
`window.__scRace=this` in the race-state-machine constructor.

After ANY rebuild, verify the bridge survives: `grep -c 'sc:analog' index.html`
must be ≥1, and `grep -c 'window.__scInput=this' assets/index-*.js` must be 1
(else re-apply, or — the proper fix — restore the embed bridge in
`Artan0/razing` and rebuild, then drop the inline shim).

## Pruned for the console embed
Full build ~138 MB (Downtown MegaKit + editor-only props). The console only plays
the fixed `construction-loop` preset, so editor-only assets are pruned to ~64 MB.
Expand Down
2 changes: 1 addition & 1 deletion yardline-rc/assets/index-CSoa7UUc.js

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions yardline-rc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,87 @@
<meta name="theme-color" content="#17191d" />
<meta name="description" content="Yardline RC — small cars, serious racing." />
<title>Yardline RC</title>
<!-- Space Console phone-controller bridge. The 2026-07-23 Babylon rebuild
(dedupe fix for the missing cars) dropped the in-bundle embed bridge, so
the phone showed a d-pad and no input reached the car. This restores it
against two runtime handles the bundle now exposes on window
(__scInput = input controller, __scRace = race state machine). It mirrors
the original: declares the pad layout per race phase, feeds analog frames
into the car, and routes discrete intents. See BUILD.md. Remove this once
the source repo (Artan0/razing) rebuilds with the bridge included. -->
<script>
(function () {
if (window.parent === window) return; // only inside the console shell

var DPAD = { type: "sc:controls", profile: "dpad", buttons: [{ id: "enter", label: "Select" }] };
var ANALOG = { type: "sc:controls", profile: "analog", buttons: [{ id: "powerup", label: "PWR" }, { id: "reset", label: "RESET" }, { id: "pause", label: "II" }] };
var FINISH = { type: "sc:controls", profile: "buttons", buttons: [{ id: "enter", label: "Rematch" }, { id: "menu", label: "Menu" }] };
var MENU_KEYS = { up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", enter: "Enter" };

function phase() {
var r = window.__scRace;
return (r && typeof r.phase === "string") ? r.phase : "booting";
}
function controlsFor(p) {
if (p === "racing" || p === "countdown" || p === "paused") return ANALOG;
if (p === "finished") return FINISH;
return DPAD;
}
function num(v) { var n = Number(v); return isFinite(n) ? n : 0; }
function tapKey(key) {
window.dispatchEvent(new KeyboardEvent("keydown", { key: key, bubbles: true }));
window.dispatchEvent(new KeyboardEvent("keyup", { key: key, bubbles: true }));
}

// Tell the launcher which pad to show, re-sending whenever the phase's pad
// category changes (d-pad menu <-> analog wheel <-> results buttons).
var lastControls = null;
function pushControls() {
var c = controlsFor(phase());
if (c !== lastControls) {
lastControls = c;
try { window.parent.postMessage(c, "*"); } catch (e) {}
}
}
pushControls();
setInterval(pushControls, 250);

window.addEventListener("message", function (e) {
if (e.source !== window.parent) return;
var m = e.data;
if (!m || typeof m !== "object") return;

if (m.type === "sc:analog") {
var input = window.__scInput;
if (!input) return;
input.setTouchDrive(num(m.throttle), num(m.steer));
input.setTouchBrake(num(m.brake));
input.setTouchHandbrake(!!m.handbrake);
return;
}

if (m.type === "sc:intent" && typeof m.intent === "string") {
var input2 = window.__scInput, race = window.__scRace, p = phase();
if (p === "menu" || p === "booting") {
var k = MENU_KEYS[m.intent];
if (k) tapKey(k);
return;
}
if (p === "finished") {
if (m.intent === "menu" && race && race.returnToMenu) race.returnToMenu();
else if (m.intent === "enter") tapKey("Enter");
return;
}
switch (m.intent) {
case "pause": if (race && race.togglePause) race.togglePause(); break;
case "powerup": if (input2 && input2.requestUsePowerup) input2.requestUsePowerup(); break;
case "reset": if (input2 && input2.requestReset) input2.requestReset(); break;
case "enter": if (p === "paused" && race && race.togglePause) race.togglePause(); break;
}
}
});
})();
</script>
<script type="module" crossorigin src="./assets/index-CSoa7UUc.js"></script>
<link rel="modulepreload" crossorigin href="./assets/math.scalar.functions-oml-n4mO.js">
<link rel="modulepreload" crossorigin href="./assets/observable.pure-B4ZVEGuQ.js">
Expand Down
Loading