Skip to main content

Prayer System

Hyperscape implements an OSRS-accurate prayer system with combat bonuses, prayer point drain, and altar recharging. Prayers provide temporary combat buffs at the cost of draining prayer points over time.
Prayer code lives in packages/shared/src/systems/shared/character/PrayerSystem.ts with data loaded from manifests/prayers.json.

Core Mechanics

Prayer Points

Prayer points are a resource that drains while prayers are active:
  • Maximum points equals your Prayer level (1-99)
  • Starting points = 1 (at level 1)
  • Drain rate depends on active prayers and prayer bonus from equipment
  • Recharge at altars to restore points to maximum

Prayer Drain Formula

Prayer drain uses the authentic OSRS formula:
Drain Constants:
  • Game tick: 600ms (OSRS standard)
  • Base resistance: 60
  • Prayer bonus multiplier: 2
Prayer bonus comes from equipment (not yet implemented). Higher prayer bonus = slower drain.

Display Points

Prayer points are stored as fractional values for precise drain but displayed as whole numbers:
This matches OSRS behavior where the UI shows the next higher number until truly depleted.

Available Prayers

Prayers are defined in manifests/prayers.json and loaded by PrayerDataProvider.

Defensive Prayers

Offensive Prayers

More prayers can be added by editing manifests/prayers.json without code changes.

Prayer Activation

Requirements

To activate a prayer, you must have:
  1. Sufficient Prayer level (prayer.level >= required level)
  2. Prayer points remaining (points > 0)
  3. No conflicting prayers active
  4. Under max active limit (5 prayers maximum)

Conflict Resolution

Some prayers conflict with each other (e.g., Thick Skin vs Rock Skin). When activating a prayer:
  1. System checks for conflicts via PrayerDataProvider.getConflictsWithActive()
  2. Conflicting prayers are automatically deactivated
  3. New prayer activates
  4. Client receives deactivation events for each conflict

Rate Limiting

Prayer toggles are rate-limited to prevent spam:
  • Cooldown: 100ms between toggles
  • Rate limit: 5 toggles per second maximum
  • Anti-cheat: Exceeding limits flags suspicious behavior

Combat Integration

Prayer Bonuses

Active prayers provide multipliers to combat stats:
Bonus Stacking:
  • Multiple prayers of the same type do NOT stack additively
  • System takes the highest multiplier for each stat
  • Example: Burst of Strength (1.05Γ—) + Superhuman Strength (1.10Γ—) = 1.10Γ— (not 1.15Γ—)

Prayer Depletion

When prayer points reach 0:
  1. All active prayers automatically deactivate
  2. Player receives system message: β€œYou have run out of prayer points.”
  3. Combat bonuses removed immediately
  4. Player must recharge at an altar to use prayers again

Bone Burying

Training Prayer

Prayer XP is gained by burying bones:

Bury Mechanics

Burying bones follows OSRS timing:
  • Delay: 2 ticks (1.2 seconds) between burials
  • Action: Right-click bones in inventory β†’ β€œBury”
  • Animation: 2-tick bury animation
  • XP granted: Immediately on successful bury

Bone Types

Bones are defined in items/resources.json:
Bones are consumed when buried. The bury action routes through the useItem flow for server-side validation.

Altars

Recharging Prayer

Altars restore prayer points to maximum:
  1. Find an altar (purple box in world)
  2. Left-click or right-click β†’ β€œPray Altar”
  3. Points restored to maximum instantly
  4. No cooldown on altar usage

Altar Entities

Altars are InteractableEntity instances with:
  • Type: altar
  • Visual: Purple box (1 tile, 0.8 units tall)
  • Interaction range: 2 tiles
  • Collision: Blocks tile (cannot walk through)
Altars use AltarEntity class in packages/shared/src/entities/world/AltarEntity.ts.

Manifest Structure

prayers.json

Prayers are defined in manifests/prayers.json:

Prayer Definition Fields

Bonus Multipliers

Multipliers must be positive numbers between 0 and 10. Values outside this range are rejected during manifest loading.

Database Schema

Character Table Columns

Prayer state is persisted in the characters table:

Migration

Prayer columns were added in migration 0016_add_prayer_system.sql:
The migration uses IF NOT EXISTS for idempotency - safe to run multiple times.

Network Protocol

Client β†’ Server Packets

Server β†’ Client Packets

Security Features

Input Validation:
  • Prayer ID format: /^[a-z][a-z0-9_]{0,63}$/ (max 64 chars)
  • Timestamp validation prevents replay attacks
  • Rate limiting: 5 toggles/sec, 100ms cooldown
Server-Side Validation:
  • Prayer existence check via PrayerDataProvider
  • Level requirement enforcement
  • Prayer point validation
  • Conflict resolution
  • Bounds checking on all numeric inputs

API Reference

PrayerSystem Methods

PrayerDataProvider Methods


Prayer Events

The prayer system emits events for UI updates and integration:

Client UI

Skills Panel Prayer Tab

The Skills Panel (packages/client/src/game/panels/SkillsPanel.tsx) displays:
  • Prayer points bar with current/max display
  • Prayer cards organized by category (Offensive, Defensive, Utility)
  • Lock indicators for prayers above player’s level
  • Active state with green border and glow
  • Tooltips showing level requirement, effect, and drain rate

Prayer Card States


Implementation Details

System Architecture

Separation of Concerns:
  • PrayerSystem β€” Manages prayer state, drain, activation
  • SkillsSystem β€” Handles prayer XP and leveling
  • CombatSystem β€” Applies prayer bonuses to damage calculations
  • PrayerDataProvider β€” Loads and provides prayer definitions
Event Flow:

Memory Optimization

PrayerSystem uses pre-allocated buffers for hot paths:

Persistence

Prayer state is persisted to the database:
  • Debounced saves: 1 second after state changes
  • Auto-save: Every 30 seconds for dirty states
  • Immediate save: On player disconnect
  • Validation: NaN/undefined values rejected before DB write

Type Guards

Prayer types include comprehensive runtime validation:

Security Constants


Adding New Prayers

Step 1: Edit prayers.json

Add a new prayer definition to manifests/prayers.json:

Step 2: Restart Server

Manifests are loaded at startup:

Step 3: Verify

  1. Open Skills panel β†’ Prayer tab
  2. Check prayer appears in Defensive section
  3. Verify level requirement shows correctly
  4. Test activation/deactivation
  5. Verify conflicts work (activating Steel Skin deactivates Thick Skin/Rock Skin)
No code changes required - the system is fully manifest-driven.

Testing

Prayer system has 62 unit tests covering:
  • Type guard validation (all edge cases)
  • Bounds checking (overflow, underflow, NaN, Infinity)
  • Prayer ID format validation (security)
  • Rate limiting behavior
  • Input validation for all payloads
  • Drain mechanics
  • Conflict resolution
  • Combat bonus calculations