# Client vs server authority (Neon Sprawl) This doc answers **who owns truth** for gameplay-relevant state and what the client may assume or predict. It complements [contracts.md](contracts.md) (what shapes cross the wire) and [`docs/architecture/tech_stack.md`](../../architecture/tech_stack.md) (stack locks). --- ## Default rule - **Server** is authoritative for anything that affects **persistence**, **other players**, **economy**, **progression**, **security / PvP policy**, or **anti-cheat**. - **Client** owns **input**, **presentation**, **UI**, **camera framing**, and **optional local prediction** that must **reconcile** to the server without changing committed outcomes. Matches tech stack: client sends **intents**; server emits **state** (deltas or snapshots). Authoritative logic stays in **ASP.NET Core**, not Godot multiplayer templates. --- ## Intents vs authoritative state | Direction | Content | Rule | |-----------|---------|------| | Client → server | **Intents** (move path, ability use, craft request, interact, chat, …) | Server validates every intent against rules, content, and current sim state. | | Server → client | **Authoritative state** (`PositionState`, inventory, combat resolution, quest flags, zone tier, PvP eligibility, …) | Client displays and may predict; server wins on conflict. | Naming on the wire may use `*Command` or `*Intent` for client→server and `*State` / `*Resolution` / snapshots for server→client; the **role** (intent vs truth) matters more than the suffix. --- ## By module (prototype defaults) ### E1.M1: InputAndMovementRuntime - **Authoritative:** `PositionState` (and any rule derived from it: interaction range, zone presence) is owned by the **server** simulation. - **Client:** Sends movement **intent** (e.g. destination, path id, or tick-aligned input—exact wire shape in Protobuf later). May **predict** the local avatar for responsiveness. - **Reconciliation:** One documented ruleset: on server snapshot or correction, the client **must** converge to server truth (snap or blend—implementation choice; server outcome is final). Log material desync via [E9.M1 — TelemetryEventSchema](E9_M1_TelemetryEventSchema.md) when schema exists. - **Deferred (not fixed here):** Sim tick rate, snapshot cadence, delta vs full snapshot protocol, and prediction smoothing curves—pick when networking MVP is scoped. ### E1.M2: IsometricCameraController - **Authoritative:** **None** for prototype gameplay. Camera follow, zoom band, and occlusion are **client-local**; the server does **not** need `CameraState` for combat, zones, or PvP unless a future feature (e.g. replay) explicitly requires it. - **Server:** Must not use client-reported camera pose for **gameplay checks** (targeting, line of sight, etc.); those use **world geometry + server-known positions**, not “what the player saw.” ### E1.M3: InteractionAndTargetingLayer - **Authoritative:** Valid **target** and **interactable** eligibility (range, faction, phase, alive/dead) are decided on the **server**. Client sends selection or use **intent**; server responds with accepted `TargetState` or denial. - **Client:** Hover, highlights, and tentative selection are presentation; may be wrong until server confirms. ### E1.M4: AbilityInputScaffold - **Client:** Emits ability **intent** (`AbilityCastRequest` / equivalent) with ability id, target id, optional aim data as designed. - **Server:** [E5.M1 — CombatRulesEngine](E5_M1_CombatRulesEngine.md) (and related systems) validate cooldowns, resources, range, facing/LOS rules, and [E6.M1](E6_M1_PvPEligibilityAndFlagState.md) where relevant; emits **CombatResolution** (or denies with reason). ### E5.M1: CombatRulesEngine - **Never trust** client-supplied **damage**, **healing**, **crit rolls**, or **death** outcomes as source of truth. - **Trust** only what the client can **observe** as intent: which action, which target, timing within tolerance—then **recompute** everything server-side from `SkillDef`, stats, and combat state. - **Player targets:** Before applying hostile effects to another player, consult [E6.M1](E6_M1_PvPEligibilityAndFlagState.md) in-process; one combat engine for PvE and PvP — [details](pvp_combat_integration.md). ### Economy, crafting, inventory, quests, zones, PvP - **E3.\*, E7.\*, E4.\*, E6.\*:** Commit state and validate requests **only** on the server; client UI is a **view** over server-driven data. Already assumed in epics; this doc makes the split explicit for implementers. --- ## Telemetry and debugging - **Authority violations** (client assumed an outcome the server denied) should be **visible**: denied intents with reason codes, optional lightweight desync counters—not silent fixes in production without logging. --- ## What this doc does not fix yet - Exact **network update rate** and **interest management** (who receives which entity updates). - **Lag compensation** model for tab-target combat (if any)—decide with combat design and E5.M1 implementation. - **Rollback** vs **hard snap** reconciliation for movement—engineering choice after first multiplayer vertical slice. Revisit when the first **Protobuf** game channel and a **multiplayer** milestone are defined. --- ## Related docs - [`docs/architecture/tech_stack.md`](../../architecture/tech_stack.md) — server-authoritative critical paths, intents vs state - [contracts.md](contracts.md) — wire vs content artifacts - [PvP and the combat engine](pvp_combat_integration.md) — E5.M1 × E6.M1 integration shape - [Module dependency register](module_dependency_register.md)