diff --git a/.gitignore b/.gitignore index 3d3ba87..67cf8fe 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,11 @@ user:// .gitea/logs/ build/ -.env \ No newline at end of file +.env + +# AI / asset-development outputs (regenerated by the tools; not shipped in the game) +assets/models/concepts/ +assets/models/npc/ +assets/textures/npc/ai/ +assets/textures/ai/* +!assets/textures/ai/game_ready/ \ No newline at end of file diff --git a/MEMORY.md b/MEMORY.md index c4385cd..5d3bd9c 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -46,6 +46,16 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o Next: Phase 3 (`NpcAvatar._load_model` + slot tinting) consumes `palette.json` and the GLB; Phase 2's capture/judge item is blocked on that. +- **Git hygiene + tooling (2026-11-01):** dev asset folders are now gitignored + and untracked: `assets/models/concepts/`, `assets/models/npc/` (Blender + sources), `assets/textures/npc/ai/` (raw AI fabrics), and the raw + `assets/textures/ai/*` outputs (only `assets/textures/ai/game_ready/` stays). + Kept in the repo: `assets/textures/npc/*_{albedo,normal,orm}.png` + + `palette.json`, `assets/models/generated/*` (props + npc_base.glb), and the + authored `assets/textures/*` set. `tools/asset_pipeline.py generate` gained + `--variants N` — generates N alternatives saved as `-1..N.png` (N=1 + keeps the unsuffixed path). Python tooling tests still pass (exit 0). + - Repo: `/run/media/system/DATA/Documents/06-games/security-game` (also reachable at `/var/home/zwitschi/Documents/06-games/security-game`). Godot: `~/.local/bin/godot` (4.3.stable). Tests: `godot --headless --path . --script res://src/test/test_runner.gd` → **177/177**. diff --git a/assets/models/concepts/bench.png b/assets/models/concepts/bench.png deleted file mode 100644 index 814ae13..0000000 Binary files a/assets/models/concepts/bench.png and /dev/null differ diff --git a/assets/models/concepts/bollard.png b/assets/models/concepts/bollard.png deleted file mode 100644 index 7619396..0000000 Binary files a/assets/models/concepts/bollard.png and /dev/null differ diff --git a/assets/models/concepts/fire_hydrant.png b/assets/models/concepts/fire_hydrant.png deleted file mode 100644 index 02ba786..0000000 Binary files a/assets/models/concepts/fire_hydrant.png and /dev/null differ diff --git a/assets/models/concepts/newspaper_box.png b/assets/models/concepts/newspaper_box.png deleted file mode 100644 index a5847b4..0000000 Binary files a/assets/models/concepts/newspaper_box.png and /dev/null differ diff --git a/assets/models/concepts/planter_box.png b/assets/models/concepts/planter_box.png deleted file mode 100644 index 8aab5eb..0000000 Binary files a/assets/models/concepts/planter_box.png and /dev/null differ diff --git a/assets/models/concepts/trash_bin.png b/assets/models/concepts/trash_bin.png deleted file mode 100644 index 9c2cd3f..0000000 Binary files a/assets/models/concepts/trash_bin.png and /dev/null differ diff --git a/assets/models/npc/npc_base.blend b/assets/models/npc/npc_base.blend deleted file mode 100644 index 89c23c5..0000000 Binary files a/assets/models/npc/npc_base.blend and /dev/null differ diff --git a/assets/models/npc/npc_base.blend1 b/assets/models/npc/npc_base.blend1 deleted file mode 100644 index c06e93b..0000000 Binary files a/assets/models/npc/npc_base.blend1 and /dev/null differ diff --git a/assets/textures/ai/asphalt.png b/assets/textures/ai/asphalt.png deleted file mode 100644 index bbf7059..0000000 Binary files a/assets/textures/ai/asphalt.png and /dev/null differ diff --git a/assets/textures/ai/awning.png b/assets/textures/ai/awning.png deleted file mode 100644 index f453772..0000000 Binary files a/assets/textures/ai/awning.png and /dev/null differ diff --git a/assets/textures/ai/brick_facade.png b/assets/textures/ai/brick_facade.png deleted file mode 100644 index 9daa0ec..0000000 Binary files a/assets/textures/ai/brick_facade.png and /dev/null differ diff --git a/assets/textures/ai/cards/credential.png b/assets/textures/ai/cards/credential.png deleted file mode 100644 index a359880..0000000 Binary files a/assets/textures/ai/cards/credential.png and /dev/null differ diff --git a/assets/textures/ai/cards/guest_list.png b/assets/textures/ai/cards/guest_list.png deleted file mode 100644 index 6101666..0000000 Binary files a/assets/textures/ai/cards/guest_list.png and /dev/null differ diff --git a/assets/textures/ai/cards/id_card.png b/assets/textures/ai/cards/id_card.png deleted file mode 100644 index 5431c4b..0000000 Binary files a/assets/textures/ai/cards/id_card.png and /dev/null differ diff --git a/assets/textures/ai/cards/ticket.png b/assets/textures/ai/cards/ticket.png deleted file mode 100644 index 9ac267d..0000000 Binary files a/assets/textures/ai/cards/ticket.png and /dev/null differ diff --git a/assets/textures/ai/cards/wristband.png b/assets/textures/ai/cards/wristband.png deleted file mode 100644 index 4136a0d..0000000 Binary files a/assets/textures/ai/cards/wristband.png and /dev/null differ diff --git a/assets/textures/ai/concrete.png b/assets/textures/ai/concrete.png deleted file mode 100644 index 606b573..0000000 Binary files a/assets/textures/ai/concrete.png and /dev/null differ diff --git a/assets/textures/ai/icons/door_locked.png b/assets/textures/ai/icons/door_locked.png deleted file mode 100644 index 0bae298..0000000 Binary files a/assets/textures/ai/icons/door_locked.png and /dev/null differ diff --git a/assets/textures/ai/icons/flashlight_on.png b/assets/textures/ai/icons/flashlight_on.png deleted file mode 100644 index f84c480..0000000 Binary files a/assets/textures/ai/icons/flashlight_on.png and /dev/null differ diff --git a/assets/textures/ai/icons/rec_dot.png b/assets/textures/ai/icons/rec_dot.png deleted file mode 100644 index 6d43224..0000000 Binary files a/assets/textures/ai/icons/rec_dot.png and /dev/null differ diff --git a/assets/textures/ai/icons/wand.png b/assets/textures/ai/icons/wand.png deleted file mode 100644 index ad914e0..0000000 Binary files a/assets/textures/ai/icons/wand.png and /dev/null differ diff --git a/assets/textures/ai/skyline.png b/assets/textures/ai/skyline.png deleted file mode 100644 index fc94b23..0000000 Binary files a/assets/textures/ai/skyline.png and /dev/null differ diff --git a/assets/textures/ai/vignette.png b/assets/textures/ai/vignette.png deleted file mode 100644 index 1e8f1d5..0000000 Binary files a/assets/textures/ai/vignette.png and /dev/null differ diff --git a/assets/textures/npc/ai/coat.png b/assets/textures/npc/ai/coat.png deleted file mode 100644 index fb90454..0000000 Binary files a/assets/textures/npc/ai/coat.png and /dev/null differ diff --git a/assets/textures/npc/ai/dress.png b/assets/textures/npc/ai/dress.png deleted file mode 100644 index f0273ea..0000000 Binary files a/assets/textures/npc/ai/dress.png and /dev/null differ diff --git a/assets/textures/npc/ai/jacket.png b/assets/textures/npc/ai/jacket.png deleted file mode 100644 index 5e32109..0000000 Binary files a/assets/textures/npc/ai/jacket.png and /dev/null differ diff --git a/assets/textures/npc/ai/shirt.png b/assets/textures/npc/ai/shirt.png deleted file mode 100644 index 8a70a60..0000000 Binary files a/assets/textures/npc/ai/shirt.png and /dev/null differ diff --git a/assets/textures/npc/ai/trousers.png b/assets/textures/npc/ai/trousers.png deleted file mode 100644 index 3148ffb..0000000 Binary files a/assets/textures/npc/ai/trousers.png and /dev/null differ diff --git a/assets/textures/npc/ai/vest.png b/assets/textures/npc/ai/vest.png deleted file mode 100644 index 831b042..0000000 Binary files a/assets/textures/npc/ai/vest.png and /dev/null differ diff --git a/tools/asset_pipeline.py b/tools/asset_pipeline.py index baa8bb7..0c657cc 100644 --- a/tools/asset_pipeline.py +++ b/tools/asset_pipeline.py @@ -258,6 +258,13 @@ def image_paths(values): return sorted(set(found)) +def _variant_output(output: Path, index: int, count: int) -> Path: + """Suffix the output path for alternative images (N > 1 only).""" + if count <= 1: + return output + return output.with_name(f"{output.stem}-{index}{output.suffix}") + + def _generate(args): profile = PROFILES[args.role] if (args.width is None) != (args.height is None): @@ -267,21 +274,24 @@ def _generate(args): transparent = args.transparent if args.transparent is not None else profile.get( "alpha") is True prompt = f"{args.prompt.strip()}. {ROLE_GUIDANCE[args.role]}." - image = generate_textures.generate_image( - prompt, args.model, args.request_size, transparent, - aspect_ratio=API_ASPECTS[args.role]) - foreground = getattr(args, "foreground", None) - if foreground: - image = colorize_alpha(image, foreground) - if args.role == "icon" and has_alpha(image): - image = resize_image_from_image( - image, width, height, "contain", (0, 0, 0, 0)) - else: - image = ImageOps.fit(image, (width, height), - method=Image.Resampling.LANCZOS) - if args.role == "tile": - image = make_seamless(image) - save_image(image, resolve_path(args.output)) + count = max(1, int(getattr(args, "variants", 1) or 1)) + output = resolve_path(args.output) + for index in range(1, count + 1): + image = generate_textures.generate_image( + prompt, args.model, args.request_size, transparent, + aspect_ratio=API_ASPECTS[args.role]) + foreground = getattr(args, "foreground", None) + if foreground: + image = colorize_alpha(image, foreground) + if args.role == "icon" and has_alpha(image): + image = resize_image_from_image( + image, width, height, "contain", (0, 0, 0, 0)) + else: + image = ImageOps.fit(image, (width, height), + method=Image.Resampling.LANCZOS) + if args.role == "tile": + image = make_seamless(image) + save_image(image, _variant_output(output, index, count)) def resize_image_from_image(image, width, height, fit, background): @@ -365,6 +375,9 @@ def build_parser(): default=generate_textures.GEN_SIZE) generate.add_argument("--width", type=int) generate.add_argument("--height", type=int) + generate.add_argument("--variants", type=int, default=1, + help="generate N alternative images; saved as " + "-1.png ... -N.png when N > 1") generate.add_argument( "--foreground", type=parse_color, help="replace visible RGB with this color while preserving alpha")