Capability domains¶
The capability domains are split into ten pages.
| Page | Content |
|---|---|
| DebugShape (holograms & shapes) | Shapes · holograms · gradient lines |
| Item display | FMBE · item detail · stretch / live transforms / presets |
| Particles | Particle shapes |
| Entities & interaction | Custom entities · ghost interaction · actor interaction events |
| Fake-player NPC | NPCs · skins / image plane · pose / equipment / ride · interaction |
| Containers & inventory | Virtual containers · fake inventory · session isolation |
| Interfaces | Trade menu · NPC dialogue |
| Sulfur cube | Sulfur-cube display |
| View override | Client view override · per-viewer rendering |
| Client sensing | Input-device sensing |
Every page in this set now has an English version, including the four group guides. The selection tables below are the fastest way to pick a domain, and the API references cover the signatures.
Choosing: I want to show something at a position¶
Six different ways exist to put something into the world, with different looks, costs and capabilities. Start here:
| I want to show | Domain | Look | Cost |
|---|---|---|---|
| Wireframes, geometry, a piece of text | Shapes IShapeDrawer (the text branch) |
Glowing debug lines / text | Client-side in-memory shapes, no entity, zero server cost |
| A multi-line information board | Holographic text IHologramText |
A text block that always faces the camera (can be turned off) | Same as above; really just "one multi-line text shape" |
| A coloured trail | Gradient lines gradient* (LSE only) |
Multi-colour gradient segments | A batch of line shapes |
| An item icon | FMBE item display IItemDisplay |
A fox holding an item (or a beacon form) | Fake entity (partly invisible, visible only to the target) + packets |
| A block, being swallowed | Sulfur-cube display ISulfurDisplay |
The block floats there; the cube is invisible by default | Fully delegates to ICustomEntity; appearance tiers via ChangeMobProperty |
| A vanilla mob / entity | Custom entities ICustomEntity |
A real entity look: poses, equipment, animations, riding | Protocol-level entity (no AI); no server-side counterpart |
| A humanoid (player model) | Fake-player NPCs IPlayerNpc |
A player model with registerable / capturable / injectable skins | Pure-protocol fake player; skins travel via PlayerList |
| Making an existing mob look different | Client view override IViewOverride (EntityView::skinId) |
Swapped to your model, id unchanged | Client view only; the server still sees the original mob |
Change the client's view, or create something new¶
This is the easiest choice to get wrong:
- Create something new (custom entities / fake-player NPCs / sulfur cube / FMBE item display). The server has no real entity behind it. Players can see it but cannot interact with entity logic.
- Change an existing thing's client view (
IViewOverride). No new entity is created; only the packets this one player receives are changed. The entity is still that same real server-side entity, so clicking it, hitting it and aiming at it all hit the real thing. Damage, drops and what other plugins see are all the original. The trade-off is that details which only ever arrived with the spawn packet (variant, initial equipment) wait for the server's next sync.
The right way to "give a mob a custom model" is
EntityView::skinId(since26.40.9), not the older "invisible real entity + per-tick following + ghost-forwarded attacks" approach, which forces you to handle visibility decisions, following and attack forwarding yourself.
Choosing: I want an interface the player can interact with¶
| Need | Domain | Why |
|---|---|---|
| A list UI where clicking an entry fires a callback, on any input device | Virtual container IContainerMenu |
A click is an item pickup, so touch players send packets too; 27 or 54 slots |
| Show a villager trade table | Trade menu ITradeMenu |
Protocol-level UpdateTrade, byte-identical to captured BDS packets |
| Trades that actually charge and deliver | ITradeMenu + settleLocally, or usePacketOffers=false |
The former settles in the library, the latter hands settlement to BDS (recommended) |
| Multi-level dialogue / NPC story with buttons | NPC dialogue INpcDialogue |
NpcDialoguePacket + synthetic carrier; levels routed by scene name |
| Make the client believe it is carrying certain items | Fake inventory IFakeInventory |
Rewrites the client's view of the inventory; the real inventory is untouched |
| Detect the player's input device and route accordingly | Player sensing IPlayerSensing |
Per-packet InputMode: touch / gamepad / keyboard-mouse |
The shared boundary: these "virtual interfaces" do not exist on the server. When a player interacts, the server-side slot does not match, so BDS rejects it and the client rolls back its prediction. The library deliberately does not answer with a failure response on the server's behalf. Doing so makes the client pop up an error, whereas letting BDS walk its own failure path is silent.
Choosing: particles and transient effects¶
| Need | Domain |
|---|---|
| Points, lines, rectangular rings, filled planes, box frames, six-faced shapes, polyhedra | Particle shapes IParticleShape |
| A whole plane sliding smoothly with an anchor, rotating, spinning, following | Same: moveTo / rotation / setFollowPlayer |
| Visible to only some players | Same: setVisiblePlayers whitelist (empty = everyone in the dimension) |
| Per-client sounds, short-lived floating text | Not available. Removed wholesale in 26.40.3 |
Particles are sent through the vanilla SpawnParticleEffectPacket batch channel, and BDS's tick flush aggregates them into a single Batch datagram.
Cross-domain dependencies¶
Almost all domains are independent. Only these relationships matter:
| Domain | Relationship |
|---|---|
Sulfur cube sulfur |
Fully delegates to ICustomEntity: scale / view distance / whitelist / per-viewer rotation are inherited. Its only new protocol content is ChangeMobProperty |
Holographic text holo |
Reuses the shape domain and never writes protocol packets directly (a hologram is a multi-line text shape) |
Gradient lines gradient (LSE) |
Also builds its own batch of line segments through the shape domain |
| Per-viewer appearance / text variables | Per-viewer overrides on ICustomEntity / IHologramText, not standalone domains |
| Container / fake inventory | Share one item-request hook (src/interaction/PlayerInteractionHooks.cpp) and are told apart by container id |
| View override | Reads the IPlayerNpc skin registry when it needs a skin (registerSkin / captureSkin / registerSkinFromBlob) |
Minimum version per domain¶
Use these values when writing static_assert gates:
| Version | Added |
|---|---|
0x010900 · 1.9.0 |
Early domains: IShapeDrawer / IHologramText / IItemDetail |
0x011500 · 1.15.0 |
IParticleShape |
0x011900 · 1.19.0 |
Skin export from memory / directory import, geometryData custom models, NPC scaling |
0x011A00 · 1.20.0 |
26.40 adaptation; per-viewer rotation |
0x011B00 · 1.21.0 |
ITradeMenu / INpcDialogue / IContainerMenu / IPlayerSensing + per-viewer rendering |
0x011C00 · 1.22.0 |
Trade menu became display-only; four domains gained LSE exports |
0x011D00 · 1.23.0 |
IFakeInventory / ISulfurDisplay |
0x011E00 · 1.24.0 |
Trade menu: protocol-only settlement |
0x011F00 · 1.25.0 |
IViewOverride |
0x012000 · 1.26.0 |
View-override cleanup; five new IPlayerNpc methods; holographic-text shrink and completion |
0x012100 · 1.27.0 |
EntityView::skinId; real-entity interaction listeners; ABI layout stamp |
0x012300 · 1.29.0 |
AddItemActor interception; EntityView gains pose / scale / variant / colour |
26.51.5 |
1.31.0 |
26.51.4 |
1.30.0 |
⚠
0x012200(= API 1.28.0) is not in the table. That number was skipped and never shipped as a release. See the version & ABI matrix.