Skip to content

Combat State Replication

Document: Technical Design – Combat – Combat State Replication
Status: Exploratory
Last updated: 2026-01-12


1. Purpose

This document defines how combat state is represented, replicated, and validated in Atherion.

Goals:

  • server-authoritative combat outcomes
  • responsive, rhythm-safe gameplay
  • readable combat at MMO scale
  • scalable replication via SpacetimeDB
  • predictable latency handling

Combat must feel immediate without trusting the client.


2. Core Replication Philosophy

2.1. Authority Model

  • The server (SpacetimeDB module) is authoritative over:

    • health
    • damage
    • buffs / debuffs
    • cooldowns
    • threat / attention
    • stagger / break states
  • The client is authoritative only over:

    • local input intent
    • animation playback
    • camera and presentation

The client never decides outcomes.


2.2. Intent-Based Combat

Clients send intent, not results.

Examples:

  • “Attempt Block”
  • “Attempt Skill X at Target Y”
  • “Attempt Dodge in Direction Z”

The server:

  • validates
  • resolves timing
  • mutates state
  • publishes results

3. Combat State Granularity

3.1. Persistent Combat State

Stored in tables and replicated via subscriptions:

CombatantState
--------------
entity_id: EntityId
current_hp: int
max_hp: int
resource: int
status_flags: bitmask
position: Vector3
facing: Vector3

Used for:

  • rendering
  • targeting
  • validation
  • UI

3.2. Transient Combat Events

Not stored permanently; emitted as events:

  • damage application
  • stagger triggers
  • successful blocks
  • interrupts

Events are:

  • timestamped
  • ordered per entity
  • consumed by clients for feedback

4. Tick Rate Strategy

4.1. Variable Tick Domains

Combat uses multiple logical tick domains:

Domain Purpose Tick Rate
World Movement, positioning ~10–15 Hz
Combat Resolution Damage, blocks, hits ~20–30 Hz
UI / FX Visual updates Client-side

SpacetimeDB modules resolve combat on combat ticks, not world ticks.

4.2. Why Not Ultra-High Tick Rates

  • MMO scale makes 60+ Hz impractical
  • Latency hiding is achieved via prediction + reconciliation
  • Precision comes from timing windows, not raw frequency

5. Client-Side Prediction

5.1. What Is Predicted

Clients may predict:

  • movement
  • animation start
  • dodge start
  • block posture

Clients do not predict:

  • damage numbers
  • stagger success
  • buff application

5.2. Reconciliation Rules

If server disagrees:

  • client corrects silently
  • animation blends to authoritative state
  • no rewind-based correction (avoid jank)

Visual correction is favored over mechanical rewind.

6. Timing Windows (Critical)

6.1. Action Windows

Every combat action defines:

  • wind-up window
  • active window
  • recovery window

The server validates intent based on timestamps, not animation frames.

6.2. Example: Vanguard Block

  1. Client sends AttemptBlock(timestamp)
  2. Server checks:
    • block window active?
    • stamina/resource sufficient?
    • facing valid?
  3. If valid:
    • damage mitigated
    • stagger event emitted
  4. Clients receive:
    • block success event
    • boss stagger state

No pause. No cinematic.

7. Stagger and Break States

7.1. Server-Owned States

StaggerState
------------
entity_id: EntityId
stagger_level: int
is_exposed: bool
expires_at: timestamp
  • Triggered by coordinated actions
  • Short-lived
  • Explicitly timed

Clients react instantly.

8. Buffs and Debuffs

8.1. BuffState Table

BuffState
---------
entity_id: EntityId
buff_id: BuffId
source_id: EntityId
expires_at: timestamp
  • No permanent buffs
  • No infinite stacking
  • Server controls duration

Clients render icons + effects.

9. Threat and Attention

Threat is:

  • computed server-side
  • soft-weighted
  • influenced by taunts and mechanics

No threat UI bars by default.

10. Subscriptions and Replication Scope

Clients subscribe only to:

  • nearby combatants
  • relevant bosses
  • party members

This limits:

  • bandwidth
  • processing cost
  • visual noise

11. Instance Isolation

Each combat instance:

  • has its own combat tick loop
  • no cross-instance combat state
  • clean teardown on completion

Supports Everspire and dungeon scaling.

12. Anti-Cheat and Trust Boundaries

  • Clients cannot fabricate hits
  • Clients cannot alter cooldowns
  • All combat reducers validate:
    • timestamps
    • resources
    • state preconditions

Desync resolves in favor of server.

13. Performance Considerations

  • No per-frame combat writes
  • Events are batched per tick
  • State tables are compact
  • Combat math avoids dynamic allocation

14. Why This Works

This model:

  • preserves combat rhythm
  • scales to MMO populations
  • supports skill-based play
  • works with SpacetimeDB’s strengths
  • avoids client trust pitfalls

Combat feels responsive without sacrificing authority.

15. Open Questions

  • How much client-side interpolation is acceptable?
  • Should boss attacks be fully deterministic?
  • Should latency tolerance vary by content type?
  • How visible should correction be to players?

These will be answered via prototyping.

End of document.


Discussion