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: DataManager → ProcessingDataProvider
Validation: All recipes are validated on load with detailed error reporting.
Manifest Files
Cooking Manifest
File:recipes/cooking.json
Format:
raw(string, required): Raw food item IDcooked(string, required): Cooked food item IDburnt(string, required): Burnt food item IDlevel(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 stopsfire(integer): Stop-burn level for firesrange(integer): Stop-burn level for ranges
- 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
Firemaking Manifest
File:recipes/firemaking.json
Format:
log(string, required): Log item IDlevel(integer, required): Firemaking level required (1-99)xp(number, required): XP granted per fire lit (> 0)ticks(integer, required): Time in game ticks (> 0)
- Log item ID must exist in items manifest
- Level in range [1, 99]
- XP > 0, ticks > 0
Smelting Manifest
File:recipes/smelting.json
Format:
output(string, required): Bar item IDinputs(array, required): Input materials (non-empty)item(string): Ore or coal item IDamount(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)
- 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]
Smithing Manifest
File:recipes/smithing.json
Format:
output(string, required): Output item IDbar(string, required): Bar type requiredbarsRequired(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 groupingoutputQuantity(integer, optional): Items produced per action (default: 1)
- 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
Crafting Manifest
File:recipes/crafting.json
Format:
output(string, required): Output item IDcategory(string, required): Category for UI groupinginputs(array, required): Input materials (non-empty)item(string): Material item IDamount(integer): Quantity required (>= 1)
tools(array, required): Tool item IDs (not consumed, can be empty)consumables(array, optional): Consumable items with limited usesitem(string): Consumable item IDuses(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”)
- 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”
Fletching Manifest
File:recipes/fletching.json
Format:
output(string, required): Output item IDoutputQuantity(integer, optional): Items produced per action (default: 1)category(string, required): Category for UI groupinginputs(array, required): Input materials (non-empty)item(string): Material item IDamount(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”
- 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”
Runecrafting Manifest
File:recipes/runecrafting.json
Format:
runeType(string, required): Rune type identifier (e.g., “air”, “water”)runeItemId(string, required): Output rune item IDlevelRequired(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)
- 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
- Base: 1 rune per essence
- Each threshold in
multiRuneLevelsadds +1 rune per essence - Example: At level 22 with thresholds [11, 22, 33], player gets 3 runes per essence
Tanning Manifest
File:recipes/tanning.json
Format:
input(string, required): Input hide item IDoutput(string, required): Output leather item IDcost(integer, required): Coin cost per hide tanned (>= 0)name(string, required): Display name
- All item IDs must exist in items manifest
- Cost >= 0
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:
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)
- Arrowtips: 15 per bar
Consumables with Limited Uses
Crafting supports consumables that have multiple uses before being consumed: Example (thread):- 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
Station Requirements
Some recipes require specific stations: Crafting Stations:"none"- Can craft anywhere (leather armor, gem cutting)"furnace"- Requires furnace (jewelry)
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
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:Validation Process
- Load manifest JSON file
- 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
- Log all errors with recipe label
- Skip invalid recipes (don’t crash)
- Build lookup tables from valid recipes
Adding New Recipes
1. Edit Manifest File
Add recipe to appropriate manifest file:2. Verify Item Exists
Check that all item IDs exist inpackages/server/world/assets/manifests/items.json:
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
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)
- 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)
- 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)
- 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)
- 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
cookingproperty → cooking recipes - Items with
firemakingproperty → firemaking recipes - Items with
smeltingproperty → smelting recipes - Items with
smithingproperty → smithing recipes
- Add recipe manifests
- ProcessingDataProvider prefers manifests over embedded data
- Eventually remove embedded data from items (cleanup)
Manifest Loading Order
- DataManager loads all manifests from
packages/server/world/assets/manifests/ - DataManager calls
processingDataProvider.loadXRecipes()for each manifest - ProcessingDataProvider stores raw manifests
- ProcessingDataProvider.initialize() builds lookup tables from manifests
- Systems access recipes via ProcessingDataProvider methods
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
Manifest Size Limits
Recommended:- < 100 recipes per manifest
- < 500 KB per manifest file
- Fletching: 37 recipes (~15 KB)
- Smithing: 45 recipes (~20 KB)
- Crafting: 28 recipes (~12 KB)
See Also
- SKILLS.md - Skills system overview
- API-REFERENCE.md - API documentation
- DATABASE-MIGRATIONS.md - Migration guide
- CLAUDE.md - Development guidelines