Skip to content

Map colours averaged from the real block textures (#127) - #149

Merged
CaYatur merged 1 commit into
mainfrom
feat/block-colours-from-textures
Jul 29, 2026
Merged

Map colours averaged from the real block textures (#127)#149
CaYatur merged 1 commit into
mainfrom
feat/block-colours-from-textures

Conversation

@CaYatur

@CaYatur CaYatur commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Closes #127.

COLOURS in regionFormat.ts names about forty blocks and guesses the rest from suffixes — *_planks, *_leaves, anything containing "stone". That is wrong for the hundreds it does not name and for every modded block there has ever been. The textures are already on disk from #148; averaging them is simply better data for the same question.

An override, not a replacement, installed at runtime rather than imported. Empty until an operator downloads a client jar, and one bad decode costs one block its entry rather than the map its colours.

Measuring found three defects

Every number below is from the real 1.21.4 jar, and each one was a bug.

Two thirds of the textures did not decode — 355 of 1039. The failures were entirely bit depths 4 and 2: 626 Minecraft block textures are 4-bit palette PNGs and 35 are 2-bit. The decoder handled depth 8 only, and no fixture caught it because every fixture was written at depth 8. Now 1037 of 1039 decode.

Animated textures were averaged whole. Water, lava, fire and the portal ship as a vertical strip of frames — water_still is 16×512, thirty-two frames. Averaging the strip averages every frame at once. firstFrame crops to the top square; lava now reads #d9691a. The same check keeps a strip out of the item icons, where it was being drawn as thirty-two pictures squashed into a 30px box.

The extractor's comment claimed this was already handled "by skipping .mcmeta files". It was not — skipping the metadata file does nothing about the png beside it.

Biome-tinted textures are grey in the file. grass_block_top averages #939393, oak_leaves #909090, water_still #b1b1b1 — the game multiplies them by a colour it picks per biome at render time. Overriding the table's green with grey would have made the map visibly worse than before, which is exactly the regression this was split into its own PR to avoid. Those keep the table's answer.

Sanity check on the result

block averaged
sand #dbcfa3
oak_planks #a2834f
gold_block #f6d03e
diamond_block #62ede4
obsidian #0f0b19
netherrack #622626
lava_still #d9691a

The lookup also prefers the top face — a map is looked at from above, so a log should read as its rings rather than its bark.

Verification

12/12 gates. Restoring the depth-8-only check fails with a 4-bit palette png did not decode — the check the first version did not have.

The other half of #127. `COLOURS` in regionFormat.ts names about forty
blocks and guesses the rest from suffixes — `*_planks`, `*_leaves`,
anything containing "stone" — which is wrong for the hundreds it does not
name and for every modded block there has ever been. The textures are
already on disk from the item-icon half; averaging them is simply better
data for the same question.

An OVERRIDE, not a replacement, installed at runtime rather than
imported. Empty until an operator downloads a client jar, and one bad
decode costs one block its entry rather than the map its colours. The map
that worked before this existed still works if the decoder meets
something it does not understand.

Everything below was measured against the real 1.21.4 jar, and every
number found a defect.

  TWO THIRDS OF THE TEXTURES DID NOT DECODE. 355 of 1039. The failures
  were entirely bit depths 4 and 2 — 626 block textures in Minecraft are
  4-bit palette pngs and 35 are 2-bit. The decoder handled depth 8 only,
  and no fixture caught it because every fixture was written at depth 8.
  Sub-byte palette samples now unpack from the byte they share. 1037 of
  1039 decode; the two left are one 1-bit greyscale and one oddity.

  ANIMATED TEXTURES WERE AVERAGED WHOLE. Water, lava, fire and the portal
  ship as a vertical strip of frames in one file — water_still is 16x512,
  thirty-two frames. Averaging the strip averages every frame at once and
  came out a muddy nothing. `firstFrame` crops to the top square; lava
  now reads #d9691a instead. The same check keeps a strip out of the item
  icons, where it was drawn as thirty-two pictures squashed into a 30px
  box. The comment in the extractor claimed this was already handled by
  skipping `.mcmeta` files. It was not: skipping the metadata file does
  nothing about the png beside it.

  BIOME-TINTED TEXTURES ARE GREY IN THE FILE. grass_block_top averages
  #939393, oak_leaves #909090, water_still #b1b1b1 — the game multiplies
  them by a colour it picks per biome at render time. Overriding the
  table's green with grey would have made the map visibly worse than
  before, which is exactly the regression this was split into its own PR
  to avoid. Those keep the table's answer.

And the lookup prefers the TOP face: a map is looked at from above, so a
log should read as its rings rather than its bark.

Verified: 12/12 gates. Restoring the depth-8-only check fails with "a
4-bit palette png did not decode" — the check the first version did not
have.
Copilot AI review requested due to automatic review settings July 29, 2026 17:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@CaYatur
CaYatur merged commit 130f081 into main Jul 29, 2026
1 check passed
@CaYatur
CaYatur deleted the feat/block-colours-from-textures branch July 29, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract item and block textures from the client jar instead of using a CDN and a colour table

2 participants