diff --git a/art/generated/textures/floors/PROMPTS.md b/art/generated/textures/floors/PROMPTS.md index 32191dc..7a44cd8 100644 --- a/art/generated/textures/floors/PROMPTS.md +++ b/art/generated/textures/floors/PROMPTS.md @@ -1,53 +1,58 @@ # 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 slabs in a 3x2 grid on magenta; five -are used (`HD_FLOORS` in `src/gfx.rs`, with weights so plain slabs come more often). +`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). + +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. Prompt template (`{floor}` per master): ```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 one square floor slab made of a few fitted flagstones, with a dark grout line along all four edges, so the tiles fit together in any arrangement. All six tiles use the same stone, colours and style: {floor} The six tiles differ: tile 1 intact and clean; tile 2 with a large carved engraving in the middle; tile 3 with fine hairline cracks; tile 4 with a chipped corner and a few missing stone splinters; tile 5 with a broken flagstone, cracked through, a piece sunk and loose rubble; tile 6 with small engravings and worn edges. Style: hand-painted pixel art, chunky clear shapes, crisp edges, 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, 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. ``` ## player ```text -polished flagstones of medium crimson-red stone with a purple tint (clearly brighter than black), the engravings are glowing-edged demonic runes, horned skulls and pentagram-like sigils of an evil dungeon master. +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. ``` ## mossgrim ```text -damp mossy green-grey flagstones; the engravings show mushrooms, spores and coiling mould tendrils, green fungus and moss grow out of the grout lines and cracks, a mouldy cellar master's floor. +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 -elegant deep-blue marble flagstones with fine silver veins, the engravings are refined lilies, crescent moons and elegant curling filigree inlaid with silver, the floor of a cold, cultivated and vain lady of the night. +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-yellow sandstone flagstones with brass inlays, the engravings are alchemical sigils, suns and sulphur symbols, a few scorch marks, the floor of a greedy alchemist master of sulphur and gold. +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. ``` ## Processing -`tools/make_floor_tiles.py` crops the slabs, fills magenta inside them (chipped corners, holes) -with a dark void, brightens if asked, scales and reduces the colours: +`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: ```bash T=tools/make_floor_tiles.py -python3 $T player-raw.png player --grid 2x3 --pick 1,2,3,5,6 --size 128 --bright 1.45 # and --size 64 -python3 $T mossgrim-raw.png mossgrim --grid 2x3 --pick 1,2,3,4,5 --size 128 -python3 $T nightwell-raw.png nightwell --grid 2x3 --pick 1,2,3,4,5 --size 128 --bright 1.15 -python3 $T saffrax-raw.png saffrax --grid 2x3 --pick 1,2,3,4,5 --size 128 --bright 0.82 +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 +# the same with --size 64 ``` -The player's sheet came out too dark (brightened by 1.45); its fourth slab repeats the big skull -with a chipped corner and is left out. Saffrax' sandstone was too glaring (darkened by 0.82). `-64.png` / `-128.png` are copied to `assets/textures/floor-.png` / `floor--128.png`; `-128-preview.png` shows a floor laid out at random. diff --git a/art/generated/textures/floors/mossgrim-128-preview.png b/art/generated/textures/floors/mossgrim-128-preview.png index 0a40e33..d3df191 100644 Binary files a/art/generated/textures/floors/mossgrim-128-preview.png and b/art/generated/textures/floors/mossgrim-128-preview.png differ diff --git a/art/generated/textures/floors/mossgrim-128.png b/art/generated/textures/floors/mossgrim-128.png index 267b897..116abc1 100644 Binary files a/art/generated/textures/floors/mossgrim-128.png and b/art/generated/textures/floors/mossgrim-128.png differ diff --git a/art/generated/textures/floors/mossgrim-64-preview.png b/art/generated/textures/floors/mossgrim-64-preview.png index b64f0d6..dcf19ee 100644 Binary files a/art/generated/textures/floors/mossgrim-64-preview.png and b/art/generated/textures/floors/mossgrim-64-preview.png differ diff --git a/art/generated/textures/floors/mossgrim-64.png b/art/generated/textures/floors/mossgrim-64.png index 0e3d409..326c5d7 100644 Binary files a/art/generated/textures/floors/mossgrim-64.png and b/art/generated/textures/floors/mossgrim-64.png differ diff --git a/art/generated/textures/floors/mossgrim-raw.png b/art/generated/textures/floors/mossgrim-raw.png index 930a302..0df00da 100644 Binary files a/art/generated/textures/floors/mossgrim-raw.png and b/art/generated/textures/floors/mossgrim-raw.png differ diff --git a/art/generated/textures/floors/nightwell-128-preview.png b/art/generated/textures/floors/nightwell-128-preview.png index 7590c61..d36cea6 100644 Binary files a/art/generated/textures/floors/nightwell-128-preview.png and b/art/generated/textures/floors/nightwell-128-preview.png differ diff --git a/art/generated/textures/floors/nightwell-128.png b/art/generated/textures/floors/nightwell-128.png index 28a4ab1..8091399 100644 Binary files a/art/generated/textures/floors/nightwell-128.png and b/art/generated/textures/floors/nightwell-128.png differ diff --git a/art/generated/textures/floors/nightwell-64-preview.png b/art/generated/textures/floors/nightwell-64-preview.png index 6262875..1a89381 100644 Binary files a/art/generated/textures/floors/nightwell-64-preview.png and b/art/generated/textures/floors/nightwell-64-preview.png differ diff --git a/art/generated/textures/floors/nightwell-64.png b/art/generated/textures/floors/nightwell-64.png index 0239d51..5709f8e 100644 Binary files a/art/generated/textures/floors/nightwell-64.png and b/art/generated/textures/floors/nightwell-64.png differ diff --git a/art/generated/textures/floors/nightwell-raw.png b/art/generated/textures/floors/nightwell-raw.png index 3edbe9c..b03b44d 100644 Binary files a/art/generated/textures/floors/nightwell-raw.png and b/art/generated/textures/floors/nightwell-raw.png differ diff --git a/art/generated/textures/floors/player-128-preview.png b/art/generated/textures/floors/player-128-preview.png index 24e77e1..a7b6a5a 100644 Binary files a/art/generated/textures/floors/player-128-preview.png and b/art/generated/textures/floors/player-128-preview.png differ diff --git a/art/generated/textures/floors/player-128.png b/art/generated/textures/floors/player-128.png index a9212da..17618d1 100644 Binary files a/art/generated/textures/floors/player-128.png and b/art/generated/textures/floors/player-128.png differ diff --git a/art/generated/textures/floors/player-64-preview.png b/art/generated/textures/floors/player-64-preview.png index 964622e..085157c 100644 Binary files a/art/generated/textures/floors/player-64-preview.png and b/art/generated/textures/floors/player-64-preview.png differ diff --git a/art/generated/textures/floors/player-64.png b/art/generated/textures/floors/player-64.png index 599bf5e..7b14741 100644 Binary files a/art/generated/textures/floors/player-64.png and b/art/generated/textures/floors/player-64.png differ diff --git a/art/generated/textures/floors/player-raw.png b/art/generated/textures/floors/player-raw.png index 7fb2b90..f593fbf 100644 Binary files a/art/generated/textures/floors/player-raw.png and b/art/generated/textures/floors/player-raw.png differ diff --git a/art/generated/textures/floors/saffrax-128-preview.png b/art/generated/textures/floors/saffrax-128-preview.png index 16e62ca..47153a4 100644 Binary files a/art/generated/textures/floors/saffrax-128-preview.png and b/art/generated/textures/floors/saffrax-128-preview.png differ diff --git a/art/generated/textures/floors/saffrax-128.png b/art/generated/textures/floors/saffrax-128.png index 0b10232..b5a53f1 100644 Binary files a/art/generated/textures/floors/saffrax-128.png and b/art/generated/textures/floors/saffrax-128.png differ diff --git a/art/generated/textures/floors/saffrax-64-preview.png b/art/generated/textures/floors/saffrax-64-preview.png index 7e86794..3d1630c 100644 Binary files a/art/generated/textures/floors/saffrax-64-preview.png and b/art/generated/textures/floors/saffrax-64-preview.png differ diff --git a/art/generated/textures/floors/saffrax-64.png b/art/generated/textures/floors/saffrax-64.png index cde0a01..fb9005e 100644 Binary files a/art/generated/textures/floors/saffrax-64.png and b/art/generated/textures/floors/saffrax-64.png differ diff --git a/art/generated/textures/floors/saffrax-raw.png b/art/generated/textures/floors/saffrax-raw.png index 96a445c..fe3a03a 100644 Binary files a/art/generated/textures/floors/saffrax-raw.png and b/art/generated/textures/floors/saffrax-raw.png differ diff --git a/art/generated/textures/floors/v1/mossgrim-raw.png b/art/generated/textures/floors/v1/mossgrim-raw.png new file mode 100644 index 0000000..930a302 Binary files /dev/null and b/art/generated/textures/floors/v1/mossgrim-raw.png differ diff --git a/art/generated/textures/floors/v1/nightwell-raw.png b/art/generated/textures/floors/v1/nightwell-raw.png new file mode 100644 index 0000000..3edbe9c Binary files /dev/null and b/art/generated/textures/floors/v1/nightwell-raw.png differ diff --git a/art/generated/textures/floors/v1/player-raw.png b/art/generated/textures/floors/v1/player-raw.png new file mode 100644 index 0000000..7fb2b90 Binary files /dev/null and b/art/generated/textures/floors/v1/player-raw.png differ diff --git a/art/generated/textures/floors/v1/saffrax-raw.png b/art/generated/textures/floors/v1/saffrax-raw.png new file mode 100644 index 0000000..96a445c Binary files /dev/null and b/art/generated/textures/floors/v1/saffrax-raw.png differ diff --git a/assets/textures/floor-mossgrim-128.png b/assets/textures/floor-mossgrim-128.png index 267b897..116abc1 100644 Binary files a/assets/textures/floor-mossgrim-128.png and b/assets/textures/floor-mossgrim-128.png differ diff --git a/assets/textures/floor-mossgrim.png b/assets/textures/floor-mossgrim.png index 0e3d409..326c5d7 100644 Binary files a/assets/textures/floor-mossgrim.png and b/assets/textures/floor-mossgrim.png differ diff --git a/assets/textures/floor-nightwell-128.png b/assets/textures/floor-nightwell-128.png index 28a4ab1..8091399 100644 Binary files a/assets/textures/floor-nightwell-128.png and b/assets/textures/floor-nightwell-128.png differ diff --git a/assets/textures/floor-nightwell.png b/assets/textures/floor-nightwell.png index 0239d51..5709f8e 100644 Binary files a/assets/textures/floor-nightwell.png and b/assets/textures/floor-nightwell.png differ diff --git a/assets/textures/floor-player-128.png b/assets/textures/floor-player-128.png index a9212da..17618d1 100644 Binary files a/assets/textures/floor-player-128.png and b/assets/textures/floor-player-128.png differ diff --git a/assets/textures/floor-player.png b/assets/textures/floor-player.png index 599bf5e..7b14741 100644 Binary files a/assets/textures/floor-player.png and b/assets/textures/floor-player.png differ diff --git a/assets/textures/floor-saffrax-128.png b/assets/textures/floor-saffrax-128.png index 0b10232..b5a53f1 100644 Binary files a/assets/textures/floor-saffrax-128.png and b/assets/textures/floor-saffrax-128.png differ diff --git a/assets/textures/floor-saffrax.png b/assets/textures/floor-saffrax.png index cde0a01..fb9005e 100644 Binary files a/assets/textures/floor-saffrax.png and b/assets/textures/floor-saffrax.png differ diff --git a/src/gfx.rs b/src/gfx.rs index f74c352..9103b80 100644 --- a/src/gfx.rs +++ b/src/gfx.rs @@ -350,21 +350,22 @@ 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 slabs each (with a grout line -// along the edges, 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 +// 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) pub const T_HDFLOOR: u32 = 224; const HD_FLOORS: [(u32, u32, &[u8], &[u8], [u32; 5]); 4] = [ - // the player: crimson stone, demonic runes and horned skulls (plain, big engraving, cracks, broken, small engravings) - (T_CLAIM, T_HDFLOOR, include_bytes!("../assets/textures/floor-player.png"), include_bytes!("../assets/textures/floor-player-128.png"), [4, 1, 3, 1, 2]), - // Mossgrim: mossy green slabs, mushrooms and mould (plain, big engraving, cracks, chipped, broken) + // 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 marble, silver lilies and moons + // 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 and alchemical sigils + // 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]), ]; diff --git a/tools/make_floor_tiles.py b/tools/make_floor_tiles.py index 0089e15..f046934 100644 --- a/tools/make_floor_tiles.py +++ b/tools/make_floor_tiles.py @@ -6,10 +6,13 @@ palette shared by all tiles of the sheet. Usage: make_floor_tiles.py raw.png out_prefix --grid 2x3 --pick 1,2,3,5,6 [--size 128] - [--colors 48] [--bright 1.0] + [--colors 48] [--bright 1.0] [--inset 0.0] [--flatten] --pick which cells to keep, numbered row by row from 1 --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 + the grid of tiles does not show on the floor Writes out_prefix-.png: the picked tiles side by side, and out_prefix--preview.png (a 6x4 floor of them laid out at random, scaled up 2x). Needs Pillow. @@ -17,7 +20,7 @@ Writes out_prefix-.png: the picked tiles side by side, and out_prefix- 0: + d = int(tile.width * a.inset) + tile = tile.crop((d, d, tile.width - d, tile.height - d)) + tiles.append(tile) + if a.flatten: + # divide by the large-scale brightness: every tile gets the same, even brightness (the + # sheet's mean), so neither a vignette nor a lighter or darker tile shows the grid + blurs = [t.convert("L").filter(ImageFilter.GaussianBlur(t.width / 5)) for t in tiles] + mean = sum(ImageStat.Stat(b).mean[0] for b in blurs) / len(blurs) + for t, blur in zip(tiles, blurs): + bp, tp = blur.load(), t.load() + for y in range(t.height): + for x in range(t.width): + f = mean / max(bp[x, y], 1) + tp[x, y] = tuple(min(255, int(c * f)) for c in tp[x, y]) + if a.bright != 1.0: + tiles = [ImageEnhance.Brightness(t).enhance(a.bright) for t in tiles] + tiles = [t.resize((a.size, a.size), Image.LANCZOS) for t in tiles] strip = Image.new("RGB", (a.size * len(tiles), a.size)) for k, t in enumerate(tiles):