# 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)
