Skip to main content
BLACK SKIES ARCHITECTURE · EPISODE 4 OF 7

Ingress: Handling Client Actions at Scale

· 20:00 ·
#distributed-systems#validation#security#gameplay

Command validation, intent collection, and the 500ms tick budget. How client actions flow into tile processors and get validated before execution.

Overview

This episode covers the ingress path: how player commands travel from client to tile processor, get validated, and become part of the next tick.

Key Topics

  • The trust boundary: clients are adversarial by default
  • Intent-based architecture: clients suggest, server decides
  • Validation pipeline: rate limits, state checks, rule enforcement
  • The 500ms tick budget: why responsiveness demands fast validation

Architecture Flow

Client WebSocket

Relay Pod (edge)

Gateway API (auth + routing)

Tile Processor (validation + execution)

Redis Stream (persistence)

Timestamps

Validation Layers

  1. Rate limiting: Per-captain token bucket (actions per second)
  2. Cooldown checks: Card/action cooldowns enforced server-side
  3. Fuel reachability: Fuel card must be same owner or same permanent
  4. Range checks: Target must be within ability range
  5. State checks: Entity not disabled, card not exhausted

Rejection Handling

Invalid intents are rejected with specific codes:

enum RejectionCode {
  None = 0;
  RateLimited = 1;
  OnCooldown = 2;
  InsufficientFuel = 3;
  OutOfRange = 4;
  CardExpired = 5;
  CardSacrificed = 6;
  CardDisabled = 7;
}

Clients receive rejection synchronously but tick execution is asynchronous.

Next Episode

Episode 5 covers tile spawning and lifecycle: how the world dynamically expands and contracts based on player distribution.