Skip to content

feat(textures): author seamless 3D cobblestone vector master (#28) - #195

Open
anjana005 wants to merge 1 commit into
mainfrom
feat/28-stone-cobblestone-diamond-ore
Open

feat(textures): author seamless 3D cobblestone vector master (#28)#195
anjana005 wants to merge 1 commit into
mainfrom
feat/28-stone-cobblestone-diamond-ore

Conversation

@anjana005

Copy link
Copy Markdown
Collaborator

Description

Author high-fidelity vector (SVG) master and un-rotated blockstate for Cobblestone matching the official cinematic Minecraft trailer aesthetic (#28):

  • Cobblestone (textures/cobblestone.svg):
    • Modular interlocking LEGO-plate matrix sampled 1:1 from authentic Minecraft trailer cobblestone geometry.
    • Synchronized palette matching textures/stone.svg:
      • Stone Face: #7e8187
      • Recessed Seam Cavity Bed: #5f6268
      • Sunlit Top-Left Highlight Bevel: #a4a7ae (crisp 4px rim)
      • Undercut Crevice Shadow: #3c3e44 (crisp 4px rim)
      • Cast Drop Shadow: #3c3e44 (+3px Y offset into mortar bed)
    • 100% seamless toroidal boundary wrapping across all $X$ and $Y$ edges ($X=0 \leftrightarrow 512, Y=0 \leftrightarrow 512$).
  • Blockstate (pack_template/assets/minecraft/blockstates/cobblestone.json):
    • Single-variant un-rotated blockstate to suppress random 3D rotations and preserve toroidal continuity in multi-block structures.
  • Documentation:
    • Updated CHANGELOG.md [Unreleased] with cobblestone.

Closes #28

Affected Assets

  • textures/cobblestone.svg
  • pack_template/assets/minecraft/blockstates/cobblestone.json
  • CHANGELOG.md

Type of Change

  • feat: New vector texture master, blockstate, or compiler capability
  • fix: Tiling fix, palette correction, or bugfix
  • docs: Documentation improvement
  • chore / refactor: Maintenance, dependencies, or codebase cleanup

Contributor Checklist

Vector Texture Standards (if adding/modifying SVGs)

  • Authored as a clean $512\times512$ SVG (viewBox="0 0 512 512").
  • Primary shapes are aligned to the $32\text{px}$ texel grid ($16\times16$ grid).
  • Seamless Toroidal Tiling: Checked and verified that elements wrapping across $X$ and $Y$ edges align perfectly without seams or chopped shapes.
  • Palette Consistency: Palette 100% synchronized with textures/stone.svg.
  • Free of leftover AI generation comments, unnecessary editor namespaces, or embedded raster images.

Build & Verification

  • Ran npm run build locally and verified that the pack compiles successfully.
  • Verified textures in-game and inspected rasterized PNG outputs in dist/.

Git Hygiene & Standards

  • Commit message follows Conventional Commits (feat(textures): ...).
  • Signed off with the Developer Certificate of Origin (git commit -s).
  • Branch is rebased cleanly onto latest main with no merge commits.
  • Formatting complies with .editorconfig (2-space indent, LF endings, trailing newline).

@anjana005
anjana005 requested a review from BharathASL September 1, 2026 11:46

@ninja6-agent ninja6-agent Bot 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.

Thanks for pushing this one forward — the blockstate approach and the palette work are right, and the intent behind the design is clearly the correct one. Four things block merge, all reproduced locally against this branch (npm ci, node v24.11.1, @resvg/resvg-js ^2.6.2, base 1d99625).

The short version: the texture lands in a directory the pack never reads, the entire 3D bevel layer is silently discarded by resvg, and the new seam-audit harness fails on this file while its three sibling textures pass at Δ=0.


Blocking

1. Wrong directory — the texture is never applied in-game

textures/cobblestone.svg is at the top level. Every other block master lives in textures/block/, and CONTRIBUTING.md L163 specifies textures/block/*.svg.

tools/build.mjs L202-L203 mirrors the source directory verbatim:

const relDir = path.dirname(file.relPath);
const targetDir = relDir === "." ? ASSETS_TEXTURES_DIR : path.join(ASSETS_TEXTURES_DIR, relDir);

relDir === ".", so the output is assets/minecraft/textures/cobblestone.png. Visible in the build log:

  ✓ block/tall_grass_top.png
  ✓ cobblestone.png          <-- no block/ prefix

The vanilla block/cobblestone model resolves minecraft:block/cobblestoneassets/minecraft/textures/block/cobblestone.png, which the pack does not ship. The block renders vanilla, and the blockstate override added here is a no-op as a result.

Fix: git mv textures/cobblestone.svg textures/block/cobblestone.svg, rebuild, and confirm the log prints ✓ block/cobblestone.png.

2. The entire 3D bevel layer renders as nothing

The bevel group is wrapped in clip-path="url(#clip_lego_matrix)", and that clip path is:

<clipPath id="clip_lego_matrix">
  <use href="#stone_lego_matrix" />
</clipPath>

#stone_lego_matrix is a <g>. Per SVG 1.1, a <clipPath> child <use> must reference a shape or text element — referencing a group is not valid, and resvg resolves it to an empty clip. Both bevel strokes are therefore culled entirely.

Verified by rendering the file as-authored versus with the clip-path attribute stripped: the as-authored render contains zero #a4a7ae highlight pixels; the stripped render contains them. What ships today is flat two-tone plus a 3px drop shadow — no highlight rim, no undercut shadow.

3. Even with the clip fixed, the stroke is per-rect, not a union perimeter

stroke on <use href="#a-group"> is an inherited presentation attribute — it applies to each of the ~145 child <rect> elements individually, not to the silhouette of their union. Rendering with the clip removed confirms this: the result is a graph-paper grid of 32px outlined squares, with rims drawn along interior boundaries between adjacent plates of the same boulder. The interlocking matrix reads as a checkerboard rather than as merged stones.

Worth flagging together with #2, because fixing the clip alone makes the texture look worse, not better. A real union outline needs merged <path> silhouettes rather than per-cell rects.

4. Fails the toroidal seam gate; its three siblings pass

npm run test:tiling on this branch:

  ✓ PASS    block/coal_ore.svg      [X+Y]  Seam Δ=0 (0 errors)
  ✓ PASS    block/diamond_ore.svg   [X+Y]  Seam Δ=0 (0 errors)
  ✓ PASS    block/stone.svg         [X+Y]  Seam Δ=0 (0 errors)
  ✗ FAIL    cobblestone.svg         [X+Y]  X: 236 errs, Y: 352 errs (Max Δ=60)

Baseline main is 20 failures / 30 textures; this branch is 21 / 31. The suite is already red overall, so this isn't a new CI break — but the standard is clearly achievable and the other three textures in this same set meet it at Δ=0.

Underneath those counts sits one genuine, non-heuristic defect. The drop-shadow layer is <use ... y="3">, unclipped, so each plate's shadow occupies the 3px strip below it. For plates on the bottom row (y=480) that strip falls at y=512–515 and is clipped away by the viewBox — it never reappears at the top of the tile above:

Location Expected Actual
Interior plate bottom edge (x=0, y=384–386) #43454b shadow #43454b
Wrapped bottom edge (x=32/160/192/352, y=0–2) #43454b shadow #5f6268 mortar ✗

Bottom-row boulders end up as the only ones in the pattern with no cast shadow — a systematic discontinuity when tiled.

In fairness to the numbers: analyzeSeams compares column 0 against column W−1 for pixel equality, which is stricter than true toroidal continuity — a design where a plate edge lands exactly on the boundary is visually fine but still fails. Much of the 236/352 count is that stricter criterion. The shadow-clipping defect above is the part that actually shows.


Non-blocking

5. The directional lighting isn't directional. The comments promise a "Sunlit Highlight Rim (Top-Left)" and "Undercut Crevice Shadow (Bottom-Right)", but both strokes are full closed outlines on all four sides. The only asymmetry is the shadow stroke's y="2" offset, which affects top/bottom only — nothing distinguishes left from right. And because the shadow is painted after the highlight, it overpaints all but ~2px at the top, so the net effect would be a mostly-dark outline rather than a top-left light catch.

6. stroke-width="4" yields a 2px rim. SVG strokes are centred on the path, so 2px falls outside the shape and is removed by the clip. The description calls it a "crisp 4px rim" twice.

7. Style divergence from stone.svg. textures/block/stone.svg uses rx="8" on every groove, which is where the rounded plate silhouette in the house style comes from. Cobblestone uses bare square rects with no rx, while the CHANGELOG entry added here describes "interlocking rounded 3D boulders". The palette itself (#7e8187 / #5f6268 / #a4a7ae / #3c3e44) matches stone exactly — that claim holds.

8. The CHANGELOG edit weakens an accurate entry. The rewrite appends "and 100% seamless toroidal tiling (#28)" to a bullet now covering stone, cobblestone, diamond_ore and coal_ore — not true for cobblestone per #4. It also drops "synchronized stone backgrounds", which documented the real invariant from CONTRIBUTING.md L77 that ore textures inherit stone's background. Suggest restoring the original wording and giving cobblestone its own bullet.

9. Blockstate formatting. stone.json and the other 15 files in that directory expand the model object across lines; the new cobblestone.json puts it inline. Cosmetic, but the directory is otherwise uniform.

10. Dead markup. xmlns:xlink is declared but never used (href is used throughout, which resvg supports). <g id="cobblestones"> has an id nothing references. id="clip_lego_matrix" is effectively dead given #2.

11. Maintainability of the geometry. The 145 hand-listed <rect> elements are hard to review and hard to modify — and #3 requires modifying them. A merged <path> with a compact d, or a small generation script committed alongside, would make both the audit and the fix tractable.


What's already right

  • Blockstate JSON is structurally valid and matches the un-rotated single-variant pattern used by stone.json / coal_ore.json / diamond_ore.json. The intent — suppressing random model rotation to preserve tiling continuity — is correct.
  • Palette is exactly synchronized with stone.svg; all four hex values match.
  • viewBox="0 0 512 512", 32px texel-grid alignment, no editor namespaces, no embedded raster, trailing newlines and 2-space indent per .editorconfig.
  • npm run build completes successfully.

Why nothing caught #1

Not a stale branch — the merge base here is 1d99625, the current tip of main, and author and commit timestamps are identical, so this is a fresh commit on an up-to-date tree. The directory convention simply moved recently:

Date Commit Event
2026-08-30 dd538f4 (#39) textures/stone.svg, coal_ore.svg, diamond_ore.svg added at top level — correct at the time
2026-08-31 0c62d0d (#189) All 29 masters renamed into textures/block/ (pure rename, no texture changes)
2026-09-01 e84b0a5 (this PR) textures/cobblestone.svg added following the pre-rename layout

Three things meant nothing surfaced the mismatch:

  • Rebasing can't help: cobblestone.svg is a brand-new file, so there's no rename for git to follow and no conflict to raise.
  • tools/build.mjs explicitly accepts a top-level SVG and reports success, so npm run build passing was accurate.
  • CONTRIBUTING.md L46 still says textures live in textures/, contradicting L163's textures/block/*.svg.

Two follow-ups worth opening separately, independent of this PR: have the compiler reject or warn on SVGs sitting at the root of textures/, and reconcile those two CONTRIBUTING lines.


Suggested path to merge

  1. git mv textures/cobblestone.svg textures/block/cobblestone.svg; rebuild and confirm ✓ block/cobblestone.png.
  2. Replace the per-cell <rect> matrix with merged per-boulder <path> silhouettes so stroke produces a real perimeter bevel, and drop the invalid group-referencing <clipPath>.
  3. Make the lighting genuinely directional — separate top-left highlight and bottom-right shadow geometry, the way stone.svg does with its top cast-shadow / bottom highlight-rim rect pairs.
  4. Wrap the drop shadow toroidally: draw it a second time at y="3-512" so the bottom row's shadow reappears at the top edge.
  5. Re-run npm run test:tiling and get cobblestone.svg to Δ=0 alongside its three siblings.
  6. Adjust the CHANGELOG bullet and the "4px rim" / "100% toroidal" claims in the description to match what the file does.

Happy to pair on the <path> merge in step 2 if that's useful — it's the fiddliest part of the list.

@BharathASL

Copy link
Copy Markdown
Contributor

textures/cobblestone.svg is at the repo root; every other master lives under textures/block/.

tools/build.mjs mirrors the directory structure of textures/ into assets/minecraft/textures/, so a file's depth determines where it lands in the pack:

  • A root-level master compiles to assets/minecraft/textures/cobblestone.png.
  • Minecraft looks for block textures at assets/minecraft/textures/block/cobblestone.png, so as it stands this file will not override vanilla cobblestone in-game.

Moving it to textures/block/cobblestone.svg resolves this.

Two smaller notes:

)

Signed-off-by: Anjana <anjanaanjumk@gmail.com>
@BharathASL
BharathASL force-pushed the feat/28-stone-cobblestone-diamond-ore branch from 7c875d9 to 44a979e Compare September 2, 2026 04:45
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.

feat: author authentic stone, cobblestone, and diamond ore vector masters

2 participants