initial commit

This commit is contained in:
saarsena@gmail.com 2026-04-22 10:19:57 -04:00
commit c2bb3893a9
1038 changed files with 75846 additions and 0 deletions

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python3
"""Fix stale res://textures/td_sliced/<UPPER>.png references in .tres files
under textures/tb/ rewrites them to the new tb/<role>/<family>/<variant>.png
location. Cosmetic only; Godot already resolves these via UID."""
import re
from pathlib import Path
TB_ROOT = Path.home() / "godot_projects/trench/textures/tb"
ROLE_MAP = {
"brick": "wall", "concrete": "wall", "stucco": "wall", "steel": "wall",
"wood": "wall", "panel": "wall", "tech": "wall", "lab": "wall",
"rivet": "wall", "tile": "wall", "hedge": "wall", "fence": "wall",
"floor": "floor", "cobbles": "floor", "dirt": "floor", "grass": "floor",
"sand": "floor", "tarmac": "floor", "sidewalk": "floor", "grid": "floor",
"door": "door", "bigdoor": "door", "ldoor": "door", "rdoor": "door",
"doortrim": "trim", "ledge": "trim", "step": "trim", "support": "trim",
"pipes": "trim", "vent": "trim",
"light": "light",
"blood": "decal", "warn": "decal", "paper": "decal",
"slime": "liquid", "sludge": "liquid",
"crate": "prop", "console": "prop", "switch": "prop",
}
basename_re = re.compile(r"^([a-z]+)_(\d+[a-z](?:_[a-z]+)?)\.png$")
ref_re = re.compile(r'res://textures/td_sliced/([^"]+\.png)')
fixed = 0
for tres in TB_ROOT.rglob("*.tres"):
text = tres.read_text()
def replace(m):
old = m.group(1).lower()
bm = basename_re.match(old)
if not bm:
return m.group(0)
family, variant = bm.group(1), bm.group(2)
role = ROLE_MAP.get(family)
if not role:
return m.group(0)
return f"res://textures/tb/{role}/{family}/{variant}.png"
new_text = ref_re.sub(replace, text)
if new_text != text:
tres.write_text(new_text)
fixed += 1
print(f"Fixed {fixed} .tres files")

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Lowercase every file in textures/td_sliced/ and fix the source_file= field
inside .png.import files so Godot can still find the source PNG."""
import re
from pathlib import Path
SRC = Path.home() / "godot_projects/trench/textures/td_sliced"
renamed = 0
skipped = 0
collisions = []
# Snapshot before mutating
files = sorted(SRC.iterdir())
for f in files:
if not f.is_file():
continue
lower = f.name.lower()
if lower == f.name:
skipped += 1
continue
target = f.parent / lower
if target.exists():
collisions.append(f.name)
continue
f.rename(target)
renamed += 1
# Fix source_file= inside every .png.import in the folder
for imp in sorted(SRC.glob("*.png.import")):
text = imp.read_text()
new_text = re.sub(
r'(source_file="res://textures/td_sliced/)([^"]+)"',
lambda m: f'{m.group(1)}{m.group(2).lower()}"',
text,
)
if new_text != text:
imp.write_text(new_text)
print(f"renamed: {renamed}")
print(f"already-lowercase: {skipped}")
if collisions:
print(f"COLLISIONS (target already existed): {len(collisions)}")
for c in collisions:
print(f" {c}")

View file

@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""Reorganize textures/td_sliced/ into textures/tb/<family>/<variant>.png
Already-lowercase precondition: run lowercase_textures.py first.
For each <family>_<variant>.png in the source folder, moves:
- the .png itself
- the .png.import sibling (with source_file= rewritten)
- the .tres sibling (if any) with its path= field rewritten
Files that don't match the family_variant pattern are left in place.
"""
import re
from pathlib import Path
ROOT = Path.home() / "godot_projects/trench/textures"
SRC = ROOT / "td_sliced"
DST_BASE = ROOT / "tb"
# family_variant.png OR family_variant_tag.png
# variant must start with a digit (so we don't accidentally split a multi-word
# family name on its first underscore)
NAME_RE = re.compile(r"^([a-z]+)_(\d+[a-z](?:_[a-z]+)?)\.png$")
moved_groups = 0
moved_files = 0
skipped = []
png_files = sorted(SRC.glob("*.png"))
for png in png_files:
m = NAME_RE.match(png.name)
if not m:
skipped.append(png.name)
continue
family, variant = m.group(1), m.group(2)
new_dir = DST_BASE / family
new_dir.mkdir(parents=True, exist_ok=True)
new_png = new_dir / f"{variant}.png"
new_imp = new_dir / f"{variant}.png.import"
new_tres = new_dir / f"{variant}.tres"
if new_png.exists():
print(f"COLLISION skip: {png.name} -> {new_png}")
continue
# Move .png
png.rename(new_png)
# Move + rewrite .png.import
old_imp = png.with_suffix(".png.import")
if old_imp.exists():
text = old_imp.read_text()
text = text.replace(
f"res://textures/td_sliced/{png.name}",
f"res://textures/tb/{family}/{variant}.png",
)
old_imp.unlink()
new_imp.write_text(text)
# Move + rewrite sibling .tres material if it exists
old_tres = png.with_suffix(".tres")
if old_tres.exists():
text = old_tres.read_text()
text = text.replace(
f"res://textures/td_sliced/{png.name}",
f"res://textures/tb/{family}/{variant}.png",
)
old_tres.unlink()
new_tres.write_text(text)
moved_groups += 1
moved_files += 1 + int(old_imp.exists() is False) * 0 # always counted via group
print(f"\nmoved {moved_groups} groups")
print(f"skipped (non-matching) {len(skipped)} files:")
for s in skipped:
print(f" {s}")

84
tools/role_reorg.py Normal file
View file

@ -0,0 +1,84 @@
#!/usr/bin/env python3
"""Move textures/tb/<family>/ into textures/tb/<role>/<family>/ and rewrite path refs.
Run with Godot editor closed. Operates in place. Reversible by reading the
final report and inverting the mapping.
"""
from pathlib import Path
ROOT = Path.home() / "godot_projects/trench/textures/tb"
ROLE_MAP = {
# walls
"brick": "wall", "concrete": "wall", "stucco": "wall", "steel": "wall",
"wood": "wall", "panel": "wall", "tech": "wall", "lab": "wall",
"rivet": "wall", "tile": "wall", "hedge": "wall", "fence": "wall",
# floors
"floor": "floor", "cobbles": "floor", "dirt": "floor", "grass": "floor",
"sand": "floor", "tarmac": "floor", "sidewalk": "floor", "grid": "floor",
# doors
"door": "door", "bigdoor": "door", "ldoor": "door", "rdoor": "door",
# trim
"doortrim": "trim", "ledge": "trim", "step": "trim", "support": "trim",
"pipes": "trim", "vent": "trim",
# light
"light": "light",
# decal / liquid / prop
"blood": "decal", "warn": "decal", "paper": "decal",
"slime": "liquid", "sludge": "liquid",
"crate": "prop", "console": "prop", "switch": "prop",
}
ROLES = set(ROLE_MAP.values())
# Step 1: families whose name matches a role (floor, door, light) need a temp
# rename so they don't collide with the role folder we're about to create.
conflicts = {fam for fam in ROLE_MAP if fam in ROLES}
for fam in conflicts:
src = ROOT / fam
if src.is_dir():
src.rename(ROOT / f"__tmp_{fam}")
# Step 2: move each family into its role folder, rewriting path refs.
moved = 0
updated = 0
for fam, role in ROLE_MAP.items():
src = ROOT / (f"__tmp_{fam}" if fam in conflicts else fam)
if not src.is_dir():
continue
role_dir = ROOT / role
role_dir.mkdir(exist_ok=True)
dst = role_dir / fam
if dst.exists():
print(f"COLLISION: {dst} already exists, skipping {fam}")
continue
src.rename(dst)
moved += 1
old_prefix = f"res://textures/tb/{fam}/"
new_prefix = f"res://textures/tb/{role}/{fam}/"
for f in dst.iterdir():
if not f.is_file():
continue
if f.name.endswith(".png.import") or f.suffix == ".tres":
text = f.read_text()
new_text = text.replace(old_prefix, new_prefix)
if new_text != text:
f.write_text(new_text)
updated += 1
# Check for unknown families left at the top level
unknown = [
d.name for d in ROOT.iterdir()
if d.is_dir() and d.name not in ROLES and not d.name.startswith("__tmp_")
]
print(f"\nMoved {moved} families into {len(ROLES)} role folders")
print(f"Updated {updated} ref files (.png.import + .tres)")
if unknown:
print(f"\nWARNING: unknown families left at top level: {unknown}")