/* ============================================================================ EXPORT & BOOTSTRAP `SERPENT` exposes internals for the console (runSelfTests), dev tooling and the headless test harness. Auto-boot only happens in a real browser. ========================================================================== */ const SERPENT = { CONFIG, PALETTES, ST, S, Store, U, Draft, CARDS, Input, Sfx, Grid, Physics, Pool, Snake, Weapons, Enemies, Pickups, Waves, FX, Cam, Background, Renderer, HUD, UI, Menu, Game, Dbg, Bot, DemoBrain, ACH_DEFS, utils: { TAU, clamp, lerp, angleDiff, wrapAngle, len, dist, dist2, norm, approach, makeRng, rng: () => rng }, runSelfTests, }; if (typeof window !== "undefined") window.SERPENT = SERPENT; if (typeof globalThis !== "undefined") globalThis.SERPENT = SERPENT; /* Browser entry point. The harness calls Game.init() manually instead. */ (function autoBoot() { if (typeof window === "undefined" || typeof document === "undefined") return; /* Any failure must be readable on the page itself, not just in DevTools. */ function showFatal(msg) { if (typeof console !== "undefined") console.error(msg); try { let el = document.getElementById("s360err"); if (!el) { el = document.createElement("div"); el.id = "s360err"; el.style.cssText = "position:fixed;left:12px;top:12px;z-index:99;max-width:80ch;" + "font:12px/1.5 monospace;color:#ff8d9a;background:rgba(12,0,4,.94);" + "border:1px solid #ff2e4d;padding:10px 12px;white-space:pre-wrap;"; (document.body || document.documentElement).appendChild(el); } el.textContent = msg; } catch (_) { /* truly nothing left to do */ } } window.addEventListener("error", function (e) { showFatal("WINDOW ERROR\n" + (e && e.message ? e.message : String(e)) + "\n" + ((e && e.filename) || "") + ":" + ((e && e.lineno) | 0)); }); window.addEventListener("unhandledrejection", function (e) { showFatal("PROMISE REJECTION\n" + (e && e.reason ? e.reason : String(e))); }); if (typeof requestAnimationFrame !== "function") { // headless harness path return; } const cv = document.getElementById("game"); const bootEl = document.getElementById("boot"); if (!cv) { showFatal("#game canvas missing from the document"); return; } try { if (bootEl) bootEl.textContent = "BOOTING…"; Game.init(cv); if (bootEl) bootEl.textContent = ""; // first user gesture unlocks audio (autoplay policy) const unlock = () => Sfx.unlock(); window.addEventListener("pointerdown", unlock); window.addEventListener("keydown", unlock); } catch (err) { showFatal("SERPENT 360 failed to boot:\n" + ((err && err.stack) || String(err))); } })(); /*JS-END*/