---
id: server-architecture/013
title: Account-first boot flow, character-seed placeholder, and client robustness
epic: server-architecture
state: done
priority: 1
blocked_by: []
estimate: L
created: 2026-08-13
updated: 2026-08-13
claimed_by: session-88fa322b
claimed_at: 2026-08-13T00:45:00.000Z
delivers: []
review_artifact: land-of-lor/docs/handoff/historic/013-account-first-flow.md
---

## What

Kris's calls in a live session on 2026-08-13, immediately after the 010 audit
([`../010-accounts-audit.md`](../010-accounts-audit.md)): restructure the client's
boot/signup/menu flow so the player **cannot enter the world without a valid
signed-in session**, fold a character-creation placeholder step into account
creation, and absorb the audit's client-robustness fixes. Full implementation plan
approved by Kris the same session — this task file is the record; the plan's design
is summarised below and the implementing session builds exactly it.

## Decision reversal — the amendment of record

**This task amends `../010-accounts-plan.md`'s approved "guest-first — play never
gates on sign-in" decision.** Kris's explicit call, 2026-08-13, with his reasoning:
most of the client-flow mess traces to the silent auto-guest, and character
selection belongs in signup anyway. The 010 plan document is approved history — do
not edit it; this file is the amendment.

What is reversed: the silent auto-guest at boot, and the ability to start the game
without a session. What **survives** from 010, unchanged:

- **No credential is required to create an account.** An explicit signup (name +
  character step) still creates an identity-less account + session — `create_guest`
  on the wire. Email, and later Play Games / Game Center / Steam (`auth_identities`
  providers, tasks 011+), attach to it afterwards. Kris confirmed this explicitly —
  platform-native sign-in must stay first-class; nothing here forecloses it.
- **Title renders offline.** Boot never blocks on the network; the gate disables
  Start, it never blanks the screen.
- **Future offline play** = a local profile that bypasses the director entirely.
  Nothing in this task may assume a session exists at title time.

## Scope (the approved plan, condensed)

1. **Session state machine** in `account_session.gd`: BOOT / RESTORING / SIGNED_IN /
   NO_ACCOUNT / OFFLINE, `state_changed` signal, no auto-guest anywhere; only an
   explicit server `UNAUTHENTICATED` clears the stored token (timeout ≠ invalid —
   kills audit H4's account loss); reconnect with backoff; real elapsed-time
   timeouts replacing the frame-counted `+= 16` loops.
2. **Flow & screens**: title gates Start on SIGNED_IN ("New Adventurer" / "I already
   have an account" otherwise); new `signup_flow` (name → character placeholder →
   create account), `signin_screen` (email login + link-code redeem), shared
   `lor_forms.gd`; `account_screen` becomes signed-in management only (device list,
   QR add-device, display-name edit, sign out — sign-in/redeem move out). Plain
   functional LorUI styling — Kris restyles in a design session afterwards; the four
   restyle surfaces are signup_flow / signin_screen / account_screen /
   character_preview.
3. **Character-creation placeholder, opaque seed end-to-end**: one nullable
   `accounts.character_seed` column, set at signup, carried through join grants →
   world entities → `world_update` → player tint; display name rides the same
   pipeline (overhead label finally shows "Rah", not entity-id hex). The
   seed→appearance mapping lives in exactly ONE file (`client/character_seed.gd`),
   loudly commented as the placeholder the future hexagram-defined appearance model
   replaces. **No character classes/models/schemas are invented** — that design
   belongs to the full-game structure behind it.
4. **Client robustness (audit absorption)**: `?link=` web QR redemption (H2), the
   reconnect story and all four silent dead-ends (H3), guest-overwrite (H4),
   frame-counted timeouts, account-screen polish debt, doomed same-port reconnect,
   Start double-tap guard, takeover tolerance (M6 client half — dormant until 014
   ships the server's `TAKEN_OVER` reason).

**Explicitly not this task**: the audit's server-hardening batch — task 014.

## Definition of done

Both suites green (director 76+ / world 75+), `verify-accounts-e2e.ts` extended
(name+seed round-trip, seed visible to a second client, link-code device shares the
seed) and passing against the deployed droplet; web + APK rebuilt and uploaded.
Manual checks that need Kris/hardware: first-run signup on the phone, QR scan from
a phone camera landing signed-in in the browser, virtual-keyboard fit. Ends with a
handoff note and `review`, per epic convention.