NPC Configuration Guide
This guide explains how to configure NPCs (Non-Player Characters) and mobs in Hyperscape using JSON manifests.Table of Contents
- Overview
- Basic NPC Structure
- Combat Configuration
- Attack Types
- Visual Configuration
- Complete Examples
Overview
NPCs in Hyperscape are configured via JSON manifest files. All NPCs are data-driven—you can add new mobs, adjust stats, and configure behaviors without touching code. Manifest Location:packages/server/world/assets/manifests/npcs/
Basic NPC Structure
Required Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (used in code) |
name | string | Display name |
category | string | "mob", "npc", or "boss" |
stats | object | Combat and skill levels |
combat | object | Combat behavior configuration |
appearance | object | Visual model and scale |
Combat Configuration
Combat Object Schema
Combat Fields Reference
| Field | Type | Default | Description |
|---|---|---|---|
attackable | boolean | true | Can players attack this NPC? |
aggressive | boolean | false | Auto-aggro nearby players? |
retaliates | boolean | true | Fight back when attacked? |
aggroRange | number | 4 | Detection range in tiles |
combatRange | number | 1 | Maximum attack range in tiles |
leashRange | number | 42 | Max distance from spawn before returning |
attackSpeedTicks | number | 4 | Ticks between attacks (4 = 2.4s) |
attackType | string | "melee" | "melee", "ranged", or "magic" |
spellId | string | - | Required for magic mobs |
arrowId | string | - | Required for ranged mobs |
respawnTime | number | 30000 | Respawn delay in milliseconds |
xpReward | number | 0 | XP awarded on kill |
Attack Types
Melee (Default)
Close-range combat with 1-2 tile range.- Range: 1 tile (standard) or 2 tiles (halberd)
- No projectile
- Instant hit (0 tick delay)
- Uses
attackandstrengthstats
Ranged
Bow and arrow combat with up to 10 tile range.- Range: Up to 10 tiles (configurable via
combatRange) - Arrow projectile visual
- Hit delay:
1 + floor((3 + distance) / 6)ticks - Uses
rangedstat for damage - Arrow type determines projectile visual
bronze_arrow- Basic arrowsiron_arrow- Improved damagesteel_arrow- Higher damagemithril_arrow- Advanced damageadamant_arrow- High damagerune_arrow- Maximum damage
Magic
Spell casting with up to 10 tile range.- Range: Up to 10 tiles (configurable via
combatRange) - Spell projectile visual (element-based)
- Hit delay:
1 + floor((1 + distance) / 3)ticks - Uses
magicstat for damage - Spell type determines projectile element
wind_strike- Air element (level 1)water_strike- Water element (level 5)earth_strike- Earth element (level 9)fire_strike- Fire element (level 13)wind_bolt- Air element (level 17)water_bolt- Water element (level 23)earth_bolt- Earth element (level 29)fire_bolt- Fire element (level 35)
Visual Configuration
Appearance Object Schema
Appearance Fields
| Field | Type | Description |
|---|---|---|
modelPath | string | Path to VRM/GLB model (relative to assets) |
iconPath | string | Path to icon image |
scale | number | Model scale multiplier (1.0 = normal) |
tint | string | Hex color tint (optional) |
heldWeaponModel | string | Weapon GLB to attach to hand bone |
Held Weapon Models
TheheldWeaponModel field attaches a weapon GLB to the mob’s VRM hand bone:
Format: "asset://weapons/weapon_name.glb"
Supported Weapons:
asset://weapons/bow_shortbow.glb- Shortbowasset://weapons/bow_longbow.glb- Longbowasset://weapons/staff_basic.glb- Basic staffasset://weapons/staff_fire.glb- Fire staffasset://weapons/sword_bronze.glb- Bronze swordasset://weapons/sword_iron.glb- Iron sword
- Weapon GLB is loaded asynchronously
- Cached by URL (shared across mobs of same type)
- Cloned per mob instance
- Attached to VRM
rightHandbone (or bone specified in GLB metadata) - Cleaned up on mob destroy and world teardown
Complete Examples
Example 1: Melee Mob (Goblin)
Example 2: Ranged Mob (Dark Ranger)
Example 3: Magic Mob (Dark Wizard)
Attack Type Configuration
Melee Configuration
Required Fields:attackType:"melee"combatRange:1(standard) or2(halberd)
heldWeaponModel: Visual weapon (sword, axe, etc.)
attack: Hit chancestrength: Damagedefense: Damage reduction
Ranged Configuration
Required Fields:attackType:"ranged"arrowId: Arrow type (e.g.,"bronze_arrow")combatRange: Attack range in tiles (typically 7-10)
heldWeaponModel: Bow model (e.g.,"asset://weapons/bow_shortbow.glb")
ranged: Hit chance and damagedefense: Damage reduction
- Mobs have infinite arrows (no consumption)
- Arrow type affects projectile visual and damage
- Recommended
combatRange: 7 tiles - Recommended
attackSpeedTicks: 4 (2.4 seconds)
Magic Configuration
Required Fields:attackType:"magic"spellId: Spell to cast (e.g.,"wind_strike")combatRange: Attack range in tiles (typically 10)
heldWeaponModel: Staff model (e.g.,"asset://weapons/staff_basic.glb")
magic: Hit chance and damagedefense: Damage reduction
- Mobs have infinite runes (no consumption)
- Spell type determines projectile element (air, water, earth, fire)
- Recommended
combatRange: 10 tiles - Recommended
attackSpeedTicks: 5 (3.0 seconds)
Visual Configuration
Model Path
- Must be a VRM-compatible GLB file
- Must have humanoid skeleton for animations
- Path is relative to assets directory
Held Weapon Models
- Asset Protocol: Use
asset://prefix for all weapon paths - Caching: Weapons are cached by URL and shared across mobs
- Attachment: Attached to VRM
rightHandbone automatically - Metadata: Asset Forge exports include bone and transform data
- Cleanup: Weapons are properly disposed on mob destroy
- First mob loads weapon from network
- Subsequent mobs clone from cache (shared geometry)
- Concurrent loads deduplicated via promise cache
- Cache cleared on world teardown
Scale and Tint
scale: Multiplier for model size (1.0 = normal, 2.0 = double size)tint: Hex color overlay (optional)
Troubleshooting
Mob Not Attacking
Check:attackable: truein combat configaggressive: trueor player attacked firstcombatRangeis appropriate for attack type- For ranged:
arrowIdis specified - For magic:
spellIdis specified
"Mob X has no spellId configured"- AddspellIdto combat config"Mob X has no arrowId configured"- AddarrowIdto combat config
Weapon Not Showing
Check:heldWeaponModelusesasset://prefix- Weapon GLB file exists in assets directory
- Weapon GLB has Asset Forge attachment metadata
- VRM model has
rightHandbone
- Check browser console for GLTF load errors
- Verify weapon path:
asset://weapons/bow_shortbow.glb - Ensure CDN is running (
bun run cdn:up)
Wrong Projectile Visual
For Ranged:- Verify
arrowIdmatches an entry in ammunition data - Check
packages/shared/src/data/ammunition.ts
- Verify
spellIdmatches an entry in spell data - Check
packages/shared/src/data/combat-spells.ts - Spell element determines projectile color:
- Air = cyan/white
- Water = blue
- Earth = brown/green
- Fire = red/orange
Best Practices
Combat Balance
Attack Speed Guidelines:- Fast mobs (3-4 ticks): Low damage, low HP
- Medium mobs (5 ticks): Balanced stats
- Slow mobs (6-7 ticks): High damage, high HP
- Melee:
combatRange: 1(standard) or2(large weapons) - Ranged:
combatRange: 7(typical) to10(maximum) - Magic:
combatRange: 10(standard for spells)
Stat Recommendations
Low-Level Mobs (1-10):NPC Configuration Guide for Hyperscape v3.0