Phase 11: real block textures for 2D tiles
Layers texture-averaged colors on top of palette.rs's hand-picked table as a fallback (color_for_textured), not a hard replacement — biome-tinted/animated blocks (grass top, leaves, water, lava) deliberately keep the hand-picked color since averaging their raw jar textures would be wrong, not just imprecise. Vanilla: worker/src/textures.rs downloads Mojang's official client jar directly from launchermeta/piston-meta/piston-data (same endpoints the real launcher uses, gated behind ACCEPT_MINECRAFT_EULA=true, off by default, mirrors BlueMap's accept-download) and averages every block texture, cached to disk so it's not re-downloaded every restart. Modded: ingests block_registry/block_textures messages from the mod (new Postgres tables + MinIO storage in api/src/textures.ts) — sent once per connection over the existing WS gateway. texturepacks/<name>/ (Dynmap-style flat PNGs) lets an operator override the vanilla defaults worker-wide via TEXTURE_PACK. A per-server texturePack admin column/API exists for the same purpose, but render-time per-server resolution (of both the admin selection and the ingested modded textures) is explicitly deferred — the worker still applies one process-wide palette; true per-server resolution needs the render pipeline to thread a server-scoped palette through the batch/GPU-dispatch path, judged too big a change for this phase. Documented in README. Docker was unavailable in this dev environment for the usual integration-test verification; bunx tsc --noEmit was used as a fallback static check instead (clean except 2 pre-existing unrelated errors in markers.test.ts).
This commit is contained in:
@@ -58,6 +58,51 @@ stack isn't on the same LAN. `MINIO_SECRET_KEY` is a real credential and is deli
|
||||
committed — set it in an untracked `./api/.env` / `./worker/.env` (docker-compose layers those on
|
||||
top of the tracked `.env.example`, see `docker-compose.yml`).
|
||||
|
||||
### Real block textures (Phase 11)
|
||||
|
||||
`worker/src/palette.rs`'s hand-picked color table is now a *fallback*, not the only source of
|
||||
2D-tile colors. Set `ACCEPT_MINECRAFT_EULA=true` (`worker/.env.example`, off by default — mirrors
|
||||
BlueMap's `accept-download`) and the worker downloads Minecraft's official client jar directly
|
||||
from Mojang's own public `launchermeta`/`piston-meta`/`piston-data` endpoints (same source the
|
||||
real launcher uses — no redistribution, so no licensing issue) on first startup, averages every
|
||||
`assets/minecraft/textures/block(s)/*.png` into a representative color, and caches the result to
|
||||
disk (`TEXTURE_CACHE_DIR`, default `./cache`) so it isn't re-downloaded every restart.
|
||||
`MC_TEXTURE_VERSION` (default `1.12.2`) picks which version's jar to pull from — this project's
|
||||
priority targets (1.7.10/1.12.2) share the pre-1.13 `textures/blocks/` (plural) naming, which
|
||||
`worker/src/textures.rs` checks alongside the modern `textures/block/` path.
|
||||
|
||||
A handful of blocks (grass block top, leaves, water, lava) are deliberately *excluded* from the
|
||||
texture-averaged path (`worker/src/block_names.rs`'s doc comment) and keep their hand-picked
|
||||
color: their real textures are either biome-tinted at runtime (grayscale in the raw file) or
|
||||
animated/transparent frame strips, so averaging the raw asset would produce a wrong color, not
|
||||
just an approximate one.
|
||||
|
||||
**`texturepacks/<name>/`** (flat `*.png` files, mirrors Dynmap) lets an operator override the
|
||||
downloaded defaults — set `TEXTURE_PACK=<name>` and its colors are layered on top of the vanilla
|
||||
palette at startup. Each server also has an admin-configurable `texturePack` field (`/admin`,
|
||||
`servers.texture_pack` — same shape as `waypointFormat`) recording *which* pack an operator wants
|
||||
per server — **but render-time application is currently worker-wide only, via `TEXTURE_PACK`, not
|
||||
yet resolved per-server from that column.** True per-server resolution needs the render pipeline
|
||||
to thread a server-scoped palette through `main.rs`'s batch loop instead of one process-wide
|
||||
`OnceLock` (`worker/src/render/mod.rs`) — a real architectural change, deferred rather than rushed.
|
||||
|
||||
**Modded blocks**: Forge doesn't split client/server jars, so a modded server's own classpath
|
||||
already has every loaded mod's texture assets, just unused server-side. The `forge-1_12_2` mod
|
||||
leaf (Enigmatica 2, this project's primary target) extracts them once at startup
|
||||
(`BlockAssetExtractor`, best-effort: guesses each block's texture by its registry-name path
|
||||
segment, not a real blockstate/model JSON resolution — that's Phase 12's job) and ships two new
|
||||
WS messages after connecting: `block_registry` (numeric id -> registry name, needed since a
|
||||
numeric `blockId` alone is meaningless without the mod list that assigned it) and `block_textures`
|
||||
(the extracted PNGs, batched). The api stores both (`api/src/textures.ts`: registry rows in a new
|
||||
`block_registry` table, texture PNGs in the shared MinIO bucket with pointer rows in
|
||||
`block_textures`) — **but, like the `texturepacks/` case above, nothing reads these tables into
|
||||
the render pipeline yet.** This is a deliberate two-step boundary: "ingest and store" (done, real,
|
||||
tested) vs. "resolve into a per-server palette at render time" (the same deferred piece as
|
||||
`texturepacks/` above, and naturally solved together). `forge-1_7_10`/`neoforge-26_1` don't
|
||||
implement extraction yet either — `BackendConnection#sendBlockRegistry`/`#sendBlockTextures` are
|
||||
on the shared interface (so any leaf can adopt them later with no protocol change), but only the
|
||||
1.12.2 leaf calls them so far, matching this phase's Enigmatica-2-focused verification target.
|
||||
|
||||
## Running
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user