voxolith

minecraft-region

Drop a Minecraft .mca region file on the page, crop and downsample it with buildMinecraftRegion, and fly through it with keyboard, mouse, gamepad or touch.

Open the live page · Source

The page starts empty: drop a Minecraft Anvil region file (r.X.Z.mca, from any world's region/ folder) onto it. It crops the middle 256 × 256 blocks of the region, keeps every second one, and lets you fly through it in first person.

No region file is bundled, so until you drop one the canvas stays blank. That is expected; see Troubleshooting.

What it shows

  • buildMinecraftRegion: parse a region, crop it to a box of blocks, downsample it, and get a dense grid, a palette with a slot per block colour, and materials when any block is emissive, metal or glass.
  • A renderer created after startup, once the data exists.
  • First-person controls from the input layer: makeActions for movement by action rather than key, makeLookController (click to capture the mouse, Esc to release, drag, right stick, Q/E and R/F), and makeTouchControls for a joystick and up and down buttons on phones.
  • firstPersonFrame and its yaw convention.

The interesting part

// Free-fly controls, by action rather than by key, so the same loop works on
// a keyboard, a gamepad and a phone. Keys are physical (`code`), so WASD
// stays put on AZERTY.
prepareSurface(canvas);
const input = createInput(canvas);
const actions = makeActions(input, {
  strafe: axis({ negative: ["key:KeyA", "key:ArrowLeft"], positive: ["key:KeyD", "key:ArrowRight"], analog: ["pad:LeftX", "touch:move.x"] }),
  walk: axis({ negative: ["key:KeyS", "key:ArrowDown"], positive: ["key:KeyW", "key:ArrowUp"], analog: ["pad:LeftY-", "touch:move.y-"] }),
  rise: axis({ negative: ["key:KeyC", "pad:LB", "touch:down"], positive: ["key:Space", "pad:RB", "touch:up"] }),
  fast: button("key:ShiftLeft", "key:ShiftRight", "pad:LT"),
});

and the crop, when a file arrives:

// A 256×256 block crop from the middle of the region, every 2nd block.
const scene = await buildMinecraftRegion(new Uint8Array(buf), {
  x0: 128, x1: 383, z0: 128, z1: 383, downsample: 2,
});
const r = await createRenderer(gpu, {
  size: scene.size, data: scene.data, palette: scene.palette, materials: scene.materials,
});

Controls

inputdoes
click, then mouselook (Esc releases the mouse); or drag without capturing
W A S D, arrows, left stick, left joystickmove
Space / C, RB / LB, ▲ / ▼ buttonsup / down
Shift, LTfast
Q E R F, right stickturn

URL options

None besides the common ones.

See also File formats.

On this page