> ## Documentation Index
> Fetch the complete documentation index at: https://v5.rpgjs.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Rpg Client Engine

> Reference for the `RpgClientEngine` class.

# Rpg Client Engine

Reference for the `RpgClientEngine` class.

## Members

* [activeRoom](#activeroom)
* [activeRoomSceneComponent](#activeroomscenecomponent)
* [activeSceneKind](#activescenekind)
* [addComponentAnimation](#addcomponentanimation)
* [addEventComponentResolver](#addeventcomponentresolver)
* [addSound](#addsound)
* [addSpriteComponentBehind](#addspritecomponentbehind)
* [addSpriteComponentInFront](#addspritecomponentinfront)
* [cameraFollowRevision](#camerafollowrevision)
* [cameraFollowSmoothMove](#camerafollowsmoothmove)
* [cameraFollowTargetId](#camerafollowtargetid)
* [clear](#clear)
* [clearClientPredictionStates](#clearclientpredictionstates)
* [dashDefaults](#dashdefaults)
* [flash](#flash)
* [getComponentAnimation](#getcomponentanimation)
* [getCurrentRoom](#getcurrentroom)
* [getSound](#getsound)
* [getSoundVolume](#getsoundvolume)
* [getSpriteComponent](#getspritecomponent)
* [getSpriteSheet](#getspritesheet)
* [interactions](#interactions)
* [interruptCurrentPlayerMovement](#interruptcurrentplayermovement)
* [mapShakeTrigger](#mapshaketrigger)
* [music](#music)
* [playClientVisual](#playclientvisual)
* [playSound](#playsound)
* [pointer](#pointer)
* [processAction](#processaction)
* [processDash](#processdash)
* [registerClientVisual](#registerclientvisual)
* [registerClientVisuals](#registerclientvisuals)
* [registerSpriteComponent](#registerspritecomponent)
* [resolveEventComponent](#resolveeventcomponent)
* [sceneRoom](#sceneroom)
* [setCameraFollow](#setcamerafollow)
* [setKeyboardControls](#setkeyboardcontrols)
* [setSoundResolver](#setsoundresolver)
* [setSoundVolume](#setsoundvolume)
* [setSpritesheetResolver](#setspritesheetresolver)
* [startTransition](#starttransition)
* [stopAllSounds](#stopallsounds)
* [stopSound](#stopsound)
* [visualPause](#visualpause)

## activeRoom

Authoritative descriptor of the active room.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
activeRoom
```

## activeRoomSceneComponent

CanvasEngine component selected for a custom gameplay room.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
activeRoomSceneComponent
```

## activeSceneKind

Active room kind; `map` keeps the historical map pipeline enabled.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
activeSceneKind
```

## addComponentAnimation

Add a component animation to the engine

Component animations are temporary visual effects that can be displayed
on sprites or objects, such as hit indicators, spell effects, or status animations.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
addComponentAnimation(componentAnimation: {
    component: any,
    id: string
  })
```

### Parameters

* `componentAnimation`: `{
    component: any,
    id: string
  }`

### Returns

The added component animation configuration

### Examples

```ts theme={null}
// Add a hit animation component
engine.addComponentAnimation({
  id: 'hit',
  component: HitComponent
});

// Add an explosion effect component
engine.addComponentAnimation({
  id: 'explosion',
  component: ExplosionComponent
});
```

## addEventComponentResolver

Register a custom event component resolver.

The last resolver returning a component wins. This lets later modules
override earlier defaults without replacing the whole map scene.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
addEventComponentResolver(resolver: EventComponentResolver)
```

### Parameters

* `resolver`: `EventComponentResolver`

### Returns

The registered resolver

## addSound

Add a sound to the engine

Adds a sound to the engine's sound cache. The sound can be:

* A simple object with `id` and `src` properties
* A Howler instance
* An object with a `play()` method

If the sound has a `src` property, a Howler instance will be created automatically.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
addSound(sound: any, id?: string): any
```

### Parameters

* `sound`: `any`
* `id?`: `string`

### Returns

The added sound

### Examples

```ts theme={null}
// Simple sound object
engine.addSound({ id: 'click', src: 'click.mp3' });

// With explicit ID
engine.addSound({ src: 'music.mp3' }, 'background-music');
```

## addSpriteComponentBehind

Add a component to render behind sprites
Components added with this method will be displayed with a lower z-index than the sprite

Supports multiple formats:

1. Direct component: `ShadowComponent`
2. Configuration object: `{ component: LightHalo, props: {...} }`
3. With dynamic props: `{ component: LightHalo, props: (object) => {...} }`
4. With dependencies: `{ component: HealthBar, dependencies: (object) => [object.hp, object.param.maxHp] }`

Components with dependencies will only be displayed when all dependencies are resolved (!= undefined).
The object (sprite) is passed to the dependencies function to allow sprite-specific dependency resolution.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
addSpriteComponentBehind(component: any)
```

### Parameters

* `component`: `any`

### Returns

The added component or configuration

### Examples

```ts theme={null}
// Add a shadow component behind all sprites
engine.addSpriteComponentBehind(ShadowComponent);

// Add a component with static props
engine.addSpriteComponentBehind({ 
  component: LightHalo, 
  props: { radius: 30 } 
});

// Add a component with dynamic props and dependencies
engine.addSpriteComponentBehind({ 
  component: HealthBar, 
  props: (object) => ({ hp: object.hp(), maxHp: object.param.maxHp() }),
  dependencies: (object) => [object.hp, object.param.maxHp]
});
```

## addSpriteComponentInFront

Add a component to render in front of sprites
Components added with this method will be displayed with a higher z-index than the sprite

Supports multiple formats:

1. Direct component: `HealthBarComponent`
2. Configuration object: `{ component: StatusIndicator, props: {...} }`
3. With dynamic props: `{ component: HealthBar, props: (object) => {...} }`
4. With dependencies: `{ component: HealthBar, dependencies: (object) => [object.hp, object.param.maxHp] }`

Components with dependencies will only be displayed when all dependencies are resolved (!= undefined).
The object (sprite) is passed to the dependencies function to allow sprite-specific dependency resolution.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
addSpriteComponentInFront(component: any | { component: any, props: (object: any) => any, dependencies?: (object: any) => any[] })
```

### Parameters

* `component`: `any | { component: any, props: (object: any) => any, dependencies?: (object: any) => any[] }`

### Returns

The added component or configuration

### Examples

```ts theme={null}
// Add a health bar component in front of all sprites
engine.addSpriteComponentInFront(HealthBarComponent);

// Add a component with static props
engine.addSpriteComponentInFront({ 
  component: StatusIndicator, 
  props: { type: 'poison' } 
});

// Add a component with dynamic props and dependencies
engine.addSpriteComponentInFront({ 
  component: HealthBar, 
  props: (object) => ({ hp: object.hp(), maxHp: object.param.maxHp() }),
  dependencies: (object) => [object.hp, object.param.maxHp]
});
```

## cameraFollowRevision

Incremented for each camera follow command so repeated commands on the same target are applied

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
cameraFollowRevision
```

## cameraFollowSmoothMove

Camera follow transition options used by character components when the target changes

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
cameraFollowSmoothMove: CameraFollowSmoothMove
```

## cameraFollowTargetId

ID of the sprite that the camera should follow. null means follow the current player

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
cameraFollowTargetId
```

## clear

Clear all client resources and reset state

This method should be called to clean up all client-side resources when
shutting down or resetting the client engine. It:

* Destroys the PIXI renderer
* Stops all sounds
* Cleans up subscriptions and event listeners
* Resets scene map
* Stops ping/pong interval
* Clears prediction states

## Design

This method is used primarily in testing environments to ensure clean
state between tests. In production, the client engine typically persists
for the lifetime of the application.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
clear(): void
```

### Examples

```ts theme={null}
// In test cleanup
afterEach(() => {
  clientEngine.clear();
});
```

## clearClientPredictionStates

Clear client prediction states for cleanup

Removes old prediction states and input history to prevent memory leaks.
Should be called when changing maps or disconnecting.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
clearClientPredictionStates()
```

### Examples

```ts theme={null}
// Clear prediction states when changing maps
engine.clearClientPredictionStates();
```

## dashDefaults

Runtime defaults used by modules that specialize the built-in dash.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
dashDefaults: Partial<RpgDashInput>
```

## flash

Trigger a flash animation on a sprite

This method allows you to trigger a flash effect on any sprite from client-side code.
The flash can be configured with various options including type (alpha, tint, or both),
duration, cycles, and color.

## Design

The flash is applied directly to the sprite object using its flash trigger.
This is useful for client-side visual feedback, UI interactions, or local effects
that don't need to be synchronized with the server.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
flash(spriteId?: string, options?: {
      type?: 'alpha' | 'tint' | 'both';
      duration?: number;
      cycles?: number;
      alpha?: number;
      tint?: number | string;
    }): void
```

### Parameters

* `spriteId?`: `string`
* `options?`: `{
      type?: 'alpha' | 'tint' | 'both';
      duration?: number;
      cycles?: number;
      alpha?: number;
      tint?: number | string;
    }`

### Examples

```ts theme={null}
// Flash the current player with default settings
engine.flash();

// Flash a specific sprite with red tint
engine.flash('sprite-id', { type: 'tint', tint: 0xff0000 });

// Flash with both alpha and tint for dramatic effect
engine.flash(undefined, { 
  type: 'both', 
  alpha: 0.5, 
  tint: 0xff0000,
  duration: 200,
  cycles: 2
});

// Quick damage flash on current player
engine.flash(undefined, { 
  type: 'tint', 
  tint: 'red', 
  duration: 150,
  cycles: 1
});
```

## getComponentAnimation

Get a component animation by its ID

Retrieves the EffectManager instance for a specific component animation,
which can be used to display the animation on sprites or objects.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getComponentAnimation(id: string): AnimationManager
```

### Parameters

* `id`: `string`

### Returns

The EffectManager instance for the animation

### Examples

```ts theme={null}
// Get the hit animation and display it
const hitAnimation = engine.getComponentAnimation('hit');
hitAnimation.displayEffect({ text: "Critical!" }, player);
```

## getCurrentRoom

Return the active map scene or synchronized custom gameplay room.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getCurrentRoom(): RpgClientMap | RpgClientRoom
```

## getSound

Get a sound by ID, using resolver if not found in cache

This method first checks if the sound exists in the cache.
If not found and a resolver is set, it calls the resolver to create the sound.
The resolved sound is automatically cached for future use.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getSound(id: string): any | Promise<any>
```

### Parameters

* `id`: `string`

### Returns

The sound if found or created, or undefined if not found and no resolver

### Examples

```ts theme={null}
// Synchronous usage
const sound = engine.getSound('my-sound');

// Asynchronous usage (when resolver returns Promise)
const sound = await engine.getSound('dynamic-sound');
```

## getSoundVolume

Read the persisted volume of one sound channel for the current project.
Calls made inside a CanvasEngine computed value remain reactive.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getSoundVolume(channel: RpgAudioChannel): number
```

### Parameters

* `channel`: `RpgAudioChannel`

### Returns

Volume between 0 and 1.

### Examples

```ts theme={null}
const musicVolume = engine.getSoundVolume('music')
```

## getSpriteComponent

Get a reusable sprite component by id.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getSpriteComponent(id: string)
```

### Parameters

* `id`: `string`

### Returns

The CanvasEngine component, or undefined when missing

## getSpriteSheet

Get a spritesheet by ID, using resolver if not found in cache

This method first checks if the spritesheet exists in the cache.
If not found and a resolver is set, it calls the resolver to create the spritesheet.
The resolved spritesheet is automatically cached for future use.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
getSpriteSheet(id: string | number): any | Promise<any>
```

### Parameters

* `id`: `string | number`

### Returns

The spritesheet if found or created, or undefined if not found and no resolver

### Examples

```ts theme={null}
// Synchronous usage
const spritesheet = engine.getSpriteSheet('my-sprite');

// Asynchronous usage (when resolver returns Promise)
const spritesheet = await engine.getSpriteSheet('dynamic-sprite');
```

## interactions

Register client-only pointer behaviors for map sprites. Interactions remain
local unless a behavior explicitly sends an action to the server.

See the [client interactions guide](../../guide/interactions.md) for hover,
selection, hit testing, drag-and-drop, overlays, and network rules.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
interactions: RpgClientInteractions
```

### Examples

```ts theme={null}
engine.interactions.use('Guard', {
  cursor: 'pointer',
  click(ctx) {
    ctx.action('guard:talk', { eventId: ctx.target.id })
  }
})
```

## interruptCurrentPlayerMovement

Stop local movement immediately and discard pending predicted movement.

Use this before a blocking action such as an A-RPG attack, dialog, dash
startup, or any client-side state where already buffered movement inputs
must not be replayed after server reconciliation.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
interruptCurrentPlayerMovement(player?: any): boolean
```

### Parameters

* `player?`: `any`

### Returns

`true` when a player was found and interrupted.

### Examples

```ts theme={null}
engine.interruptCurrentPlayerMovement();
```

## mapShakeTrigger

Trigger for map shake animation

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
mapShakeTrigger: ConfigurableTrigger<MapShakeOptions>
```

## music

Client-only controller for temporary looping music and map BGM crossfades.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
music
```

## playClientVisual

Play a registered client visual locally.

This is also used by the websocket listener when the server calls
`player.clientVisual()` or `map.clientVisual()`.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
playClientVisual(packet: ClientVisualPacket)
```

### Parameters

* `packet`: `ClientVisualPacket`

## playSound

Play a sound by its ID

This method retrieves a sound from the cache or resolver and plays it.
If the sound is not found, it will attempt to resolve it using the soundResolver.
Uses Howler.js for audio playback instead of native Audio elements.

The existing API remains the single entry point for ordinary, channel-aware,
and spatial sounds. Playback is client-owned in both standalone and MMORPG
games; server calls only ask the receiving client to play a registered ID.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
playSound(soundId: string, options?: RpgPlaySoundOptions): Promise<void>
```

### Parameters

* `soundId`: `string`
* `options?`: `RpgPlaySoundOptions`

### Returns

Resolves after the sound has been resolved and started when available.

### Examples

```ts theme={null}
// Play a sound synchronously
engine.playSound('item-pickup');

// Play a sound with volume and loop
engine.playSound('background-music', { volume: 0.5, loop: true });

// Play a sound asynchronously (when resolver returns Promise)
await engine.playSound('dynamic-sound', { volume: 0.8 });

// Play a spatial sound without exposing CanvasEngine signals
await engine.playSound('enemy-hit', {
  channel: 'sfx',
  position: { x: enemy.x(), y: enemy.y() },
  listener: { x: player.x(), y: player.y() },
});
```

## pointer

Read the latest pointer position tracked by the client canvas. World
coordinates are suitable for action payloads and map interactions.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
pointer: ClientPointerContext
```

### Examples

```ts theme={null}
const target = engine.pointer.world()
if (target) engine.processAction('projectile:shoot', { target })
```

## processAction

Send an action intent to the authoritative server. Client-provided data
must be validated by the receiving player input handler or action.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
processAction(action: RpgActionName | RpgActionInput, data?: any): void
```

### Parameters

* `action`: `RpgActionName`
* `data?`: `any`

### Returns

Nothing.

### Examples

```ts theme={null}
engine.processAction('projectile:shoot', {
  target: engine.pointer.world(),
  source: 'map-click',
})
```

## processDash

Start a predicted dash for the current player and send it through the
authoritative movement channel.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
processDash(input?: Partial<RpgDashInput>): Promise<void>
```

### Parameters

* `input?`: `Partial<RpgDashInput>`

### Returns

A promise resolved after the dash input has been processed locally.

### Examples

```ts theme={null}
await engine.processDash({
  direction: { x: 1, y: 0 },
  additionalSpeed: 10,
  duration: 220,
  cooldown: 600,
})
```

## registerClientVisual

Register a named client visual macro.

Client visuals are small client-side functions that group existing visual
primitives such as flash, sound, component animations, sprite animation, or
map shake. The server sends only the visual name and a serializable payload.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
registerClientVisual(name: string, handler: ClientVisualHandler)
```

### Parameters

* `name`: `string`
* `handler`: `ClientVisualHandler`

### Returns

The registered handler

## registerClientVisuals

Register several named client visual macros.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
registerClientVisuals(visuals: ClientVisualMap)
```

### Parameters

* `visuals`: `ClientVisualMap`

## registerSpriteComponent

Register a reusable sprite component that can be addressed by the server.

Server-side component definitions only carry the component id and
serializable props. The client registry maps that id to the CanvasEngine
component that performs the actual rendering.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
registerSpriteComponent(id: string, component: any)
```

### Parameters

* `id`: `string`
* `component`: `any`

### Returns

The registered component

### Examples

```ts theme={null}
engine.registerSpriteComponent('guildBadge', GuildBadgeComponent);
```

## resolveEventComponent

Resolve the custom CanvasEngine component for an event, if any.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
resolveEventComponent(event: RpgClientEvent): EventComponentConfig | null
```

### Parameters

* `event`: `RpgClientEvent`

### Returns

The component/config returned by the last matching resolver

## sceneRoom

Synchronized state for the active non-map gameplay room.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
sceneRoom
```

## setCameraFollow

Set the camera to follow a specific sprite

This method changes which sprite the camera viewport should follow.
The camera can smoothly animate to the target sprite before continuous follow starts.

## Design

The camera follow target is stored in a signal that is read by sprite components.
Each sprite checks if it should be followed by comparing its ID with the target ID.
When smoothMove options are provided, the transition is handled by pixi-viewport's
animation plugin, then continuous follow is handled by CanvasEngine's viewport system.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
setCameraFollow(targetId: string | null, smoothMove?: CameraFollowSmoothMove): void
```

### Parameters

* `targetId`: `string | null`
* `smoothMove?`: `CameraFollowSmoothMove`

### Examples

```ts theme={null}
// Follow another player with default smooth animation
engine.setCameraFollow(otherPlayerId, true);

// Follow an event with custom smooth animation
engine.setCameraFollow(eventId, {
  time: 1000,
  ease: "easeInOutQuad"
});

// Follow without animation (instant)
engine.setCameraFollow(targetId, false);

// Return to following current player
engine.setCameraFollow(null);
```

## setKeyboardControls

Registers the current player's live CanvasEngine controls on the client.

Used automatically when the player component mounts in standalone RPG and
MMORPG modes. Destroyed directives are ignored so a retiring component cannot
overwrite replacement controls during streamed map updates. Input handling
remains client-side; this does not change server movement authority.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
setKeyboardControls
```

### Parameters

* `controlInstance`: `ControlsDirective`

### Returns

Nothing.

### Examples

```ts theme={null}
// Inside the current player's CanvasEngine mount callback:
client.setKeyboardControls(element.directives.controls)
```

## setSoundResolver

Set a resolver function for sounds

The resolver is called when a sound is requested but not found in the cache.
It can be synchronous (returns directly) or asynchronous (returns a Promise).
The resolved sound is automatically cached for future use.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
setSoundResolver(resolver: (id: string) => any | Promise<any>): void
```

### Parameters

* `resolver`: `(id: string) => any | Promise<any>`

### Examples

```ts theme={null}
// Synchronous resolver
engine.setSoundResolver((id) => {
  if (id === 'dynamic-sound') {
    return { id: 'dynamic-sound', src: 'path/to/sound.mp3' };
  }
  return undefined;
});

// Asynchronous resolver (loading from API)
engine.setSoundResolver(async (id) => {
  const response = await fetch(`/api/sounds/${id}`);
  const data = await response.json();
  return data;
});
```

## setSoundVolume

Set the persisted volume of one sound channel for the current project.
Master volume is applied through Howler, including sounds controlled through
the legacy `RpgSound.global` facade. This client-owned preference behaves the
same in standalone and MMORPG games and never changes server state.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Member of: `RpgClientEngine`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
setSoundVolume(channel: RpgAudioChannel, value: number): void
```

### Parameters

* `channel`: `RpgAudioChannel`
* `value`: `number`

### Examples

```ts theme={null}
engine.setSoundVolume('music', 0.6)
engine.setSoundVolume('master', 0.8)
```

## setSpritesheetResolver

Set a resolver function for spritesheets

The resolver is called when a spritesheet is requested but not found in the cache.
It can be synchronous (returns directly) or asynchronous (returns a Promise).
The resolved spritesheet is automatically cached for future use.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
setSpritesheetResolver(resolver: (id: string | number) => any | Promise<any>): void
```

### Parameters

* `resolver`: `(id: string | number) => any | Promise<any>`

### Examples

```ts theme={null}
// Synchronous resolver
engine.setSpritesheetResolver((id) => {
  if (id === 'dynamic-sprite') {
    return { id: 'dynamic-sprite', image: 'path/to/image.png', framesWidth: 32, framesHeight: 32 };
  }
  return undefined;
});

// Asynchronous resolver (loading from API)
engine.setSpritesheetResolver(async (id) => {
  const response = await fetch(`/api/spritesheets/${id}`);
  const data = await response.json();
  return data;
});
```

## startTransition

Start a transition

Convenience method to display a transition by its ID using the GUI system.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
startTransition(id: string, props?: any): Promise<void>
```

### Parameters

* `id`: `string`
* `props?`: `any`

### Examples

```ts theme={null}
// Start a fade transition
engine.startTransition('fade', { duration: 1000, color: 'black' });

// Start with onFinish callback
engine.startTransition('fade', {
  duration: 1000,
  onFinish: () => console.log('Fade complete')
});

// Wait until the transition component calls onFinish
await engine.startTransition('fade', { duration: 1000 });
```

## stopAllSounds

Stop all currently playing sounds

This method stops all sounds that are currently playing.
Useful when changing maps to prevent sound overlap.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
stopAllSounds(): void
```

### Examples

```ts theme={null}
// Stop all sounds
engine.stopAllSounds();
```

## stopSound

Stop a sound that is currently playing

This method stops a sound that was previously started with `playSound()`.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `method`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
stopSound(soundId: string): void
```

### Parameters

* `soundId`: `string`

### Examples

```ts theme={null}
// Start a looping sound
engine.playSound('background-music', { loop: true });

// Later, stop it
engine.stopSound('background-music');
```

## visualPause

Freezes map rendering for short presentation-only beats such as combat
hit-stop. It is deliberately separate from menu/gameplay pause ownership.

* Source: `packages/client/src/RpgClientEngine.ts`
* Kind: `property`
* Defined in: `RpgClientEngine`

### Signature

```ts theme={null}
visualPause
```
