M2 Cycle 8 — UI Scale Pass, Bible Live Filter & Neon Restyle
M2 Cycle 8 — UI Scale Pass, Bible Live Filter & Neon Restyle
Section titled “M2 Cycle 8 — UI Scale Pass, Bible Live Filter & Neon Restyle”Date: 2026-06-23
Status: Approved
Three tightly related improvements to make the game easier to read mid-play and the design bible feel like part of the same project.
- Game UI scale pass — bump HUD and weapon-panel constants so elements are readable at a glance
- Bible live filter — mark in-game content with
live: truein seed data; default the bible to show only live items - Bible neon restyle — Orbitron + JetBrains Mono, neon glow accents matching the game aesthetic
Section 1: Game UI scale pass
Section titled “Section 1: Game UI scale pass”Files modified: ui/hud.gd, ui/weapon_panel.gd
No logic changes, no new tests. All changes are constant and font-size values.
ui/hud.gd — new values
Section titled “ui/hud.gd — new values”| Element | Current | New |
|---|---|---|
| HP bar backing size | 240×40px | 340×52px |
| BAR_W (usable fill) | 234px | 334px |
| BAR_H (fill height) | 32px | 40px |
| HP label font | 15px | 18px |
| HP fill inset | position (19,16) | (21,18) — 3px inset maintained |
| Level label font | 18px Orbitron | 22px |
| Level label x-offset | 264px | 348px (right of new 340px bar) |
| Level label size | 80×40px | 100×52px |
| Timer font | 28px Orbitron | 38px |
| Timer label width | 160px | 220px |
| Timer label x | vp.x/2 - 80 |
vp.x/2 - 110 |
| Kills font | 18px | 22px |
| Kills label width | 144px | 180px |
| Kills label x | vp.x - 160 |
vp.x - 196 |
ui/weapon_panel.gd — new values
Section titled “ui/weapon_panel.gd — new values”| Element | Current | New |
|---|---|---|
| SLOT_W | 120px | 160px |
| SLOT_H | 70px | 90px |
| SLOT_GAP | 12px | 16px |
| Name label font | 13px | 16px |
| Name label size | (SLOT_W-16)×20 | (SLOT_W-16)×24 |
| Stat label font | 12px | 15px |
| Stat label y-offset | 28px | 34px |
| Stat label size | (SLOT_W-44)×18 | (SLOT_W-50)×20 |
| Arc radius | 24.0 | 32.0 |
| Arc position x | x + SLOT_W - 30 |
x + SLOT_W - 38 |
| Arc position y | y + SLOT_H/2 |
y + SLOT_H/2 (unchanged) |
| Arc line width | 3.0 | 4.0 |
Section 2: Bible live filter
Section titled “Section 2: Bible live filter”Files modified: tools/design-bible/src/seed.js, tools/design-bible/src/app.js, tools/design-bible/src/views/list.js
Live items — add live: true to these 13 entries in seed.js
Section titled “Live items — add live: true to these 13 entries in seed.js”Weapons (2): pulse, nova
Enemies (1): swarmer
Mods/upgrades (8): damage, fire-rate, move-speed, pickup, max-hp (stat mods), overcharge, catalyst, lingering (transformative mods)
Elements (2): fire, lightning
Reactions (1): fire-lightning (id: fire-lightning, the Plasma reaction)
All other entries have no live field (falsy = not yet in-game).
seed.js change pattern
Section titled “seed.js change pattern”// Before:weapon('pulse', 'Pulse', 'projectile', 'lightning', 1.0, 0.6, { tags: ['projectile','homing'] }),
// After:weapon('pulse', 'Pulse', 'projectile', 'lightning', 1.0, 0.6, { tags: ['projectile','homing'], live: true }),The weapon() / mod() / enemy() / el() / rx() helper functions all use ...extra or spread — the live field passes through automatically to the output object.
For elements (using the el() helper that doesn’t take an extra spread), add live after construction:
const elements = [ Object.assign(el('fire', 'Fire', '#ff6a4d', 'burn'), { live: true }), el('cold', 'Cold', '#6cc8ff', 'chill'), Object.assign(el('lightning', 'Lightning', '#ffe34d', 'shock', 0.15), { live: true }), // ... rest unchanged];For reactions (using rx() which also has no spread), same Object.assign pattern on the fire-lightning entry.
app.js changes
Section titled “app.js changes”- Add
liveOnly: trueto the initialuistate object:
const ui = { activeKey: 'elements', activeId: null, query: '', viewMode: 'detail', liveOnly: true };- Update
filtered()to respect the flag:
function filtered() { const entries = model.list(ui.activeKey); return ui.liveOnly ? entries.filter(e => e.live) : entries;}- Add a live-toggle button in
renderActions()(alongside existing Export/Import buttons):
const liveBtn = mk(ui.liveOnly ? '◈ Live' : '◇ All', () => { ui.liveOnly = !ui.liveOnly; render(); });liveBtn.title = ui.liveOnly ? 'Showing live items only — click to show all' : 'Showing all items — click to show live only';liveBtn.dataset.live = ui.liveOnly ? 'true' : 'false';actionsEl.prepend(liveBtn);The CSS [data-live="true"] selector will give the active state a gold glow (see Section 3).
views/list.js — live badge
Section titled “views/list.js — live badge”In the list-item rendering loop, add a ◈ badge after the name when e.live:
const label = document.createElement('span');label.textContent = (e.live ? '◈ ' : '') + (e.name ?? e.id);label.style.cursor = 'pointer';if (e.live) label.classList.add('live-label');When liveOnly is true, the ◈ badge is redundant (everything shown is live), but it’s still visible and reinforces the state. When showing all, it cleanly marks which items exist in-game.
Export behaviour
Section titled “Export behaviour”The live filter is a UI-only state. The existing “Export JSON” action writes the full model.bible (all entries) to bible.json regardless of the filter. The live fields will be present in the exported JSON — Godot’s ContentLoader.validate ignores unknown fields, so no loader changes are needed now. If needed in a future cycle, the Godot side can read live to show in-game indicators.
Section 3: Bible neon restyle
Section titled “Section 3: Bible neon restyle”Files modified: tools/design-bible/index.html, tools/design-bible/css/style.css
index.html — add Google Fonts
Section titled “index.html — add Google Fonts”In <head>, before the stylesheet link:
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">css/style.css — targeted changes
Section titled “css/style.css — targeted changes”Body font:
body { font: 14px/1.5 'JetBrains Mono', monospace; }Topbar:
#topbar { background: linear-gradient(180deg, #14141f 0%, #0a0a12 100%); border-bottom: 1px solid #1e1e38;}.brand { font-family: 'Orbitron', sans-serif; font-size: 15px; letter-spacing: 0.08em; color: var(--accent); text-shadow: 0 0 12px rgba(108,200,255,0.5);}Nav and list items — active state:
.navitem.active, .listitem.active { background: var(--panel); color: var(--accent); border-left: 2px solid var(--accent); padding-left: 6px; /* compensate so text doesn't shift */ box-shadow: inset 0 0 10px rgba(108,200,255,0.06);}Buttons:
button { font-family: 'JetBrains Mono', monospace; font-size: 12px; transition: border-color 0.15s, box-shadow 0.15s;}button:hover { border-color: var(--accent); box-shadow: 0 0 6px rgba(108,200,255,0.3);}Live toggle button active state:
button[data-live="true"] { border-color: rgba(255,227,77,0.6); color: #ffe34d; box-shadow: 0 0 8px rgba(255,227,77,0.35);}Inputs/selects:
input:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 5px rgba(108,200,255,0.25);}Live label in list:
.live-label { color: #ffe34d; }Metrics panel:
.metrics { border: 1px solid #1e1e38; }.metrics .m b { text-shadow: 0 0 6px rgba(108,200,255,0.4); }Reaction matrix hover:
.cell:hover { background: rgba(108,200,255,0.08); color: var(--accent); }No layout changes — the 3-column grid, topbar structure, and panel dimensions are unchanged.
Testing
Section titled “Testing”- Game HUD/panel: boot smoke only (
godot --headless --path . --quit-after 300) — render-only changes, no new GUT tests needed. Existing 150 tests must still pass. - Bible filter:
cd tools/design-bible && node --test— existing 31 node tests must still pass. No new tests needed (the filter is UI state in app.js, not in the pure-logic core). - Bible restyle: visual verification in browser only —
cd tools/design-bible && python3 -m http.server 8080.
Files changed
Section titled “Files changed”| File | Change type |
|---|---|
ui/hud.gd |
Constants/sizes only |
ui/weapon_panel.gd |
Constants/sizes only |
tools/design-bible/src/seed.js |
Add live: true to 13 entries |
tools/design-bible/src/app.js |
liveOnly state + filtered() + toggle button |
tools/design-bible/src/views/list.js |
◈ badge on live items |
tools/design-bible/index.html |
Google Fonts link |
tools/design-bible/css/style.css |
Neon typography + glow styles |