> ## Documentation Index
> Fetch the complete documentation index at: https://hyperscape-ai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# shared

> Core 3D engine with ECS, Three.js, PhysX, and networking

## Overview

The `@hyperscape/shared` package is the core Hyperscape engine, providing:

* Entity Component System (ECS)
* Three.js 3D rendering
* PhysX physics simulation
* Real-time networking
* React UI components
* Game data manifests

## Package Location

```
packages/shared/
├── src/
│   ├── components/     # ECS components
│   ├── constants/      # Game constants
│   ├── core/           # Core engine classes
│   ├── data/           # Game manifests (npcs, items, etc.)
│   ├── entities/       # Entity definitions
│   │   ├── player/     # PlayerEntity, PlayerLocal, PlayerRemote
│   │   ├── npc/        # MobEntity, NPCEntity
│   │   ├── world/      # World entities
│   │   └── managers/   # Entity managers
│   ├── extras/         # Additional utilities
│   ├── libs/           # External integrations
│   ├── nodes/          # Scene graph nodes
│   ├── physics/        # PhysX wrapper
│   ├── platform/       # Platform detection
│   ├── runtime/        # Game loop
│   ├── systems/        # ECS systems
│   │   ├── client/     # Client-only systems
│   │   ├── server/     # Server-only systems
│   │   └── shared/     # Shared systems (combat, economy, etc.)
│   ├── types/          # TypeScript types
│   └── utils/          # Helper functions
├── index.ts            # Server exports
└── index.client.ts     # Client exports
```

## Rendering

### WebGPU with WebGL Fallback

The shared package includes renderer factory utilities for creating renderers with automatic fallback:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
// From src/utils/rendering/RendererFactory.ts
import { createRenderer, isWebGPURenderer, getRendererBackend } from '@hyperscape/shared';

// Create renderer (WebGPU preferred, WebGL fallback)
const renderer = await createRenderer({
  antialias: true,
  powerPreference: "high-performance",
});

// Check backend
const isWebGPU = isWebGPURenderer(renderer);  // true or false
const backend = getRendererBackend(renderer); // "webgpu" or "webgl"
```

**Renderer Features:**

* Automatic WebGPU detection and fallback to WebGL
* Works in WKWebView (Tauri), older Safari, and browsers without WebGPU
* Configurable shadow maps and post-processing
* Max anisotropy detection

**Environment System:**

* Auto exposure for day/night cycle (mimics eye adaptation)
* Cascaded shadow maps (WebGPU) or single directional shadows (WebGL)
* Dynamic ambient lighting based on time of day
* Fog color transitions

## Key Exports

### Entity Hierarchy

The entity system follows a clear inheritance pattern:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
// From packages/shared/src/entities/Entity.ts (lines 26-38)
// Entity (base class)
// ├── InteractableEntity (can be interacted with)
// │   ├── ResourceEntity (trees, rocks, fishing spots)
// │   ├── ItemEntity (ground items)
// │   └── NPCEntity (dialogue, shops)
// ├── CombatantEntity (can fight)
// │   ├── PlayerEntity (base player)
// │   │   ├── PlayerLocal (client-side local player)
// │   │   └── PlayerRemote (client-side remote players)
// │   └── MobEntity (enemies)
// └── HeadstoneEntity (player death markers)
```

| Export               | Purpose                                                |
| -------------------- | ------------------------------------------------------ |
| `Entity`             | Base entity class with components, physics, networking |
| `CombatantEntity`    | Combat-capable entities with health, damage            |
| `InteractableEntity` | Objects players can interact with                      |
| `PlayerEntity`       | Server-side player with full stats, inventory          |
| `PlayerLocal`        | Client-side local player with input handling           |
| `PlayerRemote`       | Client-side representation of other players            |
| `MobEntity`          | NPCs and hostile mobs with AI states                   |
| `HeadstoneEntity`    | Death marker for item retrieval                        |

### Systems (Shared)

Located in `src/systems/shared/`:

| Category        | Systems                                            |
| --------------- | -------------------------------------------------- |
| `character/`    | Character stats, equipment, skills, inventory      |
| `combat/`       | Combat mechanics, damage, death, aggro             |
| `death/`        | Death handling, respawn, safe zones                |
| `economy/`      | Banks, shops, trading, loot                        |
| `entities/`     | Entity lifecycle, spawning, resource management    |
| `interaction/`  | Player-world interactions, dialogue, processing    |
| `movement/`     | Tile-based movement, collision, pathfinding        |
| `presentation/` | Visual rendering, particles, music                 |
| `progression/`  | Quest system, achievements                         |
| `tick/`         | Game tick processing, NPC AI                       |
| `world/`        | Terrain generation, flat zones, biomes, vegetation |

### Collision System

The movement system includes a unified collision matrix for OSRS-accurate tile blocking:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
// From packages/shared/src/systems/shared/movement/
export { CollisionMatrix } from './CollisionMatrix';
export { CollisionFlag, CollisionMask } from './CollisionFlags';
export { EntityOccupancyMap } from './EntityOccupancyMap';
export { TileSystem } from './TileSystem';
```

**Key Exports:**

| Export                        | Purpose                                         |
| ----------------------------- | ----------------------------------------------- |
| `CollisionMatrix`             | Zone-based collision storage (8×8 tile zones)   |
| `CollisionFlag`               | Bitmask flags (BLOCKED, WATER, OCCUPIED, walls) |
| `CollisionMask`               | Combined masks (BLOCKS\_WALK, BLOCKS\_MOVEMENT) |
| `EntityOccupancyMap`          | Entity tracking facade over CollisionMatrix     |
| `tilesWithinRangeOfFootprint` | Multi-tile interaction range checks             |

**Usage:**

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
import { CollisionMatrix, CollisionMask } from '@hyperscape/shared';

const collision = new CollisionMatrix();

// Check if tile is walkable
if (!collision.hasFlags(x, z, CollisionMask.BLOCKS_WALK)) {
  // Safe to move
}

// Add blocking for a tree
collision.addFlags(x, z, CollisionFlag.BLOCKED);
```

### Data Manifests

Game content is defined in TypeScript files in `src/data/`:

| File                          | Purpose                                   |
| ----------------------------- | ----------------------------------------- |
| `DataManager.ts`              | Runtime loader for manifests              |
| `npcs.ts`                     | NPC/mob definitions with drops, stats     |
| `items.ts`                    | Item definitions with stats, requirements |
| `world-areas.ts`              | Zone configuration                        |
| `banks-stores.ts`             | Shop inventories and bank locations       |
| `avatars.ts`                  | VRM avatar options                        |
| `playerEmotes.ts`             | Emote animation URLs                      |
| `world-structure.ts`          | World layout and spawn points             |
| `equipment-stats.json`        | Equipment bonuses                         |
| `equipment-requirements.json` | Level requirements                        |

<Info>
  NPC data is loaded from JSON manifests at runtime by DataManager.
  Add new NPCs in `world/assets/manifests/npcs.json`.
</Info>

### Skill Unlocks API

The skill unlocks system provides functions for querying what players unlock at each level:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
import { 
  getAllSkillUnlocks,
  getUnlocksAtLevel,
  getUnlocksUpToLevel,
  loadSkillUnlocks,
  type SkillUnlock
} from '@hyperscape/shared';

// Load from manifest (called by DataManager)
loadSkillUnlocks(manifest);

// Get all unlocks for a skill
const attackUnlocks = getAllSkillUnlocks()["attack"];

// Get unlocks at specific level
const level40Unlocks = getUnlocksAtLevel("attack", 40);
// Returns: [{ level: 40, description: "Rune weapons", type: "item" }]

// Get all unlocks up to level
const unlockedSoFar = getUnlocksUpToLevel("attack", 45);
```

**Defence/Defense Normalization:**

The system automatically handles British/American spelling:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
// skill-unlocks.json uses "defence" (OSRS-accurate)
// UI uses "defense" (codebase convention)
// Both work - normalization happens at load time
const defenceUnlocks = getAllSkillUnlocks()["defence"];  // Works
const defenseUnlocks = getAllSkillUnlocks()["defense"];  // Also works
```

This allows the manifest to use OSRS-accurate British spelling while the codebase uses American spelling consistently.

## Entry Points

### Server (index.ts)

Exports for server-side usage:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
import { 
  Entity, 
  DataManager, 
  PlayerEntity,
  MobEntity 
} from '@hyperscape/shared';
```

### Client (index.client.ts)

Exports for client-side usage:

```typescript theme={"theme":{"light":"github-light","dark":"css-variables"}}
import { 
  Entity, 
  PlayerLocal,
  PlayerRemote 
} from '@hyperscape/shared/client';
```

## Dependencies

| Package                       | Version   | Purpose                     |
| ----------------------------- | --------- | --------------------------- |
| `three`                       | 0.181.0   | 3D rendering                |
| `@pixiv/three-vrm`            | 3.4.3     | VRM avatar support          |
| `@hyperscape/physx-js-webidl` | workspace | Physics                     |
| `react`                       | ^19.2.0   | UI components               |
| `fastify`                     | ^5.0.0    | HTTP server (server builds) |
| `livekit-client`              | ^2.9.9    | Voice chat                  |

## Recent Changes

### Terrain Flattening System (PR #644)

The terrain system now supports flat zones under stations for proper building placement:

* **FlatZone interface** — Defines rectangular flat areas with smooth blending
* **Spatial indexing** — O(1) flat zone lookup using terrain tiles
* **Manifest-driven** — Stations configure `flattenGround`, `flattenPadding`, `flattenBlendRadius`
* **Dynamic registration** — `registerFlatZone()`, `unregisterFlatZone()`, `getFlatZoneAt()`

See [Terrain System](/wiki/game-systems/terrain) for details.

### Equipment System Fixes (PR #641)

Atomic equip/unequip operations prevent item duplication:

* **Transaction locks** prevent race conditions
* **Order of operations** — Remove from inventory FIRST (equip), clear equipment FIRST (unequip)
* **Rollback on failure** — Restores state if operation fails
* **New helper methods** — `hasSpace()`, `hasItemAtSlot()`, `removeItemDirect()`, `addItemDirect()`

## Building

```bash theme={"theme":{"light":"github-light","dark":"css-variables"}}
cd packages/shared
bun run build    # Production build
bun run dev      # Watch mode with auto-rebuild
```

<Info>
  Shared must be built before other packages that depend on it. Turbo handles this automatically.
</Info>

## Key Patterns

### ECS Architecture

All game logic uses Entity Component System. See [ECS Concepts](/concepts/ecs).

### Manifest-Driven Data

Game content defined in `src/data/`. See [Manifests](/concepts/manifests).

### Type Safety

Strong TypeScript typing throughout—**no `any` types allowed**. ESLint enforces this rule.

### Dual Entry Points

* `index.ts`: Server-side exports (includes Fastify, database utilities)
* `index.client.ts`: Client-side exports (browser-compatible)
