Skip to main content

Constants Reference

Hyperscape uses centralized constants for all game configuration values. This ensures consistency across client and server and makes tuning easier.

Combat Constants

Location: packages/shared/src/constants/CombatConstants.ts
export const COMBAT_CONSTANTS = {
  // Tick timing (OSRS-accurate)
  TICK_DURATION_MS: 600,              // 600ms per tick
  TICKS_PER_SECOND: 1.667,            // ~1.67 ticks per second
  
  // Combat timing
  ATTACK_DELAY_TICKS: 4,              // 4 ticks between attacks (2.4s)
  EAT_DELAY_TICKS: 3,                 // 3 ticks between eating (1.8s)
  
  // Damage calculation
  MAX_HIT_MULTIPLIER: 1.3,            // Strength bonus multiplier
  ACCURACY_MULTIPLIER: 1.5,           // Attack bonus multiplier
  
  // Combat ranges (meters)
  MELEE_RANGE: 1.0,                   // Melee attack range
  RANGED_RANGE: 10.0,                 // Ranged attack range
  AGGRO_RANGE: 5.0,                   // Mob aggro detection range
  
  // Death and respawn
  RESPAWN_DELAY_MS: 3000,             // 3 seconds before respawn
  LOOT_PROTECTION_TICKS: 100,         // 60 seconds loot protection
  
  // Auto-retaliate
  AUTO_RETALIATE_ENABLED: true,       // Default auto-retaliate state
};

Gathering Constants

Location: packages/shared/src/constants/GatheringConstants.ts
export const GATHERING_CONSTANTS = {
  // Timing
  MINIMUM_CYCLE_TICKS: 1,             // Minimum ticks between attempts
  RATE_LIMIT_MS: 600,                 // 600ms between gather requests (1 tick)
  
  // Validation
  MAX_RESOURCE_ID_LENGTH: 128,        // Max resource ID length
  VALID_RESOURCE_ID_PATTERN: /^[a-zA-Z0-9_.-]+$/, // Alphanumeric + _.-
  PROXIMITY_SEARCH_RADIUS: 5.0,       // Meters for nearest resource fallback
  DEFAULT_INTERACTION_RANGE: 10.0,    // Max interaction distance
  POSITION_EPSILON: 0.1,              // Movement detection threshold
  
  // Depletion
  MINING_DEPLETE_CHANCE: 0.125,       // 1/8 chance (12.5%)
  
  // Skill-specific mechanics
  SKILL_MECHANICS: {
    woodcutting: {
      type: "fixed-roll-variable-success",
      baseRollTicks: 4,
      description: "Fixed 4-tick rolls, axe tier affects success rate"
    },
    mining: {
      type: "variable-roll-fixed-success",
      baseRollTicks: 8,
      description: "Tool tier determines roll frequency, success rate is level-only"
    },
    fishing: {
      type: "fixed-roll-fixed-success",
      baseRollTicks: 5,
      description: "Fixed 5-tick rolls, equipment doesn't affect speed or success"
    }
  },
  
  // Success rate tables (OSRS-accurate)
  WOODCUTTING_SUCCESS_RATES: {
    tree_normal: {
      bronze: { low: 40, high: 110 },
      iron: { low: 45, high: 115 },
      steel: { low: 50, high: 120 },
      mithril: { low: 55, high: 125 },
      adamant: { low: 60, high: 130 },
      rune: { low: 65, high: 135 },
      dragon: { low: 70, high: 140 },
    },
    tree_oak: {
      bronze: { low: 20, high: 100 },
      iron: { low: 25, high: 105 },
      steel: { low: 30, high: 110 },
      // ... (more tiers)
    },
    // ... (more tree types)
  },
  
  MINING_SUCCESS_RATES: {
    ore_copper: { low: 40, high: 110 },
    ore_tin: { low: 40, high: 110 },
    ore_iron: { low: 20, high: 90 },
    ore_coal: { low: 30, high: 100 },
    ore_mithril: { low: 20, high: 90 },
    ore_adamantite: { low: 15, high: 85 },
    ore_runite: { low: 10, high: 80 },
  },
  
  // Forestry-style tree timers (ticks)
  TREE_DESPAWN_TICKS: {
    tree: 0,          // Regular trees use chance-based depletion
    oak: 50,          // 30 seconds
    willow: 100,      // 60 seconds
    maple: 200,       // 120 seconds
    yew: 300,         // 180 seconds
    magic: 500,       // 300 seconds
  },
  
  TIMER_REGEN_PER_TICK: 1,            // Ticks regenerated per tick when idle
  
  // Fishing spot movement
  FISHING_SPOT_MOVE: {
    baseTicks: 100,                    // 60 seconds base
    varianceTicks: 50,                 // ±30 seconds variance
  },
};

Smithing Constants

Location: packages/shared/src/constants/SmithingConstants.ts
export const SMITHING_CONSTANTS = {
  // Item IDs
  HAMMER_ITEM_ID: "hammer",
  COAL_ITEM_ID: "coal",
  
  // Tick-based timing
  DEFAULT_SMELTING_TICKS: 4,          // 4 ticks = 2.4s
  DEFAULT_SMITHING_TICKS: 4,          // 4 ticks = 2.4s
  TICK_DURATION_MS: 600,              // 600ms per tick
  
  // Input validation
  MAX_QUANTITY: 10000,
  MIN_QUANTITY: 1,
  MAX_ITEM_ID_LENGTH: 64,
  
  // Messages
  MESSAGES: {
    ALREADY_SMELTING: "You are already smelting.",
    NO_ITEMS: "You have no items.",
    NO_ORES: "You don't have the ores to smelt anything.",
    INVALID_BAR: "Invalid bar type.",
    LEVEL_TOO_LOW_SMELT: "You need level {level} Smithing to smelt that.",
    SMELTING_START: "You begin smelting {item}s.",
    OUT_OF_MATERIALS: "You have run out of materials.",
    SMELT_SUCCESS: "You smelt a {item}.",
    IRON_SMELT_FAIL: "The ore is too impure and you fail to smelt it.",
    
    ALREADY_SMITHING: "You are already smithing.",
    NO_HAMMER: "You need a hammer to work the metal on this anvil.",
    NO_BARS: "You don't have the bars to smith anything.",
    INVALID_RECIPE: "Invalid smithing recipe.",
    LEVEL_TOO_LOW_SMITH: "You need level {level} Smithing to make that.",
    SMITHING_START: "You begin smithing {item}s.",
    OUT_OF_BARS: "You have run out of bars.",
    SMITH_SUCCESS: "You hammer the {metal} and make a {item}.",
  },
};

Banking Constants

Location: packages/shared/src/constants/BankingConstants.ts
export const BANKING_CONSTANTS = {
  // Capacity
  MAX_BANK_SLOTS: 480,                // Slots per bank
  MAX_TABS: 9,                        // 1 main + 8 custom tabs
  
  // Interaction
  INTERACTION_RANGE: 3,               // Max distance to use bank (meters)
  
  // Placeholders
  PLACEHOLDER_ITEM_ID: "placeholder", // Special item ID for placeholders
  
  // Equipment operations
  EQUIPMENT_SLOTS: [
    "head", "cape", "neck", "weapon", "body", "shield",
    "legs", "hands", "feet", "ring", "ammunition"
  ],
};

Interaction Constants

Location: packages/shared/src/constants/interaction.ts
export const CONTEXT_MENU_COLORS = {
  NPC: "#ffff00",      // Yellow - NPCs (shopkeepers, quest givers)
  SCENERY: "#00ffff",  // Cyan - Interactive objects (trees, rocks, anvils)
  ITEM: "#ff9040",     // Orange - Ground items
  PLAYER: "#ffffff",   // White - Other players
  MOB: "#ff0000",      // Red - Hostile mobs (goblins, etc.)
} as const;

export const INTERACTION_DISTANCE: Readonly<Record<SessionType, number>> = {
  STORE: 2,            // 2 tiles
  BANK: 2,             // 2 tiles
  DIALOGUE: 2,         // 2 tiles
};

export const INPUT_LIMITS = {
  MAX_ITEM_ID_LENGTH: 64,
  MAX_STORE_ID_LENGTH: 64,
  MAX_QUANTITY: 2_147_483_647,        // Max signed 32-bit int
  MAX_INVENTORY_SLOTS: 28,
  MAX_BANK_SLOTS: 480,
  MAX_REQUEST_AGE_MS: 5000,           // 5 seconds
  MAX_CLOCK_SKEW_MS: 1000,            // 1 second
};

export const TRANSACTION_RATE_LIMIT_MS = 50; // 50ms = ~20 ops/sec

Equipment Constants

Location: packages/shared/src/constants/EquipmentConstants.ts
export const EQUIPMENT_CONSTANTS = {
  // Slot names
  SLOTS: {
    HEAD: "head",
    CAPE: "cape",
    NECK: "neck",
    WEAPON: "weapon",
    BODY: "body",
    SHIELD: "shield",
    LEGS: "legs",
    HANDS: "hands",
    FEET: "feet",
    RING: "ring",
    AMMUNITION: "ammunition",
  },
  
  // Weapon styles
  WEAPON_STYLES: {
    ACCURATE: "accurate",
    AGGRESSIVE: "aggressive",
    DEFENSIVE: "defensive",
    CONTROLLED: "controlled",
  },
  
  // Attack types
  ATTACK_TYPES: {
    STAB: "stab",
    SLASH: "slash",
    CRUSH: "crush",
    RANGED: "ranged",
    MAGIC: "magic",
  },
};

Game Constants

Location: packages/shared/src/constants/GameConstants.ts
export const GAME_CONSTANTS = {
  // World
  WORLD_SIZE: 1000,                   // World dimensions (meters)
  TILE_SIZE: 1,                       // 1 meter per tile
  
  // Player
  DEFAULT_WALK_SPEED: 2.5,            // Meters per second
  DEFAULT_RUN_SPEED: 5.0,             // Meters per second
  PLAYER_HEIGHT: 1.8,                 // Meters
  PLAYER_RADIUS: 0.3,                 // Collision radius
  
  // Inventory
  INVENTORY_SLOTS: 28,                // OSRS standard
  MAX_STACK_SIZE: 2_147_483_647,      // Max signed 32-bit int
  
  // Currency
  COIN_ITEM_ID: "coins",
  MAX_COINS: 2_147_483_647,           // Max signed 32-bit int
  
  // Loot
  LOOT_DESPAWN_TICKS: 100,            // 60 seconds
  LOOT_PROTECTION_TICKS: 50,          // 30 seconds
  
  // Respawn
  RESPAWN_DELAY_MS: 3000,             // 3 seconds
  RESPAWN_LOCATIONS: [
    { x: 0, y: 0, z: 0 },             // Central spawn
    { x: 100, y: 0, z: 0 },           // Eastern spawn
    { x: -100, y: 0, z: 0 },          // Western spawn
  ],
};