terrain-gate

Decides whether a 128x128 Minecraft map tile is vanilla terrain or something a player made. It is stage 1 of mapart-nsfw-detector: a cheap, high-recall filter that keeps an expensive content model from ever looking at auto-generated world maps.

It does not decide whether an image is safe. Terrain versus not-terrain is the whole question it answers. Treating its score as an NSFW score would be a category error.

What it is

Gradient boosting over 18 hand-built features, exported to ONNX. 311 KB, CPU only, with no GPU path and none needed.

Property Value
Input one 128x128 RGBA tile, native map resolution, never resized
Output p(not terrain)
Threshold 0.0376, shipped in terrain_gate.meta.json
Latency 2.23 ms/tile, one CPU thread
AUC 0.9993, grouped 5-fold CV over 5 seeds

The features are palette statistics rather than pixels: colour-transition rates, run lengths, entropy, and the group that earns its keep, which is how a tile steps between shades of one base colour versus between different base colours. Minecraft derives a pixel's shade from the height difference with the block to its north, so vanilla terrain steps within a colour as the ground rises, while a player dithering with wool steps across colours. Badlands and orange wool share exact RGB values, and nothing else separates them.

Feature order is read from terrain_gate.meta.json and never rebuilt in code. Renaming one feature would otherwise permute every column while the scores still looked plausible.

Use

from mapart_nsfw.mapdata.image import load_rgba
from mapart_nsfw.terrain_gate import predict

rgba = load_rgba("tile.png")
predict.score(rgba)  # p(not terrain)
predict.is_terrain(rgba)  # score < threshold

The model ships inside the mapart-nsfw-detector wheel, so installing the package is all it takes. It is not on PyPI yet, so install from the repository:

pip install git+https://github.com/hqkh4nh/mapart-nsfw-detector

Training data

8,045 tiles: 6,445 hand-labelled tiles from an earlier version of the KingMC server, plus 1,600 vanilla maps generated by Minecraft's own rendering code. Folds are grouped by near-duplicate so two copies of one artwork never land on opposite sides. Art examples are augmented 8x, and the shipped artifact records this as "variant": "B x8 (+1729 art)".

The server corpus is not distributed, because it holds content that players built. The vanilla half is public, in the GitHub repository.

Limits

  • Recall-first by construction. The threshold sits at the lowest out-of-fold score any real art tile received, so it forwards more than it strictly must. Over its own corpus it forwards 7.4% of tiles, against 14.5% for the colour-only rule it replaced.
  • JPEG breaks it. Re-encoding at quality 95 pushed 97% of pixels off-palette and flipped 183 of 200 tiles across the threshold. What JPEG destroys is the dither the model reads, so lossy input should bypass this stage entirely rather than be snapped and scored.
  • One server's distribution. It was trained on one corpus. A server with a different build culture should retrain, and the repository ships the labelling tool for exactly that.
  • Nether maps are noise, not terrain images. Vanilla generates them from a coordinate hash without reading a block. They are labelled terrain here because that is what they are, legitimate game output, but they look like nothing else in the set.

Sponsor

KingMC, a Vietnamese Minecraft server at kingmc.vn, sponsors this project and is where the training corpus was collected. There is a live demo of both stages together.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support