Claimed floors: grey castle flagstones with an inlay in the owner's colour and engraving

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-07 22:01:02 +01:00
1 parent 72c44ae8d0
commit ad668ec123
35 files changed
+40 -52

No files matched your search

+25 -36
View File
@@ -1,56 +1,45 @@
# The masters' claimed floors (high-res)
Generated on 2026-11-07 with fal.ai: `fal-ai/nano-banana-pro`, `aspect_ratio: 3:2`,
`resolution: 2K`, one image per master. Each sheet has six tiles in a 3x2 grid on magenta; tiles
1-5 are used (plain, engraving, cracks, chipped, broken; `HD_FLOORS` in `src/gfx.rs`, weighted
4:1:3:2:1 so plain tiles come most often).
Generated on 2026-11-07 with fal.ai. The same grey, worn-smooth castle flagstones for every
master; every tile has a polished inlay in the master's colour with a light engraving of their
own, so ownership shows on every tile (`HD_FLOORS` in `src/gfx.rs`).
The first version (`v1/`) had regular slabs with thick grout frames and looked too even; this
one asks for roughly hewn castle flagstones worn smooth by many feet.
Earlier versions: `v1/` (regular coloured slabs with thick grout, too even), `v2/` (roughly hewn
stones fully in the master's colour, too glaring).
Prompt template (`{floor}` per master):
1. The player's sheet: `fal-ai/nano-banana-pro`, `aspect_ratio: 3:2`, `resolution: 2K`; six tiles
in a 3x2 grid on magenta, the prompt below with the player's inlay and engraving.
2. The other masters: `fal-ai/nano-banana-pro/edit` with the player's sheet as the reference, so
the grey stones stay exactly the same and only the inlays change.
Prompt for the player's sheet (`{inlay}`, `{engraving}` below):
```text
A texture sheet of six square floor tiles for a dark-fantasy dungeon strategy game, arranged in a grid of 3 columns and 2 rows, the tiles separated by thin flat pure magenta (#FF00FF) gaps, magenta also around the outside. Every tile is seen straight from above (orthographic top-down, no perspective), flat even lighting, no shadows, and fills its square completely. Every tile is a piece of the floor of an old medieval castle dungeon: irregular, roughly hewn flagstones of clearly different sizes and shapes (some large, some small, uneven outlines, slightly rounded chipped edges), laid with uneven mortar joints of varying width - not a regular grid. Centuries of feet have worn the stones smooth and polished: soft sheen on the walked-on surfaces, rounded worn edges, shallow dips. Along the four edges of every tile runs a mortar joint as thin and irregular as the ones inside, so the tiles fit together in any arrangement without a visible grid. All six tiles use the same stone, colours and style: {floor} The six tiles differ: tile 1 plain worn stones; tile 2 with a carved engraving on one large stone, worn half smooth; tile 3 with hairline cracks; tile 4 with a chipped stone corner and missing splinters; tile 5 with a broken flagstone, cracked through, a piece sunk and loose rubble; tile 6 with a few small worn engravings. Style: hand-painted pixel art, crisp edges, muted natural stone colours, readable at small size. No text, no labels, no numbers.
A texture sheet of six square floor tiles for a dark-fantasy dungeon strategy game, arranged in a grid of 3 columns and 2 rows, the tiles separated by thin flat pure magenta (#FF00FF) gaps, magenta also around the outside. Every tile is seen straight from above (orthographic top-down, no perspective), flat even lighting, no shadows, no vignette, and fills its square completely. Every tile is a piece of the floor of an old medieval castle dungeon: irregular, roughly hewn flagstones of neutral medium-grey stone (muted, desaturated, not glaring) of different sizes and shapes, laid with uneven dark-grey mortar joints - not a regular grid. Centuries of feet have worn the stones smooth: soft sheen, rounded worn edges, shallow dips. The joints along the four edges of every tile are as thin and irregular as the ones inside, so the tiles fit together in any arrangement without a visible grid. In the middle of every tile one polished inlay is set into the floor: a small rounded diamond-shaped inset of {inlay}, about a quarter of the tile wide, framed by a thin dark rim, with a light shallow engraving in it: {engraving}. The six tiles differ only in the grey stones around the inlay: tile 1 plain worn stones; tile 2 plain stones of other sizes; tile 3 with hairline cracks in the grey stones; tile 4 with a chipped grey stone corner and missing splinters; tile 5 with a broken grey flagstone beside the inlay, cracked through, a piece sunk and loose rubble; tile 6 with a few small scratches. Style: hand-painted pixel art, crisp edges, readable at small size. No text, no labels, no numbers.
```
## player
Edit prompt for the others:
```text
dark red-brown stone with a crimson-purple tint (medium brightness, not black); the engravings are worn demonic runes and horned skulls of an evil dungeon master, the grooves faintly glowing red.
Keep this image exactly the same - the same grey stones, mortar joints, cracks, damage, layout, magenta gaps and pixel art style - and change only the six small diamond-shaped inlays in the middle of the tiles: make them {inlay}, with a light shallow engraving of {engraving} in every inlay instead of the skull and runes. Do not change anything else.
```
## mossgrim
```text
grey-green stone, damp; moss and small fungi grow in the mortar joints and cracks; the engravings are worn mushrooms and coiling mould tendrils.
```
## nightwell
```text
cold blue-grey slate and marble stones with faint silver veins; the engravings are worn lilies and crescent moons with remnants of silver inlay.
```
## saffrax
```text
warm ochre-brown sandstone with a few brass studs; the engravings are worn alchemical sigils and suns, a few sooty scorch marks and yellow sulphur stains.
```
| master | inlay | engraving |
|---|---|---|
| player | deep crimson-red polished stone | a small horned demon skull and demonic rune marks |
| mossgrim | mossy green polished stone | a small mushroom with spores and a coiling mould tendril |
| nightwell | deep blue polished stone with a silver rim | a small lily under a crescent moon |
| saffrax | golden-yellow polished stone with a brass rim | a small alchemical sun sigil |
## Processing
`tools/make_floor_tiles.py` crops the tiles, fills magenta inside them (chipped corners, holes)
with a dark void, cuts a thin edge off (the joints and frames the model drew around every tile),
evens out the light (no vignette, all tiles equally bright, so the grid does not show), scales
and reduces the colours:
Tiles 1, 3, 4, 5, 6 are used (plain, cracked, chipped, broken, scratched; tile 2 nearly repeats
tile 1), weighted 4:2:2:1:3 in the game. `tools/make_floor_tiles.py` crops the tiles, fills
magenta inside them with a dark void, cuts a thin edge off, evens out the light and scales;
the colours are kept (a palette would let the large grey areas swallow the inlays' colours):
```bash
T=tools/make_floor_tiles.py
python3 $T player-raw.png player --grid 2x3 --pick 1,2,3,4,5 --size 128 --bright 1.1 --inset 0.03 --flatten
python3 $T mossgrim-raw.png mossgrim --grid 2x3 --pick 1,2,3,4,5 --size 128 --inset 0.03 --flatten
python3 $T nightwell-raw.png nightwell --grid 2x3 --pick 1,2,3,4,5 --size 128 --inset 0.045 --flatten
python3 $T saffrax-raw.png saffrax --grid 2x3 --pick 1,2,3,4,5 --size 128 --inset 0.03 --flatten
python3 tools/make_floor_tiles.py <name>-raw.png <name> --grid 2x3 --pick 1,3,4,5,6 --size 128 --colors 0 --inset 0.03 --flatten
# the same with --size 64
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 KiB

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 MiB

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 MiB

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 KiB

After

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

After

Width:  |  Height:  |  Size: 507 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 MiB

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 38 KiB

+12 -16
View File
@@ -350,23 +350,19 @@ const HD_TILES: [(u32, u32, &[u8], &[u8]); 9] = [
(T_DIAMOND, 2, include_bytes!("../assets/textures/diamond.png"), include_bytes!("../assets/textures/diamond-128.png")),
];
// The masters' claimed floors in the high-res style: five single tiles each of roughly hewn,
// worn-smooth castle flagstones (cut so they fit in any order), in the master's colour with
// engravings of their own and some of them cracked, chipped or broken. They go into cells of their own (from
// T_HDFLOOR on, five per master); a tile picks one by its position, weighted (plain slabs more
// often than the big engravings and the broken ones).
// (the claimed floor's cells, the first own cell, 64x64 slabs side by side, 128x128 ones, weights)
// The masters' claimed floors in the high-res style: the same grey, worn-smooth castle
// flagstones for everybody (cut so they fit in any order), every tile with a polished inlay in
// its master's colour and an engraving of their own (the player: a demon skull, Mossgrim: a
// mushroom, Lady Nightwell: a lily under the moon, Saffrax: an alchemical sun). Five tiles each:
// plain, cracked, chipped, broken, scratched. They go into cells of their own (from T_HDFLOOR on,
// five per master); a tile picks one by its position, weighted (plain ones most often).
// (the claimed floor's cells, the first own cell, 64x64 tiles side by side, 128x128 ones, weights)
pub const T_HDFLOOR: u32 = 224;
const HD_FLOORS: [(u32, u32, &[u8], &[u8], [u32; 5]); 4] = [
// every floor: plain, engraving, cracks, chipped, broken
// the player: red-brown stone, demonic runes and horned skulls
(T_CLAIM, T_HDFLOOR, include_bytes!("../assets/textures/floor-player.png"), include_bytes!("../assets/textures/floor-player-128.png"), [4, 1, 3, 2, 1]),
// Mossgrim: damp grey-green stone, moss in the joints, mushrooms and mould
(T_RIVAL1, T_HDFLOOR + 5, include_bytes!("../assets/textures/floor-mossgrim.png"), include_bytes!("../assets/textures/floor-mossgrim-128.png"), [4, 1, 3, 2, 1]),
// Lady Nightwell: blue-grey slate and marble, lilies and moons
(T_RIVAL2, T_HDFLOOR + 10, include_bytes!("../assets/textures/floor-nightwell.png"), include_bytes!("../assets/textures/floor-nightwell-128.png"), [4, 1, 3, 2, 1]),
// Saffrax: ochre sandstone, brass studs, alchemical sigils and suns
(T_RIVAL3, T_HDFLOOR + 15, include_bytes!("../assets/textures/floor-saffrax.png"), include_bytes!("../assets/textures/floor-saffrax-128.png"), [4, 1, 3, 2, 1]),
(T_CLAIM, T_HDFLOOR, include_bytes!("../assets/textures/floor-player.png"), include_bytes!("../assets/textures/floor-player-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL1, T_HDFLOOR + 5, include_bytes!("../assets/textures/floor-mossgrim.png"), include_bytes!("../assets/textures/floor-mossgrim-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL2, T_HDFLOOR + 10, include_bytes!("../assets/textures/floor-nightwell.png"), include_bytes!("../assets/textures/floor-nightwell-128.png"), [4, 2, 2, 1, 3]),
(T_RIVAL3, T_HDFLOOR + 15, include_bytes!("../assets/textures/floor-saffrax.png"), include_bytes!("../assets/textures/floor-saffrax-128.png"), [4, 2, 2, 1, 3]),
];
// the cell a tile at (x, z) shows in the high-res style: generated textures with four variants
@@ -2794,7 +2790,7 @@ mod hd_atlas_tests {
}
}
assert!(n.iter().all(|&k| k > 100), "{n:?}");
assert!(n[0] > n[1] * 2, "{n:?}");
assert!(n[0] > n[3] * 2, "{n:?}");
assert!((T_HDFLOOR + 15..T_HDFLOOR + 20).contains(&hd_tile(T_RIVAL3 + 2, 3, 7)));
// four variants by position, two variants keep theirs, others stay
assert_eq!(hd_tile(T_FLOOR + 3, 0, 0), T_FLOOR);
+3
View File
@@ -9,6 +9,8 @@ Usage:
[--colors 48] [--bright 1.0] [--inset 0.0] [--flatten]
--pick which cells to keep, numbered row by row from 1
--colors palette size (0: keep the colours; small coloured parts such as inlays would
fade in a palette taken mostly by large grey areas)
--bright factor on the colours (above 1: lighter)
--inset cut this share off every side (a frame or edge joint the model drew around the tile)
--flatten even out the light: no vignette towards the edges, all tiles equally bright, so
@@ -83,6 +85,7 @@ def main():
strip = Image.new("RGB", (a.size * len(tiles), a.size))
for k, t in enumerate(tiles):
strip.paste(t, (k * a.size, 0))
if a.colors > 0:
strip = strip.quantize(colors=a.colors, method=Image.Quantize.MEDIANCUT, dither=Image.Dither.NONE).convert("RGB")
strip.save(f"{a.out}-{a.size}.png")