Skip to main content

Recipe Manifest Documentation

This guide documents the JSON recipe manifest format for all processing skills in Hyperscape.

Overview

Recipe manifests are JSON files that define crafting recipes, cooking data, smelting formulas, and other processing skill data. They enable content creators to add new recipes without modifying code. Location: packages/server/world/assets/manifests/recipes/ Loaded By: DataManagerProcessingDataProvider Validation: All recipes are validated on load with detailed error reporting.

Manifest Files

Cooking Manifest

File: recipes/cooking.json Format:
Fields:
  • raw (string, required): Raw food item ID
  • cooked (string, required): Cooked food item ID
  • burnt (string, required): Burnt food item ID
  • level (integer, required): Cooking level required (1-99)
  • xp (number, required): XP granted per successful cook (> 0)
  • ticks (integer, required): Time in game ticks (600ms per tick, > 0)
  • stopBurnLevel (object, required): Levels at which burning stops
    • fire (integer): Stop-burn level for fires
    • range (integer): Stop-burn level for ranges
Validation:
  • All item IDs must exist in items manifest
  • Level in range [1, 99]
  • XP > 0, ticks > 0
  • stopBurnLevel.fire and stopBurnLevel.range must be integers
Example (lobster):

Firemaking Manifest

File: recipes/firemaking.json Format:
Fields:
  • log (string, required): Log item ID
  • level (integer, required): Firemaking level required (1-99)
  • xp (number, required): XP granted per fire lit (> 0)
  • ticks (integer, required): Time in game ticks (> 0)
Validation:
  • Log item ID must exist in items manifest
  • Level in range [1, 99]
  • XP > 0, ticks > 0
Example (willow logs):

Smelting Manifest

File: recipes/smelting.json Format:
Fields:
  • output (string, required): Bar item ID
  • inputs (array, required): Input materials (non-empty)
    • item (string): Ore or coal item ID
    • amount (integer): Quantity required (>= 1)
  • level (integer, required): Smithing level required (1-99)
  • xp (number, required): XP granted per bar smelted (> 0)
  • ticks (integer, required): Time in game ticks (> 0)
  • successRate (number, required): Success chance (0.0-1.0)
Validation:
  • All item IDs must exist in items manifest
  • Inputs array must be non-empty
  • Input amounts >= 1
  • Level in range [1, 99]
  • XP > 0, ticks > 0
  • successRate in range [0.0, 1.0]
Example (iron bar):
Example (steel bar with coal):

Smithing Manifest

File: recipes/smithing.json Format:
Fields:
  • output (string, required): Output item ID
  • bar (string, required): Bar type required
  • barsRequired (integer, required): Number of bars needed (>= 1)
  • level (integer, required): Smithing level required (1-99)
  • xp (number, required): XP granted per item made (> 0)
  • ticks (integer, required): Time in game ticks (> 0)
  • category (string, required): Category for UI grouping
  • outputQuantity (integer, optional): Items produced per action (default: 1)
Categories: weapons, armor, tools, arrowtips, nails, other Validation:
  • All item IDs must exist in items manifest
  • barsRequired >= 1
  • Level in range [1, 99]
  • XP > 0, ticks > 0
  • outputQuantity >= 1 (if present)
  • Category must be valid
Example (bronze platebody):
Example (bronze arrowtips - multi-output):

Crafting Manifest

File: recipes/crafting.json Format:
Fields:
  • output (string, required): Output item ID
  • category (string, required): Category for UI grouping
  • inputs (array, required): Input materials (non-empty)
    • item (string): Material item ID
    • amount (integer): Quantity required (>= 1)
  • tools (array, required): Tool item IDs (not consumed, can be empty)
  • consumables (array, optional): Consumable items with limited uses
    • item (string): Consumable item ID
    • uses (integer): Uses before consumed (>= 1)
  • level (integer, required): Crafting level required (1-99)
  • xp (number, required): XP granted per item made (> 0)
  • ticks (integer, required): Time in game ticks (> 0)
  • station (string, required): Station required (“none” or “furnace”)
Categories: leather, studded, dragonhide, jewelry, gem_cutting Stations: none, furnace Validation:
  • All item IDs must exist in items manifest
  • Inputs array must be non-empty
  • Input amounts >= 1
  • Tool IDs must be valid (if present)
  • Consumable uses >= 1 (if present)
  • Level in range [1, 99]
  • XP > 0, ticks > 0
  • Station must be “none” or “furnace”
Example (gold necklace at furnace):
Example (gem cutting with chisel):

Fletching Manifest

File: recipes/fletching.json Format:
Fields:
  • output (string, required): Output item ID
  • outputQuantity (integer, optional): Items produced per action (default: 1)
  • category (string, required): Category for UI grouping
  • inputs (array, required): Input materials (non-empty)
    • item (string): Material item ID
    • amount (integer): Quantity required (>= 1)
  • tools (array, optional): Tool item IDs (not consumed, can be empty for no-tool recipes)
  • level (integer, required): Fletching level required (1-99)
  • xp (number, required): XP granted per action (> 0, total for all items)
  • ticks (integer, required): Time in game ticks (> 0)
  • skill (string, required): Must be “fletching”
Categories: arrow_shafts, headless_arrows, shortbows, longbows, stringing, arrows Validation:
  • All item IDs must exist in items manifest
  • Inputs array must be non-empty
  • Input amounts >= 1
  • Tool IDs must be valid (if present)
  • outputQuantity >= 1 (if present)
  • Level in range [1, 99]
  • XP > 0, ticks > 0
  • skill must be “fletching”
Example (shortbow unstrung):
Example (stringing - no tool required):
Example (headless arrows - multi-output):

Runecrafting Manifest

File: recipes/runecrafting.json Format:
Fields:
  • runeType (string, required): Rune type identifier (e.g., “air”, “water”)
  • runeItemId (string, required): Output rune item ID
  • levelRequired (integer, required): Runecrafting level required (1-99)
  • xpPerEssence (number, required): XP granted per essence converted (> 0)
  • essenceTypes (array, required): Valid essence item IDs (non-empty)
  • multiRuneLevels (array, required): Levels granting +1 rune per essence (can be empty)
Validation:
  • All item IDs must exist in items manifest
  • essenceTypes array must be non-empty
  • multiRuneLevels must be an array (can be empty)
  • Level in range [1, 99]
  • XP > 0
Multi-Rune Mechanics:
  • Base: 1 rune per essence
  • Each threshold in multiRuneLevels adds +1 rune per essence
  • Example: At level 22 with thresholds [11, 22, 33], player gets 3 runes per essence
Example (water rune):
Example (law rune - no multi-rune):

Tanning Manifest

File: recipes/tanning.json Format:
Fields:
  • input (string, required): Input hide item ID
  • output (string, required): Output leather item ID
  • cost (integer, required): Coin cost per hide tanned (>= 0)
  • name (string, required): Display name
Validation:
  • All item IDs must exist in items manifest
  • Cost >= 0
Example (green dragonhide):

Recipe ID Generation

Crafting and Smithing

Recipe ID: Output item ID (e.g., "leather_body") Uniqueness: One recipe per output item Lookup:

Fletching

Recipe ID: {output}:{primaryInput} (e.g., "arrow_shaft:logs") Uniqueness: Multiple recipes can share the same output (e.g., arrow shafts from different log types) Lookup:
Why: Allows different recipes for the same output using different inputs.

Runecrafting

Recipe ID: Rune type (e.g., "air", "water") Uniqueness: One recipe per rune type Lookup:

Multi-Output Recipes

Some recipes produce multiple items per action: Fletching:
  • Arrow shafts: 15 per log
  • Headless arrows: 15 per set (15 shafts + 15 feathers)
  • Arrows: 15 per set (15 headless + 15 arrowtips)
Smithing:
  • Arrowtips: 15 per bar
Implementation:
XP Calculation: XP is granted once per action (not per item produced). Example: Fletching 1 log into 15 arrow shafts grants 5 XP total (not 75 XP).

Consumables with Limited Uses

Crafting supports consumables that have multiple uses before being consumed: Example (thread):
Mechanics:
  • Player needs 1 thread in inventory to start crafting
  • Thread is NOT consumed on first craft
  • After 5 crafts, thread is consumed and a new one is required
  • If player runs out of thread mid-session, crafting stops
Implementation:

Station Requirements

Some recipes require specific stations: Crafting Stations:
  • "none" - Can craft anywhere (leather armor, gem cutting)
  • "furnace" - Requires furnace (jewelry)
Example (jewelry at furnace):
Validation: Station must be “none” or “furnace”.

Item-on-Item Interactions

Fletching supports item-on-item interactions where player uses one item on another: Examples:
  • Bowstring + unstrung bow → strung bow
  • Arrowtips + headless arrows → finished arrows
  • Feathers + arrow shafts → headless arrows
Recipe Format (same as regular fletching):
Lookup:

Validation Rules

ProcessingDataProvider validates all recipes on load. Validation errors are logged to console with recipe label for debugging.

Common Validation Errors

Missing Required Field:
Invalid Level:
Invalid XP:
Invalid Ticks:
Item Not Found:
Invalid Input Amount:
Invalid Station:

Validation Process

  1. Load manifest JSON file
  2. For each recipe:
    • Check required fields present
    • Validate field types and ranges
    • Verify all item IDs exist in ITEMS manifest
    • Check input amounts >= 1
    • Validate tool/consumable IDs
    • Verify station is valid
  3. Log all errors with recipe label
  4. Skip invalid recipes (don’t crash)
  5. Build lookup tables from valid recipes
Example Output:

Adding New Recipes

1. Edit Manifest File

Add recipe to appropriate manifest file:

2. Verify Item Exists

Check that all item IDs exist in packages/server/world/assets/manifests/items.json:
Note: Item manifest is the source of truth for item properties. Recipe manifests reference items by ID.

3. Reload Data

Development: Hot-reload automatically picks up manifest changes. Production: Restart server to reload manifests.

4. Test Recipe

Recipe Manifest Best Practices

1. Use OSRS Wiki as Reference

All recipes should match OSRS mechanics:
  • Level requirements
  • XP values
  • Material costs
  • Processing times
Reference: https://oldschool.runescape.wiki

2. Consistent Naming

Use snake_case for all item IDs:
  • bronze_sword, leather_body, arrow_shaft
  • BronzeSword, leatherBody, arrowShaft

3. Logical Grouping

Group related recipes in categories:
  • Smithing: weapons, armor, tools, arrowtips
  • Crafting: leather, studded, dragonhide, jewelry, gem_cutting
  • Fletching: arrow_shafts, headless_arrows, shortbows, longbows, stringing, arrows

4. Validate Before Committing

Run the game and check console for validation errors:

5. Test Edge Cases

Test recipes with:
  • Minimum level requirement
  • Insufficient materials
  • Missing tools
  • Multi-output quantities
  • Consumable depletion

Recipe Manifest Examples

Complete Crafting Recipe (Leather Armor)

Mechanics:
  • Requires needle in inventory (not consumed)
  • Requires thread in inventory (consumed every 5 crafts)
  • Consumes 12 leather per chaps
  • Grants 27 XP per chaps
  • Takes 3 ticks (1.8 seconds) per chaps
  • Can craft anywhere (no station required)

Complete Fletching Recipe (Oak Longbow)

Mechanics:
  • Requires knife in inventory (not consumed)
  • Consumes 1 oak log per bow
  • Produces 1 unstrung oak longbow
  • Grants 25 XP per bow
  • Takes 3 ticks (1.8 seconds) per bow

Complete Runecrafting Recipe (Chaos Rune)

Mechanics:
  • Requires level 35 runecrafting
  • Only accepts pure essence (not rune essence)
  • Grants 8.5 XP per essence converted
  • Produces 1 chaos rune per essence at levels 35-73
  • Produces 2 chaos runes per essence at level 74+
  • Instant conversion (no tick delay)

Complete Smelting Recipe (Mithril Bar)

Mechanics:
  • Requires 1 mithril ore + 4 coal
  • Requires level 50 smithing
  • Grants 30 XP per bar
  • Takes 4 ticks (2.4 seconds) per bar
  • 100% success rate (always succeeds)

Fallback Behavior

If recipe manifests are missing, ProcessingDataProvider falls back to embedded item data: Embedded Data (backwards compatibility):
  • Items with cooking property → cooking recipes
  • Items with firemaking property → firemaking recipes
  • Items with smelting property → smelting recipes
  • Items with smithing property → smithing recipes
Example (item with embedded cooking data):
Migration Path:
  1. Add recipe manifests
  2. ProcessingDataProvider prefers manifests over embedded data
  3. Eventually remove embedded data from items (cleanup)

Manifest Loading Order

  1. DataManager loads all manifests from packages/server/world/assets/manifests/
  2. DataManager calls processingDataProvider.loadXRecipes() for each manifest
  3. ProcessingDataProvider stores raw manifests
  4. ProcessingDataProvider.initialize() builds lookup tables from manifests
  5. Systems access recipes via ProcessingDataProvider methods
Code Flow:

Debugging Recipes

Check Loaded Recipes

Check Specific Recipe

Check Validation Errors

Look for validation errors in console on server startup:

Verify Item IDs

Performance Considerations

Recipe Lookup Performance

ProcessingDataProvider uses Map-based lookups for O(1) access:

Memory Usage

Recipe data is loaded once on startup and cached in memory:
  • ~50 KB for all recipe manifests
  • ~100 KB for lookup tables (Maps, Sets)
  • Total: ~150 KB memory overhead
Optimization: Pre-allocated buffers for inventory counting (avoids allocations in hot paths).

Manifest Size Limits

Recommended:
  • < 100 recipes per manifest
  • < 500 KB per manifest file
Current:
  • Fletching: 37 recipes (~15 KB)
  • Smithing: 45 recipes (~20 KB)
  • Crafting: 28 recipes (~12 KB)

See Also