RUDPFramework/MobaSyncMVP.md

6.6 KiB

MOBA Hybrid Sync MVP

Goal

Build a minimal hybrid sync model for a MOBA-like game:

  • Client sends only player inputs
  • Server runs authoritative gameplay logic
  • Server sends authoritative state and combat results back to clients
  • Client uses prediction for local control and interpolation/reconciliation for presentation

This MVP supports only two player inputs:

  • Move
  • Shoot

Other core gameplay data such as position and HP remain server-authoritative.

Core Model

Client Responsibilities

  • Capture local input
  • Send input messages to server
  • Predict local movement immediately
  • Play local shooting presentation immediately if desired
  • Reconcile local player state when authoritative state arrives
  • Interpolate remote player movement for smooth display

Server Responsibilities

  • Receive all player inputs
  • Validate and apply movement
  • Validate shooting requests
  • Resolve hit, damage, death, and other combat results
  • Maintain authoritative position, HP, and combat state
  • Broadcast authoritative state snapshots
  • Broadcast authoritative combat events

Message Plan

Message Direction Reliability Frequency Purpose
MoveInput Client -> Server Low reliability / latest wins 10-20 Hz Report movement input
ShootInput Client -> Server Reliable ordered On demand Report shoot request
PlayerState Server -> Client Low reliability / latest wins 10-20 Hz Sync position, rotation, HP
CombatEvent Server -> Client Reliable ordered On demand Sync hit, damage, death
Heartbeat / ClockSync Both ways Reliable ordered 1-2 Hz Keepalive and server tick sync

Message Definitions

MoveInput

Sent frequently. Old packets can be dropped.

Suggested fields:

  • playerId
  • tick
  • moveX
  • moveY

Notes:

  • Represents current movement intent
  • Should be treated as a high-frequency sync message
  • Latest input matters more than full delivery history

ShootInput

Sent only when player fires.

Suggested fields:

  • playerId
  • tick
  • dirX
  • dirY
  • optional targetId

Notes:

  • Must be delivered reliably
  • Server decides whether shooting is valid
  • Client may play local muzzle flash or firing animation immediately, but not authoritative hit resolution

PlayerState

Sent from server as authoritative snapshot.

Suggested fields:

  • playerId
  • tick
  • position
  • rotation
  • hp
  • optional velocity

Notes:

  • Used for local reconciliation and remote interpolation
  • Position and HP are server-authoritative
  • Older states should be discarded if a newer state already exists

CombatEvent

Sent when authoritative combat logic produces a result.

Suggested fields:

  • tick
  • eventType
  • attackerId
  • targetId
  • damage
  • optional hitPosition

Typical event types:

  • Hit
  • DamageApplied
  • Death
  • ShootRejected

Notes:

  • Reliable ordered delivery is required
  • Clients update HP, death state, hit reactions, and combat UI from this message class

Authority Rules

Client Authoritative

Only for temporary presentation:

  • Local movement prediction
  • Local fire animation / local FX preplay

These are visual conveniences only and must be correctable.

Server Authoritative

Always authoritative for:

  • Final position
  • HP
  • Combat resolution
  • Shoot validation
  • Hit validation
  • Death state

Clients must never be allowed to finalize these outcomes.

Client Handling Rules

Local Player

  • Send MoveInput continuously while movement changes
  • Apply local predicted movement immediately
  • Send ShootInput when firing
  • Optionally play local fire effect immediately
  • When PlayerState arrives:
    • compare authoritative position against predicted position
    • if error is small, smooth correct
    • if error is large, snap or fast-correct
  • When CombatEvent arrives:
    • update HP and combat result using server truth

Remote Players

  • Do not predict their gameplay logic
  • Buffer recent PlayerState snapshots
  • Interpolate between snapshots for smooth rendering
  • Apply CombatEvent immediately

Transport Mapping

This repository already has the right high-level direction:

  • High-frequency sync lane for movement/state-like messages
  • Reliable lane for guaranteed gameplay events

Recommended mapping:

  • MoveInput -> sync lane
  • ShootInput -> reliable lane
  • PlayerState -> sync lane
  • CombatEvent -> reliable lane

Important:

  • Do not keep both movement and shooting inside the same PlayerInput message if they need different delivery policies
  • Split them into distinct message types so delivery policy stays explicit

Tick and Ordering

Use tick on all gameplay-relevant messages.

Purposes:

  • detect stale sync messages
  • support reconciliation
  • align state snapshots to server simulation
  • simplify debugging

Recommended rules:

  • MoveInput and PlayerState may drop stale packets
  • ShootInput and CombatEvent should remain ordered and reliable

Phase 1

  • Implement MoveInput
  • Implement authoritative PlayerState
  • Run local prediction for self
  • Run interpolation for remote players

Phase 2

  • Implement ShootInput
  • Implement authoritative CombatEvent
  • Server resolves hit and damage
  • Clients update HP and hit feedback from server results

Phase 3

  • Add optional projectile authority model if needed
  • Add more combat event types
  • Add anti-cheat diagnostics or state hash logging only as auxiliary tooling

Non-Goals For MVP

Do not include these in the first version:

  • Client-side authoritative combat
  • Client majority voting
  • Client hash majority recovery
  • Full deterministic lockstep
  • Complex rollback netcode
  • Advanced anti-cheat enforcement

Implementation Notes For This Repository

Based on the current network architecture:

  • Current PlayerInput is too broad for this MVP if movement and shooting need different reliability
  • Prefer adding separate message types for MoveInput and ShootInput
  • Keep PlayerState as a high-frequency authoritative snapshot
  • Add a new reliable message type for CombatEvent

If the current transport setup uses only one underlying transport instance, the application layer can still distinguish message policy logically, but true sync/reliable isolation is better when backed by distinct lanes or transport behavior.

Summary

For the MVP:

  • Client sends only MoveInput and ShootInput
  • Server owns all gameplay truth
  • Server sends PlayerState and CombatEvent
  • Client predicts local movement
  • Client interpolates remote movement
  • Client corrects to server state when divergence appears

This gives a practical, controllable, and extensible baseline for a small MOBA-style networking model.