Skip to main content

Food Consumption API

The food consumption system provides OSRS-accurate eating mechanics with 3-tick eat delay and combat attack delay integration.

EatDelayManager

Manages per-player eating cooldowns. Location: packages/shared/src/systems/shared/character/EatDelayManager.ts

Methods

canEat()

Check if player can eat (not on cooldown).
Parameters:
  • playerId - Player to check
  • currentTick - Current game tick
Returns: true if player can eat, false if still on cooldown Example:

recordEat()

Record that player just ate.
Parameters:
  • playerId - Player who ate
  • currentTick - Current game tick
Example:

getRemainingCooldown()

Get remaining cooldown ticks.
Parameters:
  • playerId - Player to check
  • currentTick - Current game tick
Returns: 0 if ready to eat, otherwise ticks remaining Example:

clearPlayer()

Clear player’s eat cooldown (on death, disconnect).
Example:

clear()

Clear all state (for testing or server reset).

getTrackedCount()

Get the number of tracked players (for debugging/monitoring).

CombatSystem Extensions

The CombatSystem provides methods for eat delay integration. Location: packages/shared/src/systems/shared/combat/CombatSystem.ts

Methods

isPlayerOnAttackCooldown()

Check if player is on attack cooldown.
Parameters:
  • playerId - Player to check
  • currentTick - Current game tick
Returns: true if player has pending attack cooldown Example:

addAttackDelay()

Add delay ticks to player’s next attack.
Parameters:
  • playerId - Player to modify
  • delayTicks - Ticks to add to attack cooldown
Example:
OSRS-Accurate: Only called when player is ALREADY on cooldown. If weapon is ready, eating does not add delay.

PlayerSystem Extensions

The PlayerSystem handles food consumption. Location: packages/shared/src/systems/shared/character/PlayerSystem.ts

Event Handlers

handleItemUsed()

Handles food consumption with OSRS-accurate timing. Triggered by: ITEM_USED event (emitted by InventorySystem) Validation:
  • Player ID validation (string type check)
  • Eat delay check (3-tick cooldown)
  • Heal amount bounds checking (Math.min(..., MAX_HEAL_AMOUNT))
  • Item type check (consumable/food only)
Flow:
  1. Validate player ID
  2. Check eat delay (reject if on cooldown)
  3. Record eat action
  4. Consume food (emit INVENTORY_REMOVE_ITEM)
  5. Apply healing (emit PLAYER_HEALTH_UPDATED if health changed)
  6. Show OSRS-style message
  7. Apply attack delay if in combat
Example:

Network Protocol

useItem Packet

Client sends useItem packet to consume food. Packet: useItem Payload:
Server Handler: handleUseItem() in packages/server/src/systems/ServerNetwork/handlers/inventory.ts Validation:
  • Rate limiting (3/sec via getConsumeRateLimiter())
  • Payload structure validation
  • Item ID validation (isValidItemId())
  • Slot bounds checking (isValidInventorySlot())
Example:

Constants

Combat Constants

Rate Limiting

Separate from getEquipRateLimiter() to allow OSRS-style PvP gear+eat combos.

Events

INVENTORY_USE

Emitted by server handler when player uses an item. Payload:
Subscribers: InventorySystem

ITEM_USED

Emitted by InventorySystem after validating item exists at slot. Payload:
Subscribers: PlayerSystem

PLAYER_HEALTH_UPDATED

Emitted when player health changes (healing or damage). Payload:
Subscribers: Client UI (StatusBars.tsx)

Security Features

Input Validation

All inputs validated server-side:

Rate Limiting

Consume-After-Check

Food is only removed AFTER all validation passes:

Testing

Unit Tests

EatDelayManager (__tests__/EatDelayManager.test.ts):
  • 197 lines, 16 test cases
  • Boundary conditions (tick 3 exact boundary)
  • Multi-player isolation
  • Cleanup edge cases
  • OSRS timing accuracy
CombatSystem eat delay (__tests__/CombatSystem.eatDelay.test.ts):
  • 236 lines, integration tests
  • Mid-combat eating scenario
  • Weapon-ready eating scenario
  • State consistency (both nextAttackTicks and CombatData updated)

Test Examples