- Add assets package with dev/prod build tags
- Dev: serve from filesystem with Cache-Control: no-store
- Prod: use hashfs for cache-busting URLs
- Add LiveClock component to show SSE connection status
- Update templates to use StaticPath for asset URLs
- Reorder HandleGameEvents to create NATS subscriptions before SSE
- Use chi's middleware.NewWrapResponseWriter for proper http.Flusher support
- Add slog-zerolog adapter for unified logging
- Add ErrorLog to HTTP server for better error visibility
- Change session Cookie.Secure to false for HTTP support
- Change heartbeat from 15s to 10s
- Remove ConnectionIndicator patching (was causing PatchElementsNoTargetsFound)
The key fix was using chi's response writer wrapper which properly
implements http.Flusher, allowing SSE data to be flushed immediately
instead of being buffered.
Migrate from the via meta-framework to direct dependencies:
- chi for routing, templ for HTML templates, datastar for SSE/reactivity
- Feature-sliced architecture (features/{auth,lobby,c4game,snakegame}/)
- Shared layouts and components (features/common/)
- Handler factory pattern (HandleX(deps) http.HandlerFunc)
- Embedded NATS server (nats/), SCS sessions (sessions/), chi router wiring (router/)
- Move ChatMessage domain type from ui package to game package
- Remove old ui/ package (gomponents-based via/h views)
- Remove via dependency from go.mod entirely
Add config package with build-tag-switched dev/prod environments,
structured logging via zerolog, Taskfile for dev workflow, golangci-lint
config, testutil package, and improved DB setup with proper SQLite
pragmas and cleanup. Rename sqlc output package from gen to repository.
Switch to allowlist .gitignore, Alpine+UPX+scratch Dockerfile, and
CI pipeline with test/lint gates before deploy.
Upgrade via to v0.18.1 and configure context suspension timeouts
(5min suspend, 30min TTL) for clean reconnection behavior. Throttle
snake direction key inputs to 100ms to prevent wasted SSE round-trips
when keys are held down.
Use via.OnKeyDownMap for snake keybindings, replacing the manual
dataExpr/rawDataAttr workaround. Window-scoped key handling removes
the need for tabindex/focus hacks, and WithPreventDefault on arrow
keys prevents page scrolling during gameplay.
Introduce a 60 FPS tick loop with a separate snake movement speed
(7 cells/s) so direction input is polled every frame but game state
only advances at the configured rate.
Use via's embedded NATS server to notify players of state changes
instead of a 100ms polling ticker. Each player subscribes to
"game.<id>" on page load; via auto-cleans subscriptions on disconnect,
eliminating the need for manual player tracking and RegisterSync.
Use gotailwind (standalone Tailwind v4 via Go tool) with DaisyUI
plugin files — no npm needed. CSS is compiled at build time and
embedded via a Via Plugin that serves it as a static file.
Custom "connect4" theme: light, warm, playful palette with red/yellow
accents matching game pieces and board blue accent.
- User registration/login with bcrypt password hashing
- SQLite database with goose migrations and sqlc-generated queries
- Games and players persisted to database, resumable after restart
- Guest play still supported alongside authenticated users
- Auth UI components (login/register forms, auth header, guest banner)
- Enter key now triggers createGame action on home page
- Remove redundant setNickname action from home page
- Remove unused code: join channel, Leave(), Stop() methods
- Consolidate ID generation into game.GenerateID()
- Remove unused CreatedAt field from Game struct
Real-time two-player Connect 4 using Via framework with:
- Game creation and invite links
- SSE-based live updates for both players
- Win detection with animated highlighting
- Session-based nickname persistence