CameraAPI 1.0.0
CameraAPI is a high-level camera control plugin for Minecraft Bedrock (PocketMine-MP 5.x).
It wraps Creator Cameras behind a fluent PHP API and a timeline DSL so you can focus on camera direction instead of packet details.
Origin and Goals
Why?
Using Creator Cameras directly is powerful but painful:
- Low-level packets like
CameraInstructionPacketandCameraPresetsPacketare complex. - Managing camera presets and timelines by hand quickly becomes verbose and error-prone.
CameraAPI aims to:
- Provide a per-player camera session abstraction.
- Offer a fluent builder API for all major camera instructions.
- Expose a timeline DSL + JSON parser for easy cutscene authoring (including by non-programmers).
- Hide protocol details such as experiments, preset IDs, and runtime IDs.
Core Concepts
1. Entry point: Camera
Camera::of(Player $player) : CameraSession
Get or create the camera session for a player.Camera::timeline() : CameraTimeline
Create an empty, code-driven timeline.Camera::loadTimeline(string $json) : CameraTimeline
Build a timeline from a JSON description.Camera::spawnMarker(Location $location, ?string $label = null) : CameraMarker
Spawn an in-world marker to define camera positions and orientations.
2. CameraSession
Per-player camera context and scheduler integration.
-
Builder methods
set() : CameraSetBuilderfade() : CameraFadeBuildertarget() : CameraTargetBuilderfov() : CameraFovBuilderfog() : CameraFogBuilderhud(HudPreset|string $presetOrName) : selfspline() : CameraSplineBuilder(deprecated; may crash clients)
-
Effects / control
shake(float $intensity = 0.5, float $duration = 1.0, int $type = CameraShakePacket::TYPE_POSITIONAL) : selfstopShake(int $type = CameraShakePacket::TYPE_POSITIONAL) : selfcontrolScheme(ClientboundControlSchemeSetPacket $packet) : selfattachToEntity(Entity|int $entityOrRuntimeId) : selfdetachFromEntity() : selfclear() : self
Features Overview
1. Position / Rotation – CameraSetBuilder
$session->set()
->preset("minecraft:free")
->position($pos)
->rotation(30, 90)
->send();- Supports vanilla and custom presets.
- World/local offsets.
- Helpers to face a position or entity.
- Easing for smooth transitions.
2. Screen Fade – CameraFadeBuilder
$session->fade()
->in(0.5)
->stay(1.0)
->out(0.5)
->color(Color::fromRGB(0, 0, 0))
->send();3. Target Tracking – CameraTargetBuilder
$session->target()
->entity($targetEntity)
->offset(new Vector3(0, 1.6, 0))
->send();4. FOV – CameraFovBuilder
$session->fov()
->set(90.0)
->ease(EaseType::IN_CUBIC, 1.0)
->send();5. Fog API (CameraFogBuilder + VanillaFogIds)
Fog is treated as a set of fog IDs for the player. You add or remove fog IDs, and the builder sends the current set in a single PlayerFogPacket.
use kim\present\cameraapi\utils\VanillaFogIds;
// Add fog (e.g. Nether-style atmosphere)
$session->fog()
->push(VanillaFogIds::FOG_HELL)
->send();
// Remove that fog
$session->fog()
->remove(VanillaFogIds::FOG_HELL)
->send();
// Multiple layers (order preserved within the set)
$session->fog()
->push(VanillaFogIds::FOG_CRIMSON_FOREST)
->push(VanillaFogIds::FOG_HELL)
->send();push(string $fogId) : self
Add a fog ID to the current set (useVanillaFogIdsfor vanilla IDs).remove(string $fogId) : self
Remove the given fog ID from the set.send() : CameraSession
Send the current fog set to the client.
VanillaFogIds provides constants for the vanilla fog IDs (FOG_HELL, FOG_CRIMSON_FOREST, FOG_WARPED_FOREST, FOG_THE_END, …).
Note: This is a simplified set-based API – it does not model the full
/fogstack with user-provided IDs. Each fog ID is present at most once in the client-side set managed by this builder.
6. Control Schemes (ControlSchemePackets)
use kim\present\cameraapi\utils\ControlSchemePackets;
$session->controlScheme(ControlSchemePackets::LOCKED_PLAYER_RELATIVE_STRAFE());- Available schemes:
LOCKED_PLAYER_RELATIVE_STRAFECAMERA_RELATIVECAMERA_RELATIVE_STRAFEPLAYER_RELATIVEPLAYER_RELATIVE_STRAFE
- Also available as a timeline instruction via
CameraTimeline::controlScheme().
7. POV Spectator Attach / Detach
$session = Camera::of($player);
// Attach to another player/entity
$session->attachToEntity($targetEntity);
// Or using the runtime ID directly
$session->attachToEntity($targetEntity->getId());
// Detach back to normal view
$session->detachFromEntity();The same operations are exposed on CameraTimeline so you can attach/detach mid-cutscene.
8. Timeline DSL – CameraTimeline
$timeline = Camera::timeline();
$timeline
->fade(fn($b) => $b->in(0.5)->stay(0.5)->out(0.5))
->wait(0.5)
->set(fn($b) => $b->preset("minecraft:free")->position($pos))
->wait(3.0)
->shake(0.6, 1.5)
->wait(1.0)
->clear();
$timeline->play($player);- Supports:
wait,waitUntil,set,fade,target,fov,fog,
controlScheme,attachToEntity,detachFromEntity,shake,stopShake,clear. setLoop(true)to loop the entire sequence.
8.1 JSON Timelines – CameraTimelineParser
$json = file_get_contents($this->getDataFolder() . "cutscenes/boss_intro.json");
$timeline = Camera::loadTimeline($json);
$timeline->play($player);Supported JSON step types (highlights):
-
wait–{ "type": "wait", "seconds": 2.0 } -
waitUntil–{ "type": "waitUntil", "signal": "boss_spawned" } -
shake–{ "type": "shake", "intensity": 0.8, "duration": 1.5 } -
stopShake–{ "type": "stopShake" } -
clear–{ "type": "clear" } -
set– camera position / preset:{ "type": "set", "preset": "minecraft:free", "position": [100, 60, 100], "rotation": [30, 90], "facing": [100, 60, 120], "ease": { "type": 0, "duration": 1.0 } } -
fade– screen fade:{ "type": "fade", "in": 0.5, "stay": 1.0, "out": 0.5 } -
fov– field of view:{ "type": "fov", "set": 90.0, "ease": { "type": 0, "duration": 1.0 } } -
fog– push and/or remove fog IDs (set semantics, per ID):{ "type": "fog", "push": ["minecraft:fog_hell"], "remove": [] }push: array of fog IDs to ensure they are present in the set.remove: array of fog IDs to remove from the set.- Order:
removeis applied first, thenpush.
-
controlScheme– send a control scheme packet:{ "type": "controlScheme", "scheme": "LOCKED_PLAYER_RELATIVE_STRAFE" } -
target– set or clear camera target entity:{ "type": "target", "entityId": 42, "offset": [0, 1.6, 0] }Omit
entityId(or usenull) to clear the target. -
attachToEntity– attach camera to an entity by runtime ID:{ "type": "attachToEntity", "entityId": 42 } -
detachFromEntity– detach camera from the current entity:{ "type": "detachFromEntity" }
8.2 Signal-Based Waiting
waitUntil("boss_spawned")in the timeline.- Later, call
$session->emitSignal("boss_spawned")to resume playback.
9. Camera Presets
CameraPresetRegistry/CameraPresetBuilder(namespacekim\present\cameraapi\camera\preset)- Vanilla presets:
minecraft:first_person,minecraft:fixed_boom,minecraft:follow_orbit,
minecraft:free,minecraft:third_person,minecraft:third_person_front
- Register and synchronize custom presets to clients.
10. HUD Presets
HudPreset,HudPresetBuilder,HudPresetRegistry- Define “HUD layouts” (hide all, minimal HUD, etc.).
- Apply via
HudPreset::send()orCameraSession::hud().
11. Camera Markers
Camera::spawnMarker()spawns a small helper entity to define camera positions.- Offers click/attack callbacks, name tags, and an “interact button”.
CameraMarker::applyToSession()applies marker pose to the camera (with optional easing).
Closing Notes
CameraAPI 1.0.0 is the first public release focusing on:
- Bringing Bedrock Creator Cameras to plugin developers via a clean, fluent API.
- Providing a robust timeline system with both code and JSON definitions.
- Offering practical helpers for fog, control schemes, presets, POV spectator, and HUD layouts.
Future work will focus on:
- Stabilizing and potentially re-enabling spline paths.
- Tracking protocol changes in new Bedrock versions.
- Adding more high-level utilities for complex cinematic scenarios.