minestom-map-rendering

Render custom graphics onto in-game maps in Minestom — Framebuffer vs LargeFramebuffer, DirectFramebuffer pixel access, Graphics2DFramebuffer (AWT Graphics2D) for shapes/text, MapColors palette, preparePacket/MapDataPacket, and sending updates to players. Use when drawing images/text/HUDs onto map items, building map displays/screens, or pushing dynamic map graphics.

tjkdev1/minestom-skills5 installsMITSynced Aug 27

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI

Agent Skills format with YAML frontmatter. Claude Code reads it as-is.

---
name: "minestom-map-rendering"
description: "Render custom graphics onto in-game maps in Minestom — Framebuffer vs LargeFramebuffer, DirectFramebuffer pixel access, Graphics2DFramebuffer (AWT Graphics2D) for shapes/text, MapColors palette, preparePacket/MapDataPacket, and sending updates to players. Use when drawing images/text/HUDs onto map items, building map displays/screens, or pushing dynamic map graphics."
license: "MIT"
---

# Minestom map rendering

Maps are 128×128 paletted images. You draw into a **framebuffer**, convert it to a `MapDataPacket`, and send that packet to viewers. A single map is 128×128; a `LargeFramebuffer` spans several maps in a grid.

## Pick a framebuffer

- `DirectFramebuffer` / `LargeDirectFramebuffer` — raw `get(x,y)` / `set(x,y,color)` pixel access against `MapColors`. Fastest; you manage pixels.
- `Graphics2DFramebuffer` / `LargeGraphics2DFramebuffer` — exposes an AWT `Graphics2D` via `getRenderer()`, so you draw shapes/strings/images and it auto-converts RGB → `MapColors`. Slower, far more convenient.

## Direct pixels

```java
import net.minestom.server.map.framebuffers.DirectFramebuffer;
import net.minestom.server.map.MapColors;

DirectFramebuffer fb = new DirectFramebuffer();
for (int x = 0; x < 128; x++)
    for (int y = 0; y < 128; y++)
        fb.set(x, y, MapColors.COLOR_CYAN.baseColor());
```

## Graphics2D (shapes & text)

```java
import net.minestom.server.map.framebuffers.Graphics2DFramebuffer;
import java.awt.Color;

Graphics2DFramebuffer fb = new Graphics2DFramebuffer();
var g = fb.getRenderer();
g.setColor(Color.BLACK);
g.fillRect(0, 0, 128, 128);
g.setColor(Color.WHITE);
g.drawString("Hello", 10, 64);
```

## Send to players

```java
import net.minestom.server.network.packet.server.play.MapDataPacket;

int mapId = 1;
MapDataPacket packet = fb.preparePacket(mapId);
player.sendPacket(packet);
```

Re-call `preparePacket` and resend whenever the framebuffer changes — that's how you animate a map.

## Giving the player the map item

```java
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;

ItemStack mapItem = ItemStack.of(Material.FILLED_MAP)
    .withTag(/* map id component/tag */ ...);
player.getInventory().addItemStack(mapItem);
```

The held `FILLED_MAP` references a map id; the packets you send update that id's pixels. Match the item's map id to the `mapId` you pass to `preparePacket`.

## Large displays

`LargeGraphics2DFramebuffer` lets you draw on a canvas bigger than 128×128; it splits the result across multiple map ids. Prepare and send one packet per sub-map (one per item frame).

## Notes & gotchas

- `MapColors` is a fixed Minecraft palette — Graphics2D buffers dither/quantize to it, so fine gradients band.
- Resolution is capped at 128×128 per map; for HUD-like detail use a grid of item frames + a `LargeFramebuffer`.
- Redraw cost scales with resolution; throttle updates (e.g. via a scheduler tick) instead of every frame.
- See `minestom-schedulers-tasks` for driving animation ticks and `minestom-inventories-items` for the map `ItemStack`.

Sources: https://minestom.net/docs/feature/map-rendering

More General & Other skills

← All General & Other skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY