Log

the house got rooms, and rooms got neighbors

Gamahaus crossed a threshold this week. The 3D canvas learned to hold multiple floors at once — you can now stack them, see through to what’s below, and flip between them without losing your place. Stairs fill the voids. Roofs pitch and flip on demand. The camera got smarter too: double-click anything and it locks onto it; F-key toggles first-person mode and you’re walking through your own design, feet on the floor, presence locked to the room you’re standing in.

the scroll gets a third act

The journey inside finally has a payoff. The hero copy now bows out as the camera flies through the door, leaving the screen clean for the ride — and once you’re standing in the room, new copy fades in: you’re standing inside the prototype. That’s where the honest part lives too: gamahaus is in private alpha, and right now its only users are my wife and me. A little pulsing status chip says exactly that — private alpha · 2 users — and it’ll tick up as the doors open. Build in public means the status is part of the page.

step inside the cube

The hero leveled up. Scrolling now flies the camera through the doorway and into a furnished room — the breathing cube unfolds into floor, window, door, and bed as you go in, then folds shut on the way back out.

On top of that, a polish pass: a faint film grain across the frame, neon edges that pulse like a slow heartbeat, an idle drift that wanders instead of spinning like clockwork, and the cube now resting tilted from above. The resolution scaler also learned to recover — a momentary GPU dip no longer leaves it permanently soft.

the wireframe cube, live in 3D

The brand’s wireframe cube is now a live WebGL hero on the landing page itself — neon edges, bloom, follows your cursor. Built end-to-end with Claude.

double-click to focus the camera — plus phases 1–3 re-audited

The QA bug from the last entry is still unresolved. Set it aside and went elsewhere.

Camera focus:

Double-click anywhere in the 3D view and the camera animates onto that point — 200ms easeOutCubic, dollies to min(current distance, 5m). Raycasts against the scene; misses are silent. F still re-fits to the full plan. Closes the most-common navigation gap now that wall-drawing got cheap.

Eight-agent audit across phases 1–3:

  • Branch IDOR + TOCTOU. Anyone could like/comment any draft via UUID guess. Branching trusted a pre-tx license read — source owner could flip license between gate and INSERT. Both closed with WHERE status='published' predicates inside the tx.
  • Avatar URL traversal. HasPrefix accepted cdn/avatars/me/../them/foo.png. Now url-parses, rejects .., matches scheme + host.
  • Sitemap race. Publish mid-fill clobbered the invalidate signal. Added an invalidatedAt snapshot; stale fills skip the cache write.
  • Rate limits. Avatar PUT was unbounded; notification + templates GETs too. New heavy-read limiter (300/min/user); avatar mutations on the write budget.

~70 findings triaged across two commits. 494 frontend tests + every Go package green at -count=2.

the 3D toggle was a layout leak — plus editor polish

Picking up from the last entry. The 3D toggle showing pure black turned out to be a layout leak, not a rendering issue.

Diagnosis:

Fabric.js wraps its host canvas in a .canvas-container div. v-show on the inner canvas hid the canvas but left the wrapper’s layout space intact, pushing the 3D canvas 904px below the viewport. Fix: wrap both canvases in a single v-show div so display:none collapses the entire 2D subtree, Fabric wrapper included.

phase 2 + 3 wrapped — then qa caught a bug i couldn't fix

Long stretch since the last entry. Heads down through Phase 2 and Phase 3.

Phase 2 shipped 3D extrusion of the 2D plan, the furniture catalog, material picker, the social loop (like / comment / follow), SSR for public surfaces, and twelve sub-tasks of editor polish.

Phase 3 added the procedural stick-man avatar customizer (avatars show up in owners’ 3D scenes), the branch system (fork a published project, attribution chain preserved, license-gated), the template browser, and thirteen official starter templates.

claude vs codex: the editor

Last entry covered Codex’s pass on the editor — including a tagline that drifted from the one explicitly defined in the project bible. This one is Claude’s pass on the same surface, plus the call I made about which to keep going with.

Same instruction to both: build whatever you can right now, skip the pieces that depend on me (email notification setup, R2 storage, etc).

Where Codex won:

Codex went straight at the 2D canvas and shipped things I never asked for but immediately wanted:

workflow scaffolding: roadmap, progress, amendments

Login and dashboard shipped. Project CRUD shipped. The 2D editor is next, and it’s the biggest piece in Phase 1 by a wide margin. Felt the right moment to add scaffolding before pouring more code into it.

Three new docs and one new command:

  • ROADMAP.md — task-level breakdown the bible doesn’t have. Phase 1 detailed, later phases sketched.
  • PROGRESS.md — where we left off, what’s blocked, “resume here” pointer for the next session.
  • AMENDMENTS.md — anywhere the code intentionally disagrees with the bible. Stops the bible from quietly becoming a lying source of truth.
  • /checkpoint — slash command that updates PROGRESS.md. Either standalone, or chained as /implement {task} /checkpoint to log work as it lands.

The point: make the next session’s first 60 seconds about resuming instead of re-deriving state.

codex builds the editor: walls, doors, windows

First slice of the actual editor — the 2D surface where rooms get drawn. Built with Codex (GPT-5.5) only. Claude’s run on the same surface comes later.

This time I changed the prompting style. Instead of “build login page” or “build dashboard” as one-shot briefs, I gave Codex full autonomy: pick the sequence, pick the depth, ship in increments. It would build something small, ask me to verify, then move to the next slice. The trade-off was visible immediately — same component, multiple round-trips.

claude vs codex: dashboard

Same brief, next surface. After logging in with a registered email, here’s what each AI built as the workspace landing.

Claude (Opus 4.7):

Claude’s dashboard

Top nav (cube + “GamaHaus” left, “Dashboard / Projects / avatar / Log out” right), then a centered single column. Greeting is personal — “Hi, Martin 👋” with “Here’s your playground.” picking up the design-doc tagline word-for-word. One project card with a “draft” pill, “1 project” count, and outlined “View all” + magenta “New project” CTAs aligned right. Lots of whitespace flanking the column. Creation lives behind a click.

claude vs codex: login

Started building the actual app. Decided to run two AIs in parallel on the same brief — Claude (Opus 4.7, 1M context, max effort) in one project directory, ChatGPT (Codex 5.5) in another. Same project bible, same design language doc as input. Port offsets — Claude on +30, Codex on +40 — so both can run at once. Claude got the custom-agents-and-commands setup I’m used to (8 agents). For Codex I asked it to mimic that workflow as best it could.

the wireframe cube

Two things landed: the GamaHaus logo and a 14-section design language doc.

The logo is a wireframe isometric cube — three colored faces, magenta-front (#F507B4), cyan-right (#18D0E9), purple-top (#CB6CE6). Stroke-only, no fills. Three variants: tri-color default, mono-magenta for tight contexts, white for dark backgrounds. Reads as “3D space” without literally drawing a house — GamaHaus is the playground, not the blueprint.

The design language pins everything else: color tokens, magenta scale 50→900, Sora display + Inter body, pillowy radii, soft shadows, Phosphor icons, springy motion. Shadcn-Vue components on top of Tailwind, restyled day-one to match. Two surfaces at MVP — App (light) and Editor (always-dark, independent of theme).

the 556 GB ghost in my SSD

Not a GamaHaus update — but this is the machine I’m building it on, so it counts. Logs aren’t always green checkmarks; sometimes they’re “spent a day digging out of my own past mistakes.”

Sat down to work at 6 AM and the laptop refused to boot to desktop. Disk at 100%, zero bytes free of 717 GB. GDM, MySQL, VirtualBox — all dead. Linux can’t start services without scratch space.

GamaHaus project bible

Spent a long session with Claude yesterday crystallizing the GamaHaus project bible — the design doc for the actual app this landing page exists to track.

26 sections, ~1500 lines. Tech stack (Vue 3 + Go/Fiber + PostgreSQL/Redis), modular monolith architecture, full database schema, auth, real-time, editor UX, avatar system, the GamaCoin virtual economy, license tiers, branch/template system, 5-phase dev roadmap.

Worth saying: Claude was the thinking partner here, not the typist. The bible came out of long back-and-forth conversations where we argued tradeoffs, killed weak ideas, and stress-tested decisions before they landed in the doc. AI does coding too — but using it as a brainstorming sparring partner is the part most people sleep on.

landing page deployed

gamahaus.com is live. Hugo for the site, Cloudflare Pages for the host, GitHub for the source. Every push to main auto-deploys within a minute or two.

The log you’re reading is the whole thing. No hero section, no roadmap, no “coming soon.” Just entries, one per thing.

gamahaus.com secured

Registered the domain today. Starting a log here — one entry per thing made, thought, or broken. No plan, no roadmap. Just notes.