# How `engine.jumpToAction()` Enables Random-Access Navigation in the OpenMAIC Playback Engine

> Discover how engine.jumpToAction() in OpenMAIC enables random-access navigation. Jump to specific actions and resume playback while safely rebuilding visual state.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-09-05

---

**`engine.jumpToAction()` jumps the playback cursor to a specific speech action by index and optionally resumes playback, safely rebuilding the visual state by silently replaying whiteboard actions up to that point.**

The `PlaybackEngine` class in the OpenMAIC repository provides deterministic replay of lecture content through precise cursor control. Understanding how `engine.jumpToAction()` works is essential for implementing "jump to line" features, test-driven navigation, and deterministic replay of specific lecture segments according to the [source code in [`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts).

## Method Signature and Parameters

The method accepts a target action index and an optional configuration object:

```typescript
await engine.jumpToAction(actionIndex: number, options?: { autoplay?: boolean }): Promise<boolean>

```

- **`actionIndex`**: Zero-based index of the target speech action to jump to.
- **`options.autoplay`**: Optional boolean controlling whether playback resumes immediately. If omitted, defaults to the engine's current playing state.
- **Returns**: `true` if the jump succeeds, `false` if validation fails.

## The Eight-Step Execution Process

As implemented in [[`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts), the method executes a precise sequence to ensure safe navigation.

### 1. Validate the Jump Target

The engine first verifies the jump is permissible using `canJumpToAction()`. This helper checks that the engine is not in live mode and that the target stays within the *reconstructable prefix* of speech actions. The safety logic resides in [[`lib/playback/action-navigation.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/action-navigation.ts)](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/action-navigation.ts).

### 2. Determine Autoplay Behavior

If the caller does not specify `autoplay`, the method defaults to `true` when the engine currently sits in **playing** mode, or `false` when paused.

### 3. Invalidate Current Generation

To prevent race conditions with pending asynchronous work, the engine increments an internal `playbackGeneration` counter (see lines 93–95 in [`engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/engine.ts)). Any audio, TTS, or timer operations from previous generations will be ignored.

### 4. Cancel Active Playback

The method calls `cancelActivePlaybackWork()` to immediately stop audio streams, clear browser TTS queues, remove visual effects, and abort pending timers.

### 5. Reset the Cursor

The engine sets `sceneIndex` and `actionIndex` back to the lecture beginning (scene 0, action 0) and clears any saved discussion state, ensuring a clean slate for reconstruction.

### 6. Rebuild Visual State Silently

From the start through `actionIndex - 1`, the engine iterates and executes only *whiteboard* actions via `isWhiteboardPlaybackAction`. This reconstructs the canvas and visual elements without sounding speech audio.

### 7. Update Engine State

After reconstruction, the engine clears lingering effects, updates the internal cursor to the target index, and fires the `onProgress` callback with a snapshot of the new position.

### 8. Handle Autoplay

If `autoplay` is enabled, the engine switches to **playing** mode and invokes `processNext()` to begin audio playback at the target action. If disabled, the engine remains paused with the cursor positioned at the target, ready for manual control.

## Code Examples

### Jump and Play Immediately

```typescript
// Jump to the 5th speech action and start playing
await engine.jumpToAction(5, { autoplay: true });

```

### Jump and Stay Paused

```typescript
// Seek to action 12 for UI scrubbing, remain paused
const success = await engine.jumpToAction(12);
// success === true indicates valid jump; cursor now at action 12

```

### Handle Invalid Jumps

```typescript
// Attempt to jump outside the reconstructable prefix
const ok = await engine.jumpToAction(99);
// Returns false; engine state remains unchanged

```

## Summary

- **`engine.jumpToAction()`** provides random-access navigation to any reconstructable speech action within a lecture.
- The method validates jumps via `canJumpToAction()` and `canJumpWithinReconstructablePrefix` to prevent illegal states.
- It safely reconstructs visual context by silently replaying whiteboard actions up to the target index.
- Generation counters ensure asynchronous operations from previous playback states do not interfere with the new position.
- The function returns a boolean indicating success and respects an optional `autoplay` flag.

## Frequently Asked Questions

### What happens if I jump to an index outside the lecture bounds?

The method returns `false` and leaves the engine state unchanged. The validation logic in `canJumpToAction()` ensures you cannot jump past the reconstructable prefix or beyond available actions.

### Why does the engine reset to the beginning before jumping forward?

Resetting to scene 0 and action 0 ensures visual consistency. The engine rebuilds the whiteboard state deterministically by processing all preceding actions, guaranteeing that animations, drawings, and text appear exactly as they would during sequential playback.

### Can I use `jumpToAction()` while the engine is in live mode?

No. The method explicitly checks for live mode via `canJumpToAction()` and will return `false` if the engine is currently streaming live content. Random-access navigation only works with recorded or reconstructed lectures.

### What is the difference between `jumpToAction()` and simple seek operations?

Unlike simple audio seeking, `jumpToAction()` reconstructs the entire visual state by iterating through whiteboard actions. This ensures the canvas, text, and animations match the speech content at that exact timestamp, providing deterministic replay rather than just audio scrubbing.