---
last_mapped: 2026-02-07T22:13:13Z
total_files: 1188
total_tokens: 2606215
---

# Codebase Map

> Auto-generated by Cartographer. Last mapped: 2026-02-07T22:13:13Z

## System Overview

BaoLife is a real-time life simulation game monorepo. Players create a character and experience a full lifetime — childhood through old age — with relationships, careers, education, dating, and random life events, all driven by a tick-based game loop over WebSocket.

```mermaid
graph TB
    subgraph Clients
        iOS["iOS App<br/>(SwiftUI)"]
        Android["Android App<br/>(Jetpack Compose)"]
        Legacy["Web Frontend<br/>(DEPRECATED)"]
    end

    subgraph "Backend (Active)"
        TS["TypeScript Server<br/>server/src/"]
        WS["WebSocket Server<br/>(ws library)"]
        GL["Game Loop<br/>(1ms tick)"]
        EV["Event System<br/>(200+ events)"]
        SVC["Services Layer<br/>(13 modules)"]
        AI["AI Integration<br/>(OpenAI, Together, Mistral)"]
    end

    subgraph "Backend (Legacy)"
        PY["Python Server<br/>ws/"]
    end

    subgraph Data
        DB[(MySQL<br/>lifesim)]
        Cache["LRU Cache<br/>(in-memory)"]
    end

    subgraph External
        DiceBear["DiceBear API<br/>(Avatars)"]
        FalAI["fal.ai<br/>(Image Gen)"]
        Firebase["Firebase<br/>(Analytics)"]
        APNs["APNs / FCM<br/>(Push)"]
    end

    iOS -->|wss://lichun.app/wss/| WS
    Android -->|wss://lichun.app/wss/| WS
    WS --> TS
    TS --> GL
    GL --> EV
    GL --> SVC
    SVC --> AI
    SVC --> DB
    SVC --> Cache
    SVC --> DiceBear
    SVC --> FalAI
    iOS --> Firebase
    Android --> Firebase
    TS --> APNs
```

## Directory Structure

```
lichun/                            # Monorepo root
├── server/                        # TypeScript Backend (ACTIVE) - 564k tokens
│   ├── src/
│   │   ├── index.ts               # Entry point & orchestration
│   │   ├── config.ts              # Environment-based configuration
│   │   ├── server/                # WebSocket server, dispatcher, registry
│   │   ├── game/                  # Game loop, session, batched updates, event registry
│   │   ├── handlers/              # 30+ WebSocket command handlers
│   │   ├── models/                # Player, Person, MessageEvent, Question
│   │   ├── events/                # 200+ life events (14 categories)
│   │   ├── services/              # 13 service modules (44 files)
│   │   ├── database/              # MySQL pool, player CRUD, conversations
│   │   ├── auth/                  # JWT authentication
│   │   ├── monetization/          # Diamond economy, energy refills, time skips
│   │   ├── monitoring/            # Performance, health checks, rate limiting
│   │   ├── stats/                 # Stats manager, stat utilities
│   │   ├── testing/               # Test helpers
│   │   └── utils/                 # Message sanitizer, stat utils
│   └── tests/                     # Vitest unit + integration tests
│
├── ws/                            # Python Backend (LEGACY) - 590k tokens
│   ├── app.py                     # WebSocket server entry point
│   ├── functions.py               # Backward-compat facade (was 3116 lines)
│   ├── game_engine.py             # Decoupled testable game loop
│   ├── config.py                  # Environment configuration
│   ├── conversationEvents.py      # AI conversation system
│   ├── intradayActivity.py        # Daily schedule generation
│   ├── core/models.py             # playerClass, personClass, locationClass
│   ├── server/                    # WebSocket handlers, command dispatcher
│   ├── events/                    # 14 event categories (100+ events)
│   ├── character/                 # Character creation & management
│   ├── education/                 # School/college/major catalogs
│   ├── jobs/                      # 26 occupations x 5 levels
│   ├── health/                    # Health conditions, habits, death
│   ├── relationships/             # Romance, dating, marriage
│   ├── retention/                 # Achievements, quests, rewards
│   ├── monetization/              # IAP, energy, time skips
│   ├── dating/                    # Compatibility, matching, activities
│   ├── analytics/                 # Event tracking
│   └── tests/                     # pytest suite with fixtures & mocks
│
├── ios/                           # iOS App (SwiftUI) - 653k tokens
│   ├── lichunWebsocket/
│   │   ├── lichunWebsocketApp.swift   # App entry, 8 @StateObjects
│   │   ├── ContentView.swift          # Root view orchestrator
│   │   ├── WebSocketService.swift     # Central hub (1208 lines, 35+ @Published)
│   │   ├── Core/                      # Models (Player, Person, Activity, etc.)
│   │   │   ├── Models/               # 7 model files
│   │   │   ├── ViewModels/           # GameStateViewModel, PlayerViewModel
│   │   │   └── Services/             # ParsingHelpers
│   │   ├── Features/                  # 13 feature modules (103 files)
│   │   │   ├── Home/                  # Dashboard, timeline, controls
│   │   │   ├── Activities/            # Jobs, education, hobbies
│   │   │   ├── Dating/               # Swipe dating, relationships (21 files)
│   │   │   ├── Messaging/            # Chat interface (9 files)
│   │   │   ├── Character/            # Profiles, creation, death (20+ files)
│   │   │   ├── Events/               # Question/event modals
│   │   │   ├── Onboarding/           # 5-step tutorial (11 files)
│   │   │   ├── Monetization/         # Energy refills, time skips
│   │   │   ├── Retention/            # Achievements, rewards, quests
│   │   │   ├── Store/                # In-game shop, IAP
│   │   │   ├── Social/               # Combined dating + messages
│   │   │   └── Settings/             # GDPR, data export
│   │   ├── Shared/                    # Design system, managers, components
│   │   │   ├── DesignSystem/          # AppColors, AppSpacing, AppTypography
│   │   │   ├── Managers/             # Toast, Analytics, Sound, Tooltip
│   │   │   └── Components/           # 50+ reusable UI components
│   │   └── Legal/                     # Privacy, terms, support HTML
│   ├── docs/                          # iOS-specific documentation
│   ├── CLAUDE.md                      # iOS development guide
│   └── BACKEND.md                     # API protocol reference
│
├── android/                       # Android App (Kotlin/Compose) - 210k tokens
│   └── app/src/main/java/com/craigvg/lichun_android/
│       ├── BaoLifeApp.kt             # Hilt application entry
│       ├── MainActivity.kt           # Single activity, Compose host
│       ├── di/AppModule.kt           # Hilt dependency injection
│       ├── domain/models/            # 16 data model files
│       ├── viewmodel/                # GameStateViewModel, PlayerViewModel
│       ├── network/WebSocketManager.kt  # Central hub (1367 lines)
│       ├── managers/                  # Toast, Sound, Analytics, Billing, Push, Tooltip
│       ├── ui/
│       │   ├── theme/                # AppColors, Spacing, Typography, Theme
│       │   ├── components/           # ~55 reusable components
│       │   ├── screens/              # ~75 feature screens
│       │   └── navigation/           # Compose Navigation graph
│       ├── utils/                    # ~20 utility files
│       └── services/                 # FCM messaging service
│
├── docs/                          # Project documentation - 360k tokens
│   ├── PROJECT_STATUS.md          # Current status & priorities
│   ├── FRONTEND.md                # Frontend reference (web deprecated)
│   ├── TESTING.md                 # Testing guide
│   ├── DEPLOYMENT.md              # GCP deployment guide
│   ├── plans/                     # 17 planning documents
│   └── archived/                  # 50+ historical docs
│
├── tests/                         # Root-level Python test infra
├── api/                           # Legacy PHP API (push notifications)
├── privacy/                       # Privacy policy HTML
├── assets/                        # Legacy web frontend assets
├── git_hook/                      # GitHub webhook auto-deploy
├── .github/workflows/test.yml     # CI/CD (pytest + lint + simulation)
├── CLAUDE.md                      # Main project documentation
├── AGENTS.md                      # Operations runbook
├── index.html                     # DEPRECATED web frontend
└── main.js                        # DEPRECATED web frontend JS
```

## Module Guide

### TypeScript Backend (`server/`)

The active backend serving all clients. Event-driven architecture with a 1ms tick-based game loop.

#### Entry & Server Infrastructure

| File | Purpose | Key Exports |
|------|---------|-------------|
| `src/index.ts` | Entry point, startup orchestration | `main()` |
| `src/config.ts` | Environment config (frozen object) | `config` |
| `src/server/WebSocketServer.ts` | Connection lifecycle, session init | `WebSocketServer`, `webSocketServer` |
| `src/server/MessageDispatcher.ts` | Command routing (Map-based O(1)) | `MessageDispatcher`, `messageDispatcher` |
| `src/server/ConnectionRegistry.ts` | Active session tracking | `ConnectionRegistry`, `connectionRegistry` |

**Startup flow**: DB pool init -> table creation -> retention init -> handler registration -> WebSocket server start -> background jobs start -> shutdown handlers registered.

#### Game Loop (`src/game/`)

| File | Purpose | Key Exports |
|------|---------|-------------|
| `PlayerSession.ts` | Per-player game loop & state sync | `PlayerSession` |
| `BatchedUpdate.ts` | Accumulate state changes for efficient sends | `BatchedUpdate` |
| `engine/EventRegistry.ts` | O(1) event filtering by conditions | `EventRegistry`, `registerEvent()` |

**Tick flow**: `tick()` -> `advanceMinute()` -> hourly: `processHourTick()` (events, queue) -> daily: `processDayTick()` (stats, energy, date) -> weekly: `processWeekTick()` (save).

#### Models (`src/models/`)

| File | Purpose | Key Properties |
|------|---------|----------------|
| `Player.ts` | Game state container | `c` (character), `r` (relationships), `conversations`, `events` (Set), `date`, `gameSpeed` |
| `Person.ts` | Character/NPC | 50+ properties: stats, age, education, career, relationships, activities, messaging traits |
| `MessageEvent.ts` | Claimable life events | `message`, costs/rewards, `claimed`, `category` |
| `Question.ts` | Player choice events | `message`, `answers[]` with costs, `characters` |

#### Event System (`src/events/` - 200+ events, 74 files)

The heart of the game. Events are checked on each hour tick and trigger based on age, probability, occupation, and custom conditions.

**Event Categories:**

| Category | Files | Events | Ages | Description |
|----------|-------|--------|------|-------------|
| `childhood/` | 5 | ~20 | 0-12 | Milestones, activities, setbacks |
| `adolescence/` | 4 | ~15 | 10-18 | Puberty, social, teen life |
| `adulthood/` | 4 | ~15 | 18+ | Career, romance, family |
| `education/` | 5 | ~25 | 5-22 | School life, tests, extracurriculars |
| `activities/` | 9 | ~70 | 5-100 | Physical, creative, social, hobbies (class-based) |
| `conversations/` | 9 | N/A | All | AI-powered NPC chat system |
| `dilemmas/` | 2 | ~12 | 10+ | Multi-step moral choices |
| `negative/` | 9 | ~50 | All | Academic, financial, career, crisis, health, social |
| `random/` | 3 | ~20 | All | Lucky finds, minor mishaps |
| `relationships/` | 2 | 8 | 10+ | Weekly romantic events |
| `school_year/` | 2 | ~25 | 5-22 | Transitions, prom, college |
| `holidays/` | 2 | 25+ | All | Christmas, birthdays, seasonal |
| `health/` | 2 | ~10 | All | Injuries, conditions, checkups |
| `tutorial/` | 2 | 13 | New | First 24-hour onboarding |
| `family/` | 2 | ~10 | All | Family activities, transitions |
| `social/` | 2 | 4 | 8+ | Clubs, volunteering (class-based) |

**Two event architectures:**
1. **Function-based** (most modules): `(player, type) => EventResult` with fname deduplication
2. **Class-based** (activities, social): Extends `BaseEvent` with activity tracking and schedules

**Core event helpers** (`base.ts`): `createMessageEvent()`, `createQuestionEvent()`, `checkProbability()`, `checkMilestoneProbability()`, `modifyStat()`

#### Services Layer (`src/services/` - 44 files, 13 modules)

| Module | Files | Purpose | Key Patterns |
|--------|-------|---------|--------------|
| `analytics/` | 3 | Event tracking, sessions | Buffered batch flush (500 events / 30s) |
| `background/` | 3 | Scheduled jobs, offline queue | Interval-based, 7-day retention |
| `character/` | 4 | Character creation, avatars, family trees | DiceBear API, AI-powered bios |
| `dating/` | 6 | Bio gen, compatibility, matching, date activities | OpenAI, score algorithm (0-100) |
| `education/` | 2 | School/college catalogs, GPA tracking | Lazy-initialized caches |
| `health/` | 3 | Conditions, habits (16 neg/15 pos), death | Age-based death probability |
| `jobs/` | 2 | 26 occupations x 5 levels, performance | Promote at 90, fire at 10 |
| `npc/` | 3 | Daily schedules, location-based interactions | Shared locations for families |
| `performance/` | 3 | LRU cache w/ TTL, message batching | 50 msg/batch, 100ms flush |
| `relationships/` | 2 | Romance, dating, marriage mechanics | Affinity-based (requires 50+) |
| `retention/` | 7 | Achievements (40+), daily rewards, quests, tutorial | Diamond economy rewards |
| `shop/` | 2 | 48 store items, 5 IAP packs | $0.99-$4.99 diamond packs |
| `images/` | 4 | Multi-provider AI image gen | fal.ai (Imagen 4), DALL-E 3 fallback |

#### Handlers (`src/handlers/`)

30+ WebSocket command handlers organized by category:

| Category | Commands |
|----------|----------|
| Game Control | `start`, `stop`, `restart`, `speed`, `resetSpeed` |
| Character | `characterSetup`, `deviceToken` |
| Activities | `applyForJob`, `quitJob`, `applyForExtracurricular`, `focusUpdate` |
| Conversations | `conversation`, `retrievePerson`, `markConversationAsRead` |
| Purchases | `purchaseItem`, `purchaseEnergyRefill`, `purchaseTimeSkip` |
| Retention | `getAchievements`, `getDailyRewards`, `claimDailyReward`, `claimQuestReward` |
| Romance | `romance`, `dateNight`, `breakUp`, `divorce`, `getSwipeCharacter` |
| Data | `exportData`, `deleteAccount`, `getPlayerStatistics` |

#### Database (`src/database/`)

- **Connection**: MySQL2 connection pool with typed query helpers
- **Tables**: `players` (JSON blob), `conversations` (dedicated), `conversation_messages`
- **Migration**: Dual-storage strategy — conversations migrated from JSON blob to dedicated table
- **Persistence**: `savePlayer()` (REPLACE INTO), `loadPlayer()` with offline stats calculation

---

### iOS App (`ios/`)

SwiftUI app with MVVM architecture. 316 files, targeting iOS 14+.

#### Architecture

**Pattern**: MVVM with 8 centralized `@StateObject` instances injected via `@EnvironmentObject`.

**State flow**: `WebSocketService` (source of truth) -> Combine subscriptions -> `GameStateViewModel` + `PlayerViewModel` (derived state) -> SwiftUI views.

**Core services** (injected as environment objects):
1. `WebSocketService` — Real-time communication hub (1208 lines, 35+ @Published properties)
2. `GameStateViewModel` — Cross-feature state (resources, time)
3. `PlayerViewModel` — Character-specific state (person, relationships)
4. `AppViewModel` — Navigation, onboarding, tab selection
5. `StoreManager` — StoreKit IAP
6. `ToastManager` — Notification queue
7. `SoundManager` — Audio playback
8. `TooltipManager` — Onboarding tooltips

#### Feature Modules (13 modules, 103 files)

| Feature | Files | Purpose |
|---------|-------|---------|
| Home | 13 | Dashboard: avatar, stats, game controls, life timeline |
| Activities | 6 | Jobs, education, extracurriculars, habits |
| Dating | 21 | Swipe dating, relationships, compatibility, mini-games |
| Messaging | 9 | Chat interface, conversation list, message bubbles |
| Character | 20+ | Creation, NPC profiles (accordion sections), death screen |
| Events | 1 | Unified question/event modal with 2-column answer grid |
| Onboarding | 11 | 5-step tutorial with tooltips |
| Monetization | 6 | Energy refills, time skips |
| Retention | 8 | Achievements (40+), daily rewards, daily quests |
| Store | 4 | In-game shop, IAP |
| Social | 1 | Combined dating + messages tab |
| Settings | 2 | GDPR: data export, account deletion |

#### Design System

**Cozy game aesthetic** — warm pastels replacing standard iOS blue:
- Primary: Soft rose pink (`#F4A5B5`) instead of system blue
- Background: Warm cream (`#FFF8F3`) instead of white
- Text: Warm brown (`#5A4A3A`) instead of black
- Stats: Sage green, butter yellow, sky blue, coral
- Dark mode: Warm evening lighting (`#2A2420`)
- Seasonal gradients: spring, summer, autumn, winter

50+ reusable shared components including `BaseCard`, `PrimaryButton`, `CozyStatBar`, `CharacterAvatar`, `ResourcePill`.

---

### Android App (`android/`)

Kotlin + Jetpack Compose app achieving ~85-90% feature parity with iOS. 167 Kotlin files.

#### Architecture

**Pattern**: MVVM + Hilt DI + Kotlin Flow (StateFlow).

- `WebSocketManager.kt` (1367 lines) — Central hub, mirrors iOS `WebSocketService`
- `GameStateViewModel` — Cross-feature state via StateFlow
- `PlayerViewModel` — Character state via StateFlow
- OkHttp WebSocket with exponential backoff reconnection
- Same design system (AppColors, AppSpacing, AppTypography) as iOS

#### Key Differences from iOS

- Hilt for dependency injection (vs iOS manual `@StateObject`)
- Kotlin StateFlow (vs Combine `@Published`)
- Compose Navigation (vs iOS sheet-based)
- Google Play Billing (vs StoreKit)
- FCM (vs APNs) for push notifications
- Coil + AndroidSVG for images (vs SDWebImage)

---

### Python Backend (`ws/`) — LEGACY

The original backend, refactored from a 3116-line monolith into 30+ modular files. It is retained as legacy reference and maintenance-only code; active backend work and deploys use the TypeScript server.

**Architecture**: async WebSocket server (websockets library), MySQL, OpenAI integration.

**Key design patterns**: Protocol-based abstractions (IGameStorage, IGameOutput, IConversationService), factory pattern, LRU player cache, command dispatch registry, event handler registry.

**Module structure** mirrors TypeScript backend: character/, education/, jobs/, health/, relationships/, retention/, monetization/, dating/, analytics/, events/ (14 categories).

---

## Data Flow

### WebSocket Message Flow

```mermaid
sequenceDiagram
    participant Client as iOS/Android
    participant WS as WebSocket Server
    participant Dispatch as MessageDispatcher
    participant Session as PlayerSession
    participant Loop as Game Loop
    participant Events as Event System
    participant DB as MySQL

    Client->>WS: {type: "init", userID: "..."}
    WS->>DB: loadPlayer(userID)
    DB-->>WS: Player data (JSON)
    WS->>Session: Create PlayerSession
    WS-->>Client: playerObject (full state)

    Session->>Loop: Start tick interval (1ms)

    loop Every game tick
        Loop->>Loop: advanceMinute()
        Loop-->>Client: {type: "u", ...} (batched update)
    end

    loop Every hour boundary
        Loop->>Events: checkEvents(player)
        Events-->>Client: messageEvent / questionEvent
    end

    Client->>WS: {type: "questionEvent", response: "..."}
    WS->>Dispatch: route to handler
    Dispatch->>Session: process answer
    Session-->>Client: updated state
```

### Game Loop Tick Hierarchy

```mermaid
graph TD
    T["tick() - every 1ms"] --> M["advanceMinute()<br/>minuteOfHour++"]
    M -->|"minuteOfHour == 0"| H["processHourTick()<br/>Check events, message queue"]
    M -->|"hourOfDay == 0"| D["processDayTick()<br/>Birthday, death, stats, energy, date"]
    M -->|"dayOfWeek == 1"| W["processWeekTick()<br/>Finances, save, relationships"]

    H --> E1["checkTutorialEvents()"]
    H --> E2["checkEvents() via EventRegistry"]
    H --> E3["checkDilemmas() (2% chance)"]
    H --> E4["Process message queue"]

    D --> S1["Clamp stats 0-100"]
    D --> S2["Clean stale events"]
    D --> S3["Restore energy"]
    D --> S4["Update date/season"]

    W --> F1["handleFinances()"]
    W --> F2["handleRelationships()"]
    W --> F3["savePlayer() to DB"]
```

### Achievement/Quest Flow

```mermaid
sequenceDiagram
    participant Game as Game Event
    participant Int as retention/integration
    participant Ach as Achievements
    participant Quest as Daily Quests
    participant WS as WebSocket

    Game->>Int: onJobObtained() / onMarriage() / etc.
    Int->>Ach: checkAchievements(eventType)
    Ach->>Ach: Evaluate conditions
    Ach-->>WS: achievementUnlocked + diamonds
    Int->>Quest: updateQuestProgress(type, amount)
    Quest->>Quest: Check completion
    Quest-->>WS: questProgress update
```

## Conventions

### Code Organization
- **Barrel exports**: Each module has `index.ts` re-exporting all public APIs
- **Singleton pattern**: Services use module-level singletons (`getTracker()`, `getJobManager()`)
- **Factory pattern**: Object creation via factories (`createHabit()`, `createOccupation()`)

### Event Naming
- **Function names** serve as unique event IDs (stored in `player.events` Set)
- Events use `fname` variable checked against `player.events` for deduplication
- Question events additionally tracked in `player.askedQuestions` Set

### Probability System
- `checkProbability(n)` returns true with 1/n chance per tick
- Common: 400-1000, Uncommon: 1000-5000, Rare: 5000-100000

### Stat Modification
- All stats bounded 0-100 via `modifyStat()` / `clampPlayerStats()`
- Direct modification allowed but must be followed by clamping

### WebSocket Message Types
- `u` — Lightweight batched updates (energy, money, time, speed)
- `playerObject` — Full state sync (on init and major changes)
- `messageEvent` — Life event notification (claimable)
- `questionEvent` — Choice modal (pauses game)
- `conversationEvent` — Chat message
- `personObject` — Character detail modal

### iOS/Android Conventions
- MVVM architecture on both platforms
- Environment objects (iOS) / Hilt injection (Android) for shared state
- Cozy design system with matching color palettes
- Feature-based module organization
- Age-gated features (jobs >= 15, extracurriculars >= 13, dating >= 16)

## Gotchas

### Game Loop
- **1ms tick interval** but actual game time controlled by `gameSpeed` (ticks per game minute)
- Game pauses by setting `gameSpeed` to 100000 during questions
- Events only checked when `gameSpeed < SPEED_QUESTION_PAUSE`

### Dual Backend
- Active deploy paths use the **TypeScript** backend from `server/`
- The legacy Python backend in `ws/` is reference/maintenance-only
- Both backends share the same MySQL database and WebSocket protocol

### Data Persistence
- Player data stored as a **JSON blob** in the `data` column of `players` table
- Conversations have been migrated to a dedicated table but legacy blob data may exist
- `player.events` is a Set internally but serialized as Array in JSON

### AI Conversations
- Multi-provider support: OpenAI, Together AI, Mistral, OpenRouter
- Verbosity detection to keep responses natural length
- Message compaction: keeps 5 recent messages, summarizes older ones
- Fact extraction every 5 messages for character memory
- Fallback responses when API is unavailable

### WebSocket
- Auto-reconnection with exponential backoff (100ms -> 5s, max 1000 retries)
- iOS supports both flat format and nested format messages
- Message sanitizer strips JSON/tool-call artifacts from AI responses
- Rate limiting: 60 OpenAI requests/hour, 30 WebSocket messages/minute

### iOS Specifics
- `WebSocketService.swift` is 1208 lines — candidate for refactoring
- Conversations limited to 100 messages, activity records to 50 per person (memory optimization)
- SDWebImage with SVG support required for DiceBear avatars

### Android Specifics
- 4 known memory leaks from CoroutineScope management (per CODE_REVIEW_ISSUES.md)
- 11 empty WebSocket message handlers need implementation
- Money field should be Double not Int

### Security Concerns
- Hardcoded GitHub webhook secret in `git_hook/index.php`
- Push notification credentials visible in `api/index.php`
- In-memory monetization tracking needs database migration for production

## Navigation Guide

### To add a new life event
1. Choose category in `server/src/events/` (or create new subdirectory)
2. Create event function following pattern: `(player, type, message?, response?) => EventResult`
3. Use `createMessageEvent()` or `createQuestionEvent()` from `events/base.ts`
4. Export from category's `index.ts`
5. Event auto-registers via `events/index.ts` -> `allEvents`
6. For Python parity: mirror in `ws/events/` with same `fname`

### To add a new WebSocket command
1. Create handler function in `server/src/handlers/` (or add to existing file)
2. Register in `server/src/handlers/index.ts` COMMAND_REGISTRY
3. Update iOS: handle in `WebSocketService.swift` message processing
4. Update Android: handle in `WebSocketManager.kt` message processing
5. Document in `ios/BACKEND.md` protocol reference

### To add a new iOS feature screen
1. Create directory under `ios/lichunWebsocket/Features/[FeatureName]/`
2. Add Views/ and Components/ subdirectories
3. Follow MVVM: read state from `@EnvironmentObject` ViewModels
4. Use `AppColors`, `AppSpacing`, `AppTypography` from design system
5. Use `BaseCard` wrapper for consistent card styling
6. Add navigation in `ContentView.swift` or parent feature view

### To add a new Android screen
1. Create screen file in `android/app/src/main/.../ui/screens/[feature]/`
2. Accept ViewModels via Hilt injection or composable parameters
3. Register route in `ui/navigation/MainNavigation.kt`
4. Use `AppColors`, `AppSpacing`, `AppTypography` from theme
5. Follow existing patterns: `BaseCard`, `PrimaryButton`, etc.

### To add a new service module
1. Create directory under `server/src/services/[module]/`
2. Add `index.ts` barrel export
3. Follow singleton or factory pattern per existing conventions
4. Wire into game loop via `server/src/index.ts` or handler registration
5. Add tests in `server/tests/services/`

### To modify game speed / time progression
- `server/src/config.ts`: TICK_INTERVAL, SPEED_* constants
- `server/src/game/PlayerSession.ts`: `tick()` method
- `server/src/stats/stats_manager.ts`: hourly/daily/weekly update functions

### To run the project locally
- **Backend**: `cd server && npm install && npm run dev` (port 8001)
- **iOS**: `open ios/lichunWebsocket.xcodeproj` then Cmd+R
- **Android**: Open `android/` in Android Studio, build and run
- **Tests**: `cd server && npm test` (TypeScript) or `cd ws && pytest` (Python)

### Key files to read first
1. `CLAUDE.md` — Project overview and architecture
2. `ios/BACKEND.md` — WebSocket protocol reference
3. `server/src/index.ts` — Server entry point
4. `server/src/game/PlayerSession.ts` — Game loop
5. `server/src/events/base.ts` — Event system foundation
6. `ios/lichunWebsocket/WebSocketService.swift` — iOS state hub
7. `docs/PROJECT_STATUS.md` — Current status and priorities
