← The game interface — first brush · all tasks
Android build is missing the whole interface — shell is DOM-only, APK ships the bare 3D world
game-interface/004 · created 2026-08-11 · updated 2026-08-12
What
Kris played the live /play page (works — title screen, HUD, Ingredients panel all
present) and then installed the APK on his phone: the 3D world runs, but none of the
interface layer is there — no title screen, no HUD buttons, no Ingredients/Spells/Gear
panel, not even the help bar. He suspected the UI had only ever been built as an HTML
overlay rather than into the Godot project itself. That’s exactly right, confirmed by
reading the actual architecture:
game/README.mdandgame/shell/README.mdboth say plainly: the shell is “the DOM layer… floated over the untouched Godot web export.” It boots./engine/index.jsand draws HTML/CSS on top of the<canvas>from the page, not from anything inside the.godotproject.game/export-android.shexports$HERE/worldonly — the raw Godot project (game/world/,run/main_scene = client_main.tscn). There is no Control-node UI anywhere inworld/; grepped for it, nothing exists.- So the APK is, correctly, exactly the Godot project on its own: touch-to-move in the
3D world, and nothing else. This was never a bug in the export script — the shell
genuinely has no path into a native Android build. It’s a real, undocumented gap:
game/README.md’s “Known limits (deliberate, v0.0)” section lists several intentional v0.0 shortcuts (static health bar, hardcoded owned-set, Spells/Gear placeholders) but never says “Android has no interface at all” — this wasn’t a decision anyone signed off on, it fell out of the shell being built web-first and nobody checked the APK against deliverable 9’s acceptance criteria before shipping it.
Deliverable 9’s own acceptance criteria (“title screen… HUD… Ingredients tab”) make no browser/mobile distinction — the APK not meeting them is a real gap against what was promised, not a scope question.
The fork this needs
Two genuinely different ways to close this gap:
- Wrap the existing web build in a WebView shell for Android, instead of exporting the raw Godot project. Reuses the shell, the Claude Design pass, and the card renderer/editor contract completely untouched — zero redesign. Downsides: WASM inside a mobile WebView is materially slower than Godot’s native Android renderer; touch input, fullscreen/back-button behaviour, and Android WebView quirks (version fragmentation) all need real verification, not assumption; app size grows (bundling the web build into the APK).
- Build the interface natively in Godot (Control nodes: title screen, HUD, tabbed
stuff panel, card grid/modal) so one implementation ships identically on web and
Android. Better native performance and input handling, no WebView involved at all.
Downsides: the whole Claude Design handoff (
docs/design/HANDOFF.md, the two.dc.htmlreferences) is HTML/CSS — none of it transfers directly to Godot’s UI system, so the visual pass has to be rebuilt by hand in-engine and now has two places that can drift (DOM shell for web, Control-node UI for Android) unless the web shell is later retired in favour of the same native UI running inside the Web export too.
RESOLVED by Kris (2026-08-12, planning session): option 2 — native Godot UI — is the direction, explicitly confirmed (“we want this correctly implemented in Godot — and well architected too”). The WebView wrap is rejected. The DOM shell’s UI layers get retired to a thin tap-to-play loader (Kris chose the gate over auto-loading the ~40MB engine on page open); the Godot Control-node scenes become the visual source of truth for the interface. The original assumption text follows for provenance:
Assumption (flagging, not blocking): defaulting to option 2 — native Godot UI — as
the direction to prototype first, because “one implementation, both platforms” matches
this project’s existing bias (world/’s whole reason for being one shared project is
“movement code can never diverge between client and server by reimplementation drift” —
the same argument applies to the interface). But this is a real architectural fork with
a real cost (redoing the Claude Design visual pass by hand), not a mechanical fix, so
whoever picks this up should read both options above before starting rather than take
the assumption on faith — and Kris should get a chance to weigh in during review, since
it resets which surface (shell/ DOM vs. Godot Control nodes) is the visual source of
truth going forward.
Done
Both platforms show the same interface: title screen, HUD (health bar + Ingredients /
Spells / Gear), tabbed stuff panel with the Ingredients grid and card modal, working
identically on the live /play page and on a fresh install of the APK on an Android
phone. Update game/README.md’s “Known limits” section either way — this stops being an
undocumented gap once someone’s made the call.
Review
Kris installs the rebuilt APK on his phone and confirms the interface is there and usable one-handed in landscape, same as the browser version.
Built (2026-08-12)
The interface was rebuilt as native Godot Control-node scenes in
land-of-lor/game/world/client/ui/ — title screen, HUD (press-hold labels, tap-to-move
passthrough), stuff panel with the always-8-across grid, and the element card with all
three rarity frames (legendary = animated foil shader) and the un-collected template.
Architecture notes in land-of-lor/game/README.md: app.tscn root flow;
player_state.gd is the deliberate MMOG seam (demo owned-set, placeholder health,
signals) that server-backed accounts later replace; element_db.gd reads
data/elements.json, synced from the canonical shell/elements.js by
sync-elements.sh inside both export scripts. client_main.gd, the six shared .gd
files, and the protocol are byte-identical; 64/64 pure-logic tests pass. The web shell
is now a thin tap-to-play loader (Kris chose the gate over auto-download); the card
editor + its HTML renderer stay as authoring tools (documented drift tradeoff: editor
preview vs Godot render — data cannot drift). Verified end-to-end in a CDP-driven
browser: loader → engine boot → native title → Start → live-droplet world with HUD,
1600+ remote entity updates streaming. New APK (27.7 MB, package
au.com.cocreations.lor.game v0.0.1, lor2026-signed) uploaded to the droplet.
Pre-existing quirk noticed while verifying (NOT introduced here, present in the old poc web build too when connected): the client logs occasional “Parse JSON failed” console errors during live traffic — protocol-side, frozen code, harmless to gameplay; worth a look whenever the protocol next opens for changes.
View source in repository · also available as raw markdown.