Operation: Black Swan presents players with a complex network architecture challenge: design and deploy critical infrastructure under budget constraints, time pressure, and unexpected events. Understanding the game flow is essential to understanding how the architecture supports strategic gameplay.
When a player starts a new game, the following sequence occurs:
┌─────────────────────────────────────────────────────────────────┐ │ GAME INITIALIZATION FLOW │ │ │ │ ┌──────────────────────┐ │ │ │ Player Visits Site │ │ │ │ (URL Request) │ │ │ └──────────┬───────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 1. CloudFront Serves Static Files │ │ │ │ • HTML, JS, CSS from nearest edge │ │ │ │ • Sub-100ms global latency │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 2. Next.js App Loads in Browser │ │ │ │ • React components mount │ │ │ │ • Zustand store initializes │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 3. Check localStorage for Saved Game │ │ │ │ • Zustand persist middleware reads │ │ │ │ • If found: "Resume last game?" │ │ │ │ • If not found: Show main menu │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ├─────────── Saved Game? ──────────┐ │ │ │ │ │ │ ▼ YES ▼ NO │ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ 4a. Resume Prompt │ │ 4b. Main Menu │ │ │ │ • Resume? │ │ • Start New │ │ │ │ • Start New? │ │ • Select Mode │ │ │ └──────────┬───────────┘ └──────────┬───────────┘ │ │ │ │ │ │ └────────────┬───────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 5. Game Mode Selection │ │ │ │ • Easy / Standard / Expert / Custom│ │ │ │ • Auto-calculate budgets via NBE │ │ │ │ • Configure: sites, throughput, │ │ │ │ turns, resiliency tokens │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 6. Initialize Game State │ │ │ │ • Create site objects │ │ │ │ • Set starting budget │ │ │ │ • Reset turn counter to 1 │ │ │ │ • Set mission points to 100 │ │ │ │ • Clear connections/events │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────┐ │ │ │ 7. Game Begins │ │ │ │ (Turn 1) │ │ │ └──────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘
Performance: Entire initialization happens in <2 seconds, including CDN fetch, app load, and state initialization.
Each turn represents a period of time for infrastructure deployment and operations. When a player ends their turn (clicks "Advance Turn"), a sophisticated multi-stage processing pipeline executes entirely client-side:
┌─────────────────────────────────────────────────────────────────┐ │ TURN PROCESSING FLOW │ │ │ │ ┌──────────────────────┐ │ │ │ Turn End Triggered │ │ │ │ (Player Action) │ │ │ └──────────┬───────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 1. Process Building Connections │ │ │ │ • Decrement build timers (-1) │ │ │ │ • Complete connections (timer=0) │ │ │ │ • Update connection status to │ │ │ │ "completed" when timer reaches 0 │ │ │ │ • Check connection milestones │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 2. Process Site-to-Site Connections │ │ │ │ • Decrement build timers (-1) │ │ │ │ • Complete connections (timer=0) │ │ │ │ • Update bidirectional link status│ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 3. Process Budget │ │ │ │ • Check if recurring budget turn │ │ │ │ (Turns 6, 11, 16, 21) │ │ │ │ • Apply budget delays (if enabled)│ │ │ │ - 3% probability on budget turns│ │ │ │ - Delay by 1-2 turns randomly │ │ │ │ • Add recurring budget if due │ │ │ │ • Process delayed budgets │ │ │ │ • Deduct per-turn operational costs│ │ │ │ (operationalCost/5 per connection)│ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 4. Process Active Events │ │ │ │ • Decrement event timers (-1) │ │ │ │ • Restore ended events (timer=0) │ │ │ │ - Restore offline connections │ │ │ │ - Remove event from active list │ │ │ │ • Award RAPTR tokens (if earned) │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 5. Calculate Throughput (2-Phase) │ │ │ │ • Phase 1: Direct site-to-cloud │ │ │ │ - Priority: Dedicated → Hosted │ │ │ │ → IP Tunnel │ │ │ │ - Allocate direct connections │ │ │ │ • Phase 2: Site-to-site sharing │ │ │ │ - Sort by site priority │ │ │ │ - Distribute excess capacity │ │ │ │ - Respect hub limits (max 4) │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 6. Update Mission Points │ │ │ │ • Calculate requirement % │ │ │ │ • < 50% met: -15 points │ │ │ │ • 50-99% met: -8 points │ │ │ │ • 100% met (no events): +5 points │ │ │ │ • 100% met (1 event): +15 points │ │ │ │ • 100% met (2 events): +25 points │ │ │ │ • 100% met (3+ events): +35-55 pts │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 7. Generate New Events │ │ │ │ • Check event probabilities │ │ │ │ - Early (T1-5): 5-10% │ │ │ │ - Mid (T6-15): 10-15% │ │ │ │ - Late (T16-25): 15-20% │ │ │ │ • Generate events if triggered │ │ │ │ • Apply event impacts immediately │ │ │ │ • Set duration (2-4 turns randomly)│ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 8. Check Game Over Conditions │ │ │ │ • Mission points <= 0? │ │ │ │ → IMMEDIATE LOSS │ │ │ │ • Turn limit reached? │ │ │ │ → Check 100% requirement │ │ │ │ • All requirements met? │ │ │ │ → WIN │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ 9. Update Game State & Save │ │ │ │ • Increment turn number │ │ │ │ • Update UI components │ │ │ │ • Auto-save to localStorage │ │ │ │ (via Zustand persist middleware) │ │ │ └──────────┬───────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────┐ │ │ │ Next Turn Begins │ │ │ │ (Player Actions) │ │ │ └──────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘
The nine-phase processing pipeline executes in a specific sequence that ensures consistent state transitions and accurate calculations. Connections complete building first, establishing new infrastructure before subsequent phases can reference it. Budget processing occurs early, providing funds before the simulation evaluates player capacity and generates new challenges. Active events decrement timers and restore connections before throughput calculation, ensuring the algorithm operates on current infrastructure state.
Throughput calculation follows infrastructure updates, producing accurate capacity measurements that feed into mission point scoring. Mission points update based on current turn requirements fulfillment, reflecting the infrastructure state after all updates. New event generation occurs near the end, introducing challenges after the turn's logistics complete, creating dramatic moments that test whether players built resilient systems. State persistence happens last, ensuring all changes save atomically to localStorage in a single operation.
Performance: All processing happens client-side in <100ms. No network latency, no server round-trips.
When a player builds a new connection, the following sequence occurs:
buildingconnections[] array in game statebuildTimer by 1buildTimer reaches 0: Set status to completedoperationalCost / 5 per turn for 5 turns)Reflects real-world project delays and prevents perfect planning. Creates uncertainty that requires players to build buffers and redundancy. Adds replay value (same strategy may yield different results due to randomization).
Operation: Black Swan uses a sophisticated two-phase algorithm to calculate site throughput that mirrors real-world network architecture patterns:
┌─────────────────────────────────────────────────────────────────┐ │ TWO-PHASE THROUGHPUT ALGORITHM │ │ │ │ PHASE 1: DIRECT SITE-TO-CLOUD CAPACITY │ │ ┌────────────────────────────────────────┐ │ │ │ For each Site (by Priority): │ │ │ │ │ │ │ │ 1. Collect all connections from site │ │ │ │ • Status: "completed" only │ │ │ │ • Exclude: offline (events) │ │ │ │ │ │ │ │ 2. Sort by connection type preference:│ │ │ │ Dedicated → Hosted → IP Tunnel │ │ │ │ │ │ │ │ 3. Allocate capacity by preference: │ │ │ │ • Dedicated: 10 Gbps each │ │ │ │ • Hosted: 1 Gbps each │ │ │ │ • IP Tunnel: 1 Gbps each │ │ │ │ │ │ │ │ 4. Calculate direct capacity: │ │ │ │ directCapacity = Σ(connection speeds)│ │ │ │ │ │ │ │ 5. Determine if requirements met: │ │ │ │ isMet = (directCapacity >= required)│ │ │ │ │ │ │ │ 6. Calculate excess capacity: │ │ │ │ excess = directCapacity - required │ │ │ │ (if excess < 0, then excess = 0) │ │ │ └────────────────────────────────────────┘ │ │ │ │ PHASE 2: SITE-TO-SITE CAPACITY SHARING │ │ ┌────────────────────────────────────────┐ │ │ │ For each Site with Excess (by Priority):│ │ │ │ │ │ │ │ 1. Get all site-to-site connections │ │ │ │ • Status: "completed" only │ │ │ │ • Exclude: offline (events) │ │ │ │ │ │ │ │ 2. Find all connected sites │ │ │ │ • Bidirectional: A→B means B←A │ │ │ │ │ │ │ │ 3. Sort connected sites by priority │ │ │ │ • Higher priority receives first │ │ │ │ │ │ │ │ 4. Distribute excess capacity: │ │ │ │ For each connected site (in order): │ │ │ │ needed = required - current │ │ │ │ allocated = min(needed, excess) │ │ │ │ Update: current += allocated │ │ │ │ Update: excess -= allocated │ │ │ │ If excess = 0: STOP │ │ │ └────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘
Sites:
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Site 1: Wright │ │ Site 2: Hamilton │ │ Site 3: Fort │
│ Brothers │ │ Yard │ │ Tecumseh │
│ │ │ │ │ │
│ Priority: 1 │ │ Priority: 2 │ │ Priority: 3 │
│ Required: 2 Gbps │ │ Required: 2 Gbps │ │ Required: 2 Gbps │
│ Direct: 0 Gbps │ │ Direct: 10 Gbps │ │ Direct: 0 Gbps │
│ (OUTAGE) │ │ Excess: 8 Gbps │ │ (OUTAGE) │
│ Need: 2 Gbps │ │ │ │ Need: 2 Gbps │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
│ │ │
│ Site-to-Site Links │ │
└────────────────────────────┴────────────────────────────┘
Phase 1 Results:
- Site 1: 0 Gbps (outage), NOT MET
- Site 2: 10 Gbps, MET (8 Gbps excess)
- Site 3: 0 Gbps (outage), NOT MET
Phase 2 Distribution (Site 2 distributes excess):
- Site 2 → Site 1: Allocate 2 Gbps (Site 1 now MET)
- Site 2 → Site 3: Allocate 2 Gbps (Site 3 now MET)
- Site 2 remaining excess: 4 Gbps (unused)
Final Results:
- Site 1: 2 Gbps (via site-to-site from Site 2), MET ✓
- Site 2: 10 Gbps (direct), MET ✓
- Site 3: 2 Gbps (via site-to-site from Site 2), MET ✓
- Overall: 100% requirements met, all sites operational
The two-phase algorithm reflects real network architectures where direct connections serve primary traffic and site-to-site links provide backup capacity. Phase 1 processes direct site-to-cloud connections with type-based prioritization (Dedicated → Hosted → IP Tunnel), establishing baseline capacity for each site. Sites meeting requirements through direct connections generate excess capacity that becomes available for distribution in Phase 2.
Phase 2 distributes excess capacity through site-to-site links using priority-based allocation, ensuring critical sites receive capacity before lower-priority sites. This cascading approach enables sites with robust direct connections to support multiple needy sites simultaneously, creating network-wide resilience from localized over-provisioning. The separation between phases creates strategic depth, requiring players to balance reliable direct connections against cost-effective site-to-site backup capacity for optimal cost-efficiency and resilience.