Data Providers
Data providers offer runtime access to game content loaded from JSON manifests. They provide type-safe APIs for querying items, recipes, requirements, and station configurations.
ProcessingDataProvider
Provides access to cooking, firemaking, smelting, and smithing recipes.
Import
import { processingDataProvider } from '@hyperscape/shared';
Initialization
The provider is automatically initialized by DataManager after loading recipe manifests. You can manually rebuild if needed:
// Force rebuild (e.g., after hot-reloading manifests)
processingDataProvider.rebuild();
// Check if initialized
const isReady = processingDataProvider.isReady();
Smelting API
Check if Bar is Smeltable
const canSmelt = processingDataProvider.isSmeltableBar('bronze_bar');
// Returns: true
Get Smelting Data
const data = processingDataProvider.getSmeltingData('bronze_bar');
// Returns: {
// barItemId: 'bronze_bar',
// primaryOre: 'copper_ore',
// secondaryOre: 'tin_ore',
// coalRequired: 0,
// levelRequired: 1,
// xp: 6.25,
// successRate: 1.0,
// ticks: 4
// }
Get Smeltable Bars from Inventory
const inventory = [
{ itemId: 'copper_ore', quantity: 10 },
{ itemId: 'tin_ore', quantity: 10 },
{ itemId: 'iron_ore', quantity: 5 },
{ itemId: 'coal', quantity: 20 }
];
const smithingLevel = 30;
const availableBars = processingDataProvider.getSmeltableBarsFromInventory(
inventory,
smithingLevel
);
// Returns: [bronzeBarData, ironBarData, steelBarData]
Get All Smeltable Bar IDs
const barIds = processingDataProvider.getSmeltableBarIds();
// Returns: Set(['bronze_bar', 'iron_bar', 'steel_bar', ...])
Get Smelting Level/XP
const level = processingDataProvider.getSmeltingLevel('steel_bar');
// Returns: 30
const xp = processingDataProvider.getSmeltingXP('steel_bar');
// Returns: 17.5
const ticks = processingDataProvider.getSmeltingTicks('steel_bar');
// Returns: 4
Smithing API
Check if Item is Smithable
const canSmith = processingDataProvider.isSmithableItem('bronze_sword');
// Returns: true
Get Smithing Recipe
const recipe = processingDataProvider.getSmithingRecipe('bronze_sword');
// Returns: {
// itemId: 'bronze_sword',
// name: 'Bronze Sword',
// barType: 'bronze_bar',
// barsRequired: 1,
// levelRequired: 4,
// xp: 12.5,
// category: 'weapons',
// ticks: 4
// }
Get Recipes for Bar Type
const recipes = processingDataProvider.getSmithingRecipesForBar('bronze_bar');
// Returns: [bronzeDaggerRecipe, bronzeSwordRecipe, bronzePlateBodyRecipe, ...]
Get Smithable Items with Availability
Shows ALL recipes for bar types the player has, with flags for UI display:
const inventory = [
{ itemId: 'bronze_bar', quantity: 10 },
{ itemId: 'iron_bar', quantity: 3 }
];
const smithingLevel = 20;
const available = processingDataProvider.getSmithableItemsWithAvailability(
inventory,
smithingLevel
);
// Returns: [
// { ...bronzeDaggerRecipe, meetsLevel: true, hasBars: true },
// { ...ironPlateBodyRecipe, meetsLevel: false, hasBars: false },
// ...
// ]
Use getSmithableItemsWithAvailability() for UI display to show greyed-out items the player can’t make yet.
Get All Smithing Recipes
const allRecipes = processingDataProvider.getAllSmithingRecipes();
// Returns: Array of all smithing recipes
Get Smithing Level/XP
const level = processingDataProvider.getSmithingLevel('rune_platebody');
// Returns: 99
const xp = processingDataProvider.getSmithingXP('rune_platebody');
// Returns: 375
const ticks = processingDataProvider.getSmithingTicks('rune_platebody');
// Returns: 4
Cooking API
Check if Item is Cookable
const canCook = processingDataProvider.isCookable('raw_shrimp');
// Returns: true
Get Cooking Data
const data = processingDataProvider.getCookingData('raw_shrimp');
// Returns: {
// rawItemId: 'raw_shrimp',
// cookedItemId: 'shrimp',
// burntItemId: 'burnt_shrimp',
// levelRequired: 1,
// xp: 30,
// stopBurnLevel: { fire: 34, range: 34 }
// }
Get Cooked/Burnt Item IDs
const cookedId = processingDataProvider.getCookedItemId('raw_shrimp');
// Returns: 'shrimp'
const burntId = processingDataProvider.getBurntItemId('raw_shrimp');
// Returns: 'burnt_shrimp'
Get Stop Burn Level
const stopBurnFire = processingDataProvider.getStopBurnLevel('raw_shrimp', 'fire');
// Returns: 34
const stopBurnRange = processingDataProvider.getStopBurnLevel('raw_shrimp', 'range');
// Returns: 34
Firemaking API
Check if Log is Burnable
const canBurn = processingDataProvider.isBurnableLog('oak_logs');
// Returns: true
Get Firemaking Data
const data = processingDataProvider.getFiremakingData('oak_logs');
// Returns: {
// logId: 'oak_logs',
// levelRequired: 15,
// xp: 60
// }
Get All Burnable Log IDs
const logIds = processingDataProvider.getBurnableLogIds();
// Returns: Set(['logs', 'oak_logs', 'willow_logs', ...])
TierDataProvider
Provides tier-based level requirements for equipment and tools.
Import
import { TierDataProvider } from '@hyperscape/shared';
Get Requirements for Item
const requirements = TierDataProvider.getRequirements({
id: 'steel_sword',
type: 'weapon',
tier: 'steel',
equipSlot: 'weapon',
attackType: 'MELEE'
});
// Returns: { attack: 5 }
Get Tier Data
const meleeTier = TierDataProvider.getTierData('melee', 'rune');
// Returns: { attack: 40, defence: 40 }
const toolTier = TierDataProvider.getTierData('tools', 'steel');
// Returns: { attack: 5, woodcutting: 6, mining: 6 }
Get Available Tiers
const tiers = TierDataProvider.getAvailableTiers('melee');
// Returns: ['bronze', 'iron', 'steel', 'mithril', 'adamant', 'rune', 'dragon']
Check if Loaded
const isLoaded = TierDataProvider.isLoaded();
// Returns: true if tier-requirements.json was loaded
StationDataProvider
Provides configuration for world stations (anvils, furnaces, ranges, banks).
Import
import { stationDataProvider } from '@hyperscape/shared';
Get Station Data
const anvilData = stationDataProvider.getStationData('anvil');
// Returns: {
// type: 'anvil',
// name: 'Anvil',
// model: 'asset://models/anvil/anvil.glb',
// modelScale: 0.5,
// modelYOffset: 0.4,
// examine: 'An anvil for smithing metal bars into weapons and tools.'
// }
Get Model Path
const modelPath = stationDataProvider.getModelPath('furnace');
// Returns: 'asset://models/furnace/furnace.glb'
Get Model Scale and Offset
const scale = stationDataProvider.getModelScale('anvil');
// Returns: 0.5
const yOffset = stationDataProvider.getModelYOffset('furnace');
// Returns: 1.0
Get Examine Text
const examineText = stationDataProvider.getExamineText('range');
// Returns: 'A range for cooking food.'
Check if Station Exists
const hasStation = stationDataProvider.hasStation('anvil');
// Returns: true
Get All Station Types
const types = stationDataProvider.getAllStationTypes();
// Returns: ['anvil', 'furnace', 'range', 'bank']
Type Definitions
SmeltingItemData
interface SmeltingItemData {
barItemId: string;
primaryOre: string;
secondaryOre: string | null;
coalRequired: number;
levelRequired: number;
xp: number;
successRate: number;
ticks: number;
}
SmithingRecipeData
interface SmithingRecipeData {
itemId: string;
name: string;
barType: string;
barsRequired: number;
levelRequired: number;
xp: number;
category: SmithingCategory;
ticks: number;
}
type SmithingCategory = 'weapons' | 'armor' | 'tools' | 'misc';
SmithingRecipeWithAvailability
interface SmithingRecipeWithAvailability extends SmithingRecipeData {
meetsLevel: boolean; // Player has sufficient level
hasBars: boolean; // Player has enough bars
}
CookingItemData
interface CookingItemData {
rawItemId: string;
cookedItemId: string;
burntItemId: string;
levelRequired: number;
xp: number;
stopBurnLevel: {
fire: number;
range: number;
};
}
FiremakingItemData
interface FiremakingItemData {
logId: string;
levelRequired: number;
xp: number;
}
StationData
interface StationData {
type: string;
name: string;
model: string | null;
modelScale: number;
modelYOffset: number;
examine: string;
}
Pre-allocated Buffers
ProcessingDataProvider uses pre-allocated buffers to avoid allocations in hot paths:
// Internal buffer reused for inventory counting
private readonly inventoryCountBuffer = new Map<string, number>();
This optimization reduces garbage collection pressure when checking smithable/smeltable items.
Lazy Initialization
All providers use lazy initialization - they build lookup tables on first access:
private ensureInitialized(): void {
if (!this.isInitialized) {
this.initialize();
}
}