Files
2026-05-27 23:29:53 +01:00

4.4 KiB
Raw Blame History

game-server — Wave C-2 enhanced (delta)

ADDED Requirements

Requirement: Anti-Cheat Validator

@suaveplan/game-server SHALL expose an AntiCheatValidator<TMove, TAction> class for server-authoritative validation of player movement and actions.

Scenario: Movement under maximum speed is accepted

  • WHEN the validator receives two successive MovementData records for a player whose Euclidean distance over the elapsed time is below movement.maxSpeed × movement.toleranceFactor
  • THEN validateMovement SHALL return { valid: true }
  • AND SHALL record the latest position as the player's reference for subsequent calls.

Scenario: Teleport above threshold is rejected as major

  • WHEN the Euclidean distance exceeds movement.maxTeleportDistance
  • THEN validateMovement SHALL return a ValidationResult whose violation.type === "teleport" and violation.severity === "major"
  • AND SHALL emit a violation:detected event.

Scenario: Rate limit blocks bursts beyond maxActions

  • WHEN more than maxActions actions of the matching actionType (or "all") arrive inside a rolling windowMs
  • THEN validateAction SHALL return a ValidationResult whose violation.type === "rate_limit"
  • AND SHALL emit a rate_limit:exceeded event.

Scenario: Auto-flag triggers at threshold

  • WHEN the player accumulates ≥ autoFlagThreshold violations in the trailing 60 seconds
  • THEN the validator SHALL flag the player automatically
  • AND the most recent recorded violation SHALL have autoFlagged: true.

Scenario: Invalid configuration is rejected

  • WHEN caller-supplied AntiCheatConfig fails Zod validation
  • THEN the constructor SHALL throw a GameServerError with code GAME_SERVER.INVALID_ANTI_CHEAT_CONFIG.

Requirement: Interest Manager

@suaveplan/game-server SHALL expose an InterestManager<TData> class that performs area-of-interest culling for broadcast scope reduction.

Scenario: Entity inside view distance is visible

  • WHEN a player and an entity are within viewDistance
  • THEN getVisibleEntities SHALL include the entity in its result.

Scenario: Visibility delta omits unchanged set

  • WHEN calculateVisibilityChanges is called twice with no intervening position change
  • THEN the second call SHALL return null
  • AND SHALL NOT emit a visibility:changed event.

Scenario: Rectangular zone containment

  • WHEN a 3D point's (x, y, z) lies within ±width/2, ±height/2, ±depth/2 of a rectangular zone's centre
  • THEN isInZone SHALL return true.

Scenario: Custom zone delegates to provided predicate

  • WHEN a CustomZone is registered with containsPoint
  • THEN isInZone SHALL invoke that predicate and return its result.

Scenario: Invalid configuration is rejected

  • WHEN caller-supplied InterestManagerConfig fails Zod validation
  • THEN the constructor SHALL throw GameServerError with code GAME_SERVER.INVALID_INTEREST_CONFIG.

Requirement: Lag Compensator

@suaveplan/game-server SHALL expose a LagCompensator<TState> class for server-side time-rewind of game state during hit validation.

Scenario: Bounded history pruning

  • WHEN the number of recorded snapshots for an entity exceeds maxHistorySize
  • THEN the oldest snapshots SHALL be evicted
  • AND the count SHALL never grow beyond maxHistorySize.

Scenario: Compensation is clamped

  • WHEN the requested rewind exceeds maxCompensationMs
  • THEN the returned CompensatedState.compensationMs SHALL equal maxCompensationMs
  • AND the returned CompensatedState.clamped SHALL be true.

Scenario: Interpolation between snapshots

  • WHEN the rewind timestamp falls between two adjacent snapshots and a lerp function is supplied
  • THEN getStateAtTime SHALL invoke lerp to produce the returned state
  • AND the returned CompensatedState.interpolated SHALL be true.

Scenario: Hit validation requires both states

  • WHEN the shooter or the target has no recorded state at the perceived time
  • THEN validateHit SHALL return { valid: false } with a reason describing the missing side.

Scenario: Invalid configuration is rejected

  • WHEN caller-supplied LagCompensatorConfig fails Zod validation
  • THEN the constructor SHALL throw GameServerError with code GAME_SERVER.INVALID_LAG_COMPENSATION_CONFIG.