API reference / @jsprismarine/bedrock-data
@jsprismarine/bedrock-data
Minecraft Bedrock game data exported in a nodejs friendly way.
Where the data comes from
src/jsp/is captured from a Bedrock Dedicated Server 1.26.51.1 bypnpm run dump:bedrock. The item table and the three payloads a client refuses to join without live at the top level, the Script API registries undersrc/jsp/bedrock/, the raw engine tables undersrc/jsp/packets/, and the reference world insrc/jsp/reference_world.json.src/resources/is a link to a pinned download of CloudburstMC/Data, the Apache-2.0 dumps of the Bedrock tables.utils/build.jsreads the creative menu, the actor identifiers, and the two item columns the capture does not record: each item's version and its component NBT. See Pinned upstream sources for how to fetch it and how to pick a Bedrock version.src/vendor/is data neither of the two carries, copied from projects that do. See its README for the source and license of each file.src/jsp/java/is dumped from the Java Edition 26.3 server jar, which Mojang ships unobfuscated since 26.1.block_properties.jsonholds the per-state block properties no Mojang report carries (hardness, blast resistance, friction, light, map color, sound type, push reaction, instrument, fire odds and the rest), with state-invariant values once per block and per-state differences understateOverrides.entity_attributes.jsonholds the default attribute values, dimensions and category for the 93 entity types with an attribute supplier. See the next section for how to refresh them.
Refreshing the Java goldens
pnpm run dump:java is a capture-time task, run on a Java version bump rather than as part of the build. It downloads the pinned server jar through the piston-meta manifest chain, verifies its sha1, unpacks the bundler, compiles utils/java-dump/DumpJavaData.java against the server classes, runs it, and rewrites the two files under src/jsp/java/. Everything downloaded stays under node_modules/.cache/jsprismarine/java/.
The pinned version, its sha1 and the manifest URL are constants at the top of utils/java-dump/run.mjs. The dumper needs a JDK matching the jar's class file version (Java 25 for 26.3); the script finds one through JSP_JAVA_HOME, JAVA_HOME or, on macOS, /usr/libexec/java_home. src/javaGoldens.test.ts checks the shape of both files and the counts measured in docs/research/java-code-only-behavior.md; a version bump updates those counts with the goldens.
The root test command and @jsprismarine/worldgen test and vector commands prepare the inner server jar automatically. They download and verify the pinned outer jar, then cache its inner server jar under node_modules/.cache/jsprismarine/java/. This step does not run Java or change captured data. Set JSP_JAVA_SERVER_JAR to use an existing inner jar, or run pnpm --filter @jsprismarine/bedrock-data run ensure:java-server to prepare it separately.
Refreshing the Bedrock captures
pnpm run dump:bedrock is the other half of the same capture-time task, run on a Bedrock version bump and weekly rather than as part of the build. It copies the fetched server into node_modules/.cache/jsprismarine/bds-run/<version>/, makes the binary executable, turns the content log on, and drives four passes over the console, each with a world of its own:
| Pass | What it does | What it writes |
|---|---|---|
dump | Runs the dump behavior pack, which walks every Script API registry | src/jsp/v<protocol>/bedrock/<table>.json |
refworld | Generates the reference region through ticking areas, then reduces the saved world | src/jsp/v<protocol>/reference_world.json |
packets | Logs a client in and records what the server sends it | src/jsp/v<protocol>/*.json, *.nbt, packets/*.bin |
palette | Places every block type, then asks the game which values each property takes | packages/minecraft/datagen/snapshot/v<protocol>/block-palette.json |
Run one pass with --pass, and pass --force to copy the server again:
pnpm run dump:bedrock --pass refworldWhere the capture can run
Mojang publishes the server for Linux x86-64 and Windows, and sources.json pins the Linux zip. On a Linux x86-64 machine dump:bedrock starts that binary directly, which is also what .github/workflows/capture.yml does on its ubuntu-latest runner. On any other host, an Apple Silicon Mac or a Linux arm64 box, it starts the same staged copy inside a Linux x86-64 container instead. You get the same four passes and the same files in the same places; only the thing that executes the binary changes.
The container path needs a container runtime whose daemon is running. The capture tries docker and then podman, and it asks each one for its server version rather than just looking on your PATH, because an installed Docker CLI with Docker Desktop stopped is the common case and it cannot start anything. If neither answers, the capture stops before it stages anything and tells you what to install or start.
Nothing is built or pulled that contains Mojang's binary. The container mounts the run directory under node_modules/.cache/jsprismarine/bds-run/<version>/, which already holds the copy the capture staged from the fetch cache, and runs ./bedrock_server out of the mount. The image is a stock docker.io/library/ubuntu:24.04, chosen because the server is dynamically linked against the glibc and libstdc++ of a recent Ubuntu and because redistributing the server in an image of our own is not something this project does. The server's UDP ports are published on 127.0.0.1 only, for the packets pass's client, and the container is removed when the run ends or when you interrupt it.
On an arm64 host the image is an emulated linux/amd64 one, running under Rosetta or qemu. Expect it to be several times slower than a native run, and refworld, already the longest pass, to be the one you wait on. The capture prints a warning when it starts under emulation, and it multiplies every stage timeout by four so that a slow run reports a stall only when something is genuinely stuck.
Four environment variables steer this, alongside the rest of the pipeline's JSP_* overrides:
| Variable | What it does |
|---|---|
JSP_BDS_RUNNER | auto (the default), native, or container. docker and podman also select container. |
JSP_BDS_CONTAINER_CLI | The CLI to use instead of probing for one, for anything that takes docker run arguments. |
JSP_BDS_CONTAINER_IMAGE | A different base image, if the stock Ubuntu is missing a shared object your server version wants. |
JSP_BDS_PATH | An unpacked server to capture, instead of the fetch cache. Works on either runner. |
Forcing a runner is for diagnosis. JSP_BDS_RUNNER=container on a Linux x86-64 machine is how you reproduce a container-only problem, and JSP_BDS_RUNNER=native makes the capture fail loudly rather than quietly fall back when you expected the host's own CPU to be used.
The reference world
src/jsp/reference_world.json is what packages/parity/ compares a generator against, and utils/bedrock-dump/region.ts is the definition of "the reference region": a fixed seed, the Overworld, and 400 chunks at the world origin. Per chunk the file carries a sha256 of the stored heightmap, of the 3D biome arrays, of the topmost non-air block name per column, and of the layer 0 block states; plus the chunk's sorted block identifiers, its block entity count and its FinalizedState. Sixteen chunks at the origin are also kept whole, as plain arrays, so a failing digest can be read rather than guessed at, and one block histogram covers the region.
The four digests are the four rows Phase 4 of the plan exits on. A generator that produces the same world reproduces every one of them exactly.
Pinned upstream sources
sources.json pins the upstream publications the data pipeline reads: the Bedrock Dedicated Server zip, Mojang/bedrock-samples, the Java Edition server jar, SpyglassMC/vanilla-mcdoc, GeyserMC/mappings and CloudburstMC/Data, each with a version, URL and hash.
pnpm run fetch:sources downloads each source into node_modules/.cache/jsprismarine/<source>/<version>/, verifies its hash before unpacking, and skips sources whose verified content is already cached. It then writes pack-hashes.json, a sha256 per top-level folder of each source, so a version bump shows which folders changed. For offline work, JSP_BDS_PATH, JSP_JAVA_JAR_PATH, JSP_BEDROCK_SAMPLES_PATH, JSP_VANILLA_MCDOC_PATH, JSP_GEYSER_MAPPINGS_PATH and JSP_CLOUDBURST_DATA_PATH point at local copies and bypass the download.
Picking a Bedrock version
CloudburstMC/Data is pinned once per Bedrock protocol version, under versions in sources.json. Each version caches under its own cloudburst-data/v<protocol>/ directory, so several versions' dumps sit side by side.
pnpm run fetch:cloudburst fetches the version in defaultProtocolVersion and links it to src/resources; pnpm run fetch:cloudburst -- --protocol 2225 picks another. pnpm run generate fetches before it builds, so a fresh clone needs no extra step. Only the files under extract are unpacked, LICENSE among them: the dumps are Apache-2.0 and the license travels with them.
Running the Java data generator
pnpm run datagen:java runs Mojang's own data generator against the fetched server jar, after re-checking the jar's sha1 against sources.json. One run produces both halves of the Java data the rest of the repository reads, under the same gitignored cache:
vanilla-datapack/<version>/, the vanilla datapack.@jsprismarine/packsloads it as the Java member of the pack stack, the overworld generator reads itsworldgen/*registries and block tags, and the loot, advancement, predicate, enchantment and feature corpus suites read it.java-reports/<version>/generated/reports/, the data reports. The mapping and item table generators read them, and the overworld generator readsbiome_parametersfrom them.java-structures/<version>/, the 1511 structure templates. The data generator writes no NBT, so these come straight out of the jar;pnpm run extract:structuresdoes that step on its own, for a checkout with no JDK.
The templates matter for speed rather than for correctness. The world generator can read them out of the jar, but that means inflating all 17655 of its entries on the first template a world places, inside chunk generation. The extracted directory is read one file at a time instead.
The generator writes no pack.mcmeta, so this step writes one from the pack_version the jar declares in its version.json; that file is what marks the directory as a loadable datapack. The same version.json names the JDK the jar needs, found through JSP_JAVA_HOME, JAVA_HOME, the java on PATH or, on macOS, /usr/libexec/java_home. The pinned Java Edition 26.3 jar asks for JDK 25 or newer; an older java earlier on PATH is skipped rather than used.
A second run is a no-op once all three directories hold the files the step checks for. Pass --force to regenerate:
pnpm run datagen:java -- --forceThe output is about 53 MB of Mojang's content and is never committed. JSP_VANILLA_DATAPACK and JSP_JAVA_REPORTS point consumers at a copy produced elsewhere.
Doing it in one step
pnpm run ensure:worldgen is the same work arranged for somebody who just wants a server running. It checks the three directories, and only if something is missing does it download the jar and run the generator. pnpm dev at the repository root runs it first, which is what makes pnpm install && pnpm dev enough on a clean clone.
On a complete cache it compares file names and exits, so repeat runs cost a fraction of a second and touch no network. When it cannot finish it prints one line saying why rather than a stack trace: no JDK, no network, or a generator that failed. It asks about the JDK before downloading the jar, so a machine without Java finds out immediately.
pnpm install deliberately does not do this. The jar is a 62 MB download that only somebody running a server needs, and builds, tests and CI arrange their own data.
Installation
To install @jsprismarine/bedrock-data, use the following command:
pnpm install @jsprismarine/bedrock-data --saveInterfaces
BlockDefinitionEntry
Defined in: index.ts:75
A vanilla block the client only knows if the server declares it.
Properties
definition
definition:
Buffer
Defined in: index.ts:78
The definition as network NBT, exactly as a Bedrock Dedicated Server sends it.
name
name:
string
Defined in: index.ts:76
CreativeGroupEntry
Defined in: generated/creativeitems.ts:4
One heading of the creative menu, with the item the client draws beside it.
Properties
category
category:
string
Defined in: generated/creativeitems.ts:8
Which tab the heading sits in: construction, nature, equipment or items.
icon
icon:
string
Defined in: generated/creativeitems.ts:10
The item name shown beside the heading.
icon_block_states?
optionalicon_block_states?:string
Defined in: generated/creativeitems.ts:15
The block state the icon shows, as base64 little-endian NBT whose network_id is the hashed block runtime id vanilla puts on the wire. Absent when the icon is not a block.
name
name:
string
Defined in: generated/creativeitems.ts:6
A translation key such as itemGroup.name.planks.
CreativeItemEntry
Defined in: generated/creativeitems.ts:19
One entry of the creative menu as the client orders it.
Properties
block_states?
optionalblock_states?:string
Defined in: generated/creativeitems.ts:28
The block state the entry places, as base64 little-endian NBT whose network_id is the hashed block runtime id vanilla puts on the wire. Absent when the entry is not a block, which includes the item form of doors, beds and hanging signs.
group
group:
number
Defined in: generated/creativeitems.ts:22
Which of creative_groups the entry is filed under, by index.
meta?
optionalmeta?:number
Defined in: generated/creativeitems.ts:29
name
name:
string
Defined in: generated/creativeitems.ts:20
nbt?
optionalnbt?:string
Defined in: generated/creativeitems.ts:30
ItemTypeEntry
Defined in: index.ts:11
One item as the item table names it.
Properties
component_based
component_based:
boolean
Defined in: index.ts:15
Whether the item is defined by components rather than being one the client already knows.
runtime_id
runtime_id:
number
Defined in: index.ts:13
The numeric id the client will know this name by. Negative for a block's item form.
version
version:
number
Defined in: index.ts:24
Item Version as ItemRegistryPacket carries it: 0 Legacy, 1 DataDriven, 2 None.
A DataDriven item is one the client builds from item_components; a Bedrock Dedicated Server sends 31 vanilla items that way (the bundles, the spears, the trial keys, the apple). Most vanilla items are None, including 44 that are component_based and still travel with an empty compound, such as the arrow, the cake and the music discs.
JavaEntityAttributes
Defined in: index.ts:144
One Java entity type's hitbox and the attributes its class declares.
Properties
attributes
attributes:
Record<string,number>
Defined in: index.ts:152
Java attribute id to its base value, such as minecraft:max_health.
category
category:
string
Defined in: index.ts:146
The MobCategory the class belongs to, such as monster or creature.
height
height:
number
Defined in: index.ts:150
The hitbox height in blocks, which Bedrock writes as minecraft:collision_box.height.
width
width:
number
Defined in: index.ts:148
The hitbox width in blocks, which Bedrock writes as minecraft:collision_box.width.
JavaEntityNavigationEntry
Defined in: index.ts:166
One Java mob's navigation, path costs, and entity-push behavior.
Properties
canFloat
canFloat:
boolean
Defined in: index.ts:170
Whether Java's registered goals enabled floating through liquid.
canNavigateGround
canNavigateGround:
boolean
Defined in: index.ts:172
Whether Java's navigator can follow paths on solid ground.
navigationClass
navigationClass:
string
Defined in: index.ts:168
The Java path-navigation class instantiated for the entity type.
pathfindingMalus
pathfindingMalus:
Record<string,number>
Defined in: index.ts:176
Java's per-PathType route cost, with negative values marking blocked terrain.
pushable
pushable:
boolean
Defined in: index.ts:174
Whether Java lets this living entity push and be pushed by other entities.
Variables
biome_definitions_network
constbiome_definitions_network:Buffer
Defined in: index.ts:138
The vanilla biome definitions, as BiomeDefinitionListPacket carries them at protocol 2193: the whole payload of the packet a Bedrock Dedicated Server 1.26.51.1 sends, replayed verbatim.
At 1.26.x the packet became a map of biome data plus a shared string table the entries index into. An empty one is no longer enough - a client reaches the world-generation screen with no biomes and gives up - so a server that generates any world has to send the real thing.
block_definitions
constblock_definitions: readonlyBlockDefinitionEntry[]
Defined in: index.ts:89
The data driven vanilla blocks, and the definitions a client needs to draw them.
Since 1.26.50 vanilla defines some of its own blocks in data rather than in the client - the wool stairs and slabs, the concrete slabs - and a server has to declare them in StartGamePacket the way it would a plugin's. Captured from the same server as the item table, by the same tool; each definition is handed back to the wire verbatim.
creative_groups
constcreative_groups:CreativeGroupEntry[]
Defined in: generated/creativeitems.ts:46
The headings of the creative menu, in the order the client draws them.
creativeitems
constcreativeitems:CreativeItemEntry[]
Defined in: generated/creativeitems.ts:173
entity_identifiers
constentity_identifiers:Buffer
Defined in: index.ts:121
Every actor type a client may be asked to render, as AvailableActorIdentifiersPacket carries it: one network NBT compound holding an idlist, replayed verbatim.
item_components
constitem_components:Readonly<Record<string,Buffer>>
Defined in: index.ts:63
Item name to its Item Component Data, as network NBT, for every item that has any.
A Bedrock Dedicated Server sends 78 vanilla items with a non-empty compound: the 31 DataDriven entries of item_table, which the client cannot build without one, and 47 foods that are not component_based yet carry their minecraft:food values anyway. Every other item travels with the empty compound, and is absent here.
From the submodule's item_components.nbt, a dump of 1.26.50 at the same protocol as the item table. utils/build.js converts each item's compound from the on-disk NBT flavor to the network one tag by tag, so a server writes the bytes to the wire as they are.
item_table
constitem_table:Record<string,ItemTypeEntry> =item_table_data
Defined in: index.ts:49
The item table: every name the client can be told about, and the number it travels as.
The authority on the mapping - the client builds its registry from what we send, so everything naming an item has to agree with this one file.
Captured from a Bedrock Dedicated Server 1.26.51.1, not taken from a third party: the server sends it as ItemRegistryPacket, so a client that can log in can simply record it. packages/client/tools/capture-server-data.mjs is that client, and its output is jsp/v<protocol>/required_item_list.json. It stays under jsp/ rather than moving to resources/ because a capture of the version this server targets is the thing nothing else can promise.
The capture records no version. utils/build.js takes that one column from the submodule's runtime_item_states.json, a dump of 1.26.50 at the same protocol, and refuses to generate the table unless the two agree on every name, id and component flag. They do.
The version matters more than it looks. Against the 1.21.40 table this has 240 names it did not, and - the part that breaks quietly - 528 items whose number changed. A server on the old table does not fail; it puts the wrong number on the wire for a quarter of the items it knows, and the client shows something else.
item_tags
constitem_tags:Readonly<Record<string, readonlystring[]>> =item_tags_data
Defined in: index.ts:109
Tag name to the items carrying it.
A recipe may ask for "any plank" rather than name the thirteen, and this is the only place that question has an answer. Typed by the question rather than by the file: a caller asks about a tag name a recipe gave it, which is a string and not one of the 77 keys the JSON happens to hold.
java_entity_attributes
constjava_entity_attributes:Record<string,JavaEntityAttributes> =java_entity_attributes_data
Defined in: index.ts:163
Every attribute Java Edition's entity classes declare, by entity type.
2619 values over 93 types, dumped from the pinned unobfuscated 26.3 server jar by utils/java-dump/run.mjs. Bedrock publishes the same stats as entity components, so this is what a cross-edition check compares those components against; the two editions genuinely differ on some of them, which is a finding rather than a defect.
java_entity_navigation
constjava_entity_navigation:Record<string,JavaEntityNavigationEntry> =java_entity_navigation_data
Defined in: index.ts:180
The path navigation Java's mob classes construct, keyed by Java entity identifier.
jigsaw_structure_data
constjigsaw_structure_data:Buffer
Defined in: index.ts:128
The jigsaw structure rules, as JigsawStructureDataPacket carries them: one network NBT compound, the payload of the packet a Bedrock Dedicated Server 1.26.51.1 sent. A client at protocol 2193 refuses to join a server that has not sent this before StartGamePacket.
legacy_item_aliases
constlegacy_item_aliases:Readonly<Record<string,string>> =legacy_item_aliases_data.simple
Defined in: index.ts:68
Legacy Bedrock item identifiers still used by vanilla definitions, mapped to current names.
legacy_item_aux_aliases
constlegacy_item_aux_aliases:Readonly<Record<string,Readonly<Record<string,string>>>> =legacy_item_aliases_data.complex
Defined in: index.ts:71
Legacy Bedrock item identifiers whose auxiliary value selects a current item name.