# 3D-Modelle > **Git:** `.glb`/Textures unter `3DModelle/` sind lokal (Forgejo HTTP 413). Mit Git-LFS nachziehen, sobald verfügbar. ``` 3DModelle/ _inbox/ # optional drop zone props/ # button, table, … houses/ # house, house_b, broken, … | massour = fest animals/ # cat, chimp, giraffe, … ``` ## Auto-Sort GLBs in die **Root** oder `_inbox/` legen (Umbenennen ok). Nach **~45s ohne Änderung**: ```bash python3 scripts/tools/organize_3d_models.py --watch --import ``` Sortiert nach Namen → `props/` / `houses/` / `animals/`, zieht Texturen mit, fixt `.import`. Einmal sofort: `python3 scripts/tools/organize_3d_models.py --force --import` **Random-Dorf:** Häuser außer `massour/`; Tiere außer `cow/` (Kuh = Masseur **im Dorf**). **Größen:** Spieler = **1,74 m** (`SpriteFit.WORLD_PLAYER_HEIGHT`); Häuser ~8,5 m, Kuh ~1,5 m, Tiere artgerecht (Katze ~28 cm … Giraffe ~3,4 m). Scale-Lab / `data/model_scales.json` überschreibt Fits. ## Editor-Vorschau (WYSIWYG) Ohne Play sehen, wo Billboards und 3D-Props landen: | Was | Script | Verhalten im Editor | |-----|--------|---------------------| | Billboards | `BillboardSprite` (`@tool`) | Quad + Texture; **yaw** zur **Editor-Kamera** (`get_viewport().get_camera_3d()`) | | NPCs / Enemies / Player | `InteractableNPC`, `HittableEntity`, `PlayerController`, … | Laden Texture/Höhe aufs Kind-Billboard (kein Kampf-/Quest-Code) | | ModelProps | `ModelProp` (`@tool`) | Lädt GLB, `fit_height` / Katalog; Mesh-Child **ohne** `owner` (wird nicht mitgespeichert) | | Dorf-Random-Spawns | `village.gd` (`@tool`) | Export **`editor_preview_spawns`** (default an): deterministische Stand-ins an `HOUSE_SLOTS` / `ANIMAL_SLOTS` + Masseur/Kuh/Progress. Prefix `_EditorPreview_*`. Runtime freut sie vor dem echten Random-Spawn. | **Tipps:** Dorf-Szene öffnen → 3D-Viewport drehen → Billboards folgen der Editor-Kamera. Preview aus = nur feste Scene-Kinder (Tisch, NPCs). Speichern persistiert keine Preview-Meshes.