SoulFire LogoSoulFire
SDK

Cameras and world maps

Capture bot views, stream images, and collect world data for maps.

bot.camera provides images for SDK applications, SoulFireClient, dashboards, and viewers. It uses the server renderer, so it does not need a graphical Minecraft client.

Capture one frame

By default, the camera follows the bot's eyes. Set a position or rotation field to use a free camera. Fields without a value continue to follow the bot.

import { decodeCameraImage } from "@soulfiremc/sdk";

const capture = yield* bot.camera.capture({
  width: 1280,
  height: 720,
  cameraX: 120.5,
  cameraY: 80,
  cameraZ: -32.5,
  yRot: 180,
  xRot: -20,
  fov: 80,
  maxDistance: 256,
  includeHud: false,
  includeHands: false,
  includeDebugTrace: true,
});

const png = decodeCameraImage(capture);

The response includes the effective width, height, FOV, render distance, camera transform, HUD state, and hand state. When debug traces are enabled it also includes renderer timings, cache activity, submitted geometry, visible entities, text samples, notable events, and detailed failures.

Stream frames

Use a frame stream when the consumer needs a live viewport. The server renders only when the transport can accept another message. It skips scheduled frames instead of building an unbounded queue, and the next delivered frame reports the skipped count in droppedBefore or dropped_before.

yield* bot.camera.frames({
  width: 854,
  height: 480,
  intervalMs: 250,
  includeHud: false,
}).pipe(
  Stream.runForEach((frame) =>
    storeFrame(
      frame.sequence,
      frame.droppedBefore,
      decodeCameraImage(frame.render!),
    )
  ),
);

The stream interval is clamped to 100 through 60,000 milliseconds. That limits software rendering to 10 frames per second. A disconnected bot or unavailable world ends the stream with a typed RPC failure.

Sample a top-down world map

World-map snapshots cover loaded client-side terrain around the bot or an explicit center. Each grid column records whether its chunk is loaded. Loaded surface samples can include height, block ID, biome ID, sky light, and block light. Entity overlays are optional.

const map = yield* bot.camera.worldMap({
  centerX: 120,
  centerZ: -32,
  radius: 128,
  sampleStep: 2,
  includeEntities: true,
});

for (const column of map.columns) {
  terrain.set(column.x, column.z, column);
}

The radius is clamped to 256 blocks and the sample step to 1 through 16. Use a larger step for overview maps and step 1 for local inspection. A snapshot also includes the dimension, vertical bounds, game-time revision, and sampling timestamp so consumers can reject stale data.

Required capabilities

Applications can request these capabilities during the SDK handshake:

  • bot.camera.capture.v1
  • bot.camera.stream.v1
  • bot.camera.world-map.v1

All camera and map calls require READ_BOT_INFO for the containing instance.

How is this page?

Last updated on

On this page