diff --git a/library/objects.json b/library/objects.json index 70aca71..f239832 100644 --- a/library/objects.json +++ b/library/objects.json @@ -2,59 +2,775 @@ "library_version": 1, "note": "Editor-Kopie der offiziellen Bibliotheks-Registry (geschlossener Baukasten, PLAN Entscheidung 20). Quelle: scopedvr-match-server library/objects.json — beim Registrieren neuer Objekte DORT zuerst eintragen und hier synchron ziehen. 'poly' = Referenz-Dreieckszahl (Budget-Rechnung, map_format.md §4 V8); 'collision' = Approximation für Platzhalter-Darstellung im Viewport.", "objects": { - "crate_wood": { "poly": 12, "collision": { "shape": "box", "size": [1.2, 1.2, 1.2] } }, - "crate_metal": { "poly": 12, "collision": { "shape": "box", "size": [1.0, 1.0, 1.0] } }, - "wall_concrete": { "poly": 12, "collision": { "shape": "box", "size": [4.0, 2.5, 0.4] } }, - "barrier_sandbag": { "poly": 36, "collision": { "shape": "box", "size": [2.0, 0.9, 0.8] } }, - "bunker_concrete": { "poly": 96, "collision": { "shape": "box", "size": [6.0, 2.8, 4.0] } }, - "watchtower_wood": { "poly": 240, "collision": { "shape": "box", "size": [3.0, 6.0, 3.0] } }, - "fence_metal": { "poly": 24, "collision": { "shape": "box", "size": [4.0, 1.8, 0.15] } }, - "rock_large": { "poly": 128, "collision": { "shape": "sphere", "radius": 1.5 } }, - "boulder_small": { "poly": 96, "collision": { "shape": "sphere", "radius": 0.8 } }, - "tree_pine": { "poly": 180, "collision": { "shape": "cylinder", "radius": 0.4, "height": 12.0 } }, - "bush_small": { "poly": 64, "collision": { "shape": "sphere", "radius": 0.8 } }, - "fass": { "poly": 128, "collision": { "shape": "cylinder", "radius": 0.31, "height": 0.88 } }, - "bruecke_holz": { "poly": 228, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.85, 0], "size": [2, 0.3, 3] }, { "shape": "box", "pos": [0, 0.361, -2.806], "size": [2, 0.3, 2.89], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0, 0.361, 2.806], "size": [2, 0.3, 2.89], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [-0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [-0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 1.5, 0], "size": [0.14, 0.12, 3] }, { "shape": "box", "pos": [0.93, 0.964, -2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [21.8, 0, 0] }, { "shape": "box", "pos": [0.93, 0.964, 2.564], "size": [0.14, 0.12, 2.69], "rot_deg": [-21.8, 0, 0] }] } }, - "hoehleneingang": { "poly": 204, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [1.8, 1.6, 0], "size": [1.4, 3.2, 4] }, { "shape": "box", "pos": [0, 2.8, 0], "size": [5, 0.8, 4] }, { "shape": "box", "pos": [0, 1.2, 1.8], "size": [2.2, 2.4, 0.4] }] } }, - "felsbogen": { "poly": 156, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [-1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [1.9, 1.3, 0], "size": [1.2, 2.6, 2.4] }, { "shape": "box", "pos": [0, 3.1, 0], "size": [5, 1, 2.4] }] } }, - "stein_kiesel_1": { "poly": 136, "collision": { "shape": "none" } }, - "baum_kiefer_1": { "poly": 728, "collision": { "shape": "cylinder", "radius": 0.4, "height": 8.489 } }, - "baum_kiefer_2": { "poly": 655, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.082 } }, - "baum_kiefer_3": { "poly": 1012, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.141 } }, - "baum_kiefer_4": { "poly": 1006, "collision": { "shape": "cylinder", "radius": 0.4, "height": 10.001 } }, - "baum_laub_1": { "poly": 857, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.022 } }, - "baum_laub_2": { "poly": 802, "collision": { "shape": "cylinder", "radius": 0.4, "height": 7.4 } }, - "baum_laub_3": { "poly": 723, "collision": { "shape": "cylinder", "radius": 0.4, "height": 9.182 } }, - "baum_laub_4": { "poly": 668, "collision": { "shape": "cylinder", "radius": 0.4, "height": 6.763 } }, - "baum_tot_1": { "poly": 761, "collision": { "shape": "cylinder", "radius": 0.4, "height": 9.16 } }, - "fels_moos_block_gross": { "poly": 46, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.4, 0], "size": [2, 0.8, 2] }, { "shape": "box", "pos": [0, 1.1, 0], "size": [1.2, 0.7, 1.2] }] } }, - "fels_moos_block_hoch": { "poly": 64, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.48, 0], "size": [1.4, 0.95, 1.4] }, { "shape": "box", "pos": [0, 1.35, 0], "size": [0.9, 0.95, 0.9] }] } }, - "fels_trocken_block": { "poly": 36, "collision": { "shape": "compound", "parts": [{ "shape": "box", "pos": [0, 0.5, 0], "size": [2.18, 1, 1.63] }, { "shape": "box", "pos": [0, 1.5, 0], "size": [1.5, 1.15, 1] }] } }, - "fels_moos_platte": { "poly": 32, "collision": { "shape": "box", "size": [2, 0.915, 2] } }, - "fels_moos_scharte": { "poly": 48, "collision": { "shape": "box", "size": [0.968, 0.289, 1.823] } }, - "fels_trocken_platte": { "poly": 48, "collision": { "shape": "box", "size": [3.821, 0.662, 2] } }, - "fels_trocken_klein": { "poly": 20, "collision": { "shape": "box", "size": [0.894, 0.724, 0.851] } }, - "stein_mittel_1": { "poly": 342, "collision": { "shape": "box", "size": [3.225, 1.989, 2.989] } }, - "stein_mittel_2": { "poly": 522, "collision": { "shape": "box", "size": [3.42, 2.001, 3.476] } }, - "strauch_gruen": { "poly": 900, "collision": { "shape": "none" } }, - "strauch_blumen": { "poly": 1368, "collision": { "shape": "none" } }, - "pflanze_farn": { "poly": 288, "collision": { "shape": "none" } }, - "pflanze_klee": { "poly": 379, "collision": { "shape": "none" } }, - "blume_gross_1": { "poly": 285, "collision": { "shape": "none" } }, - "blume_gross_2": { "poly": 642, "collision": { "shape": "none" } }, - "blumen_strauss": { "poly": 755, "collision": { "shape": "none" } }, - "pflanze_niedrig": { "poly": 120, "collision": { "shape": "none" } }, - "pflanze_teppich": { "poly": 48, "collision": { "shape": "none" } }, - "pflanze_teppich_gross": { "poly": 112, "collision": { "shape": "none" } }, - "gras_kurz": { "poly": 155, "collision": { "shape": "none" } }, - "gras_hoch": { "poly": 326, "collision": { "shape": "none" } }, - "gras_bueschel": { "poly": 494, "collision": { "shape": "none" } }, - "gras_wispy_hoch": { "poly": 622, "collision": { "shape": "none" } }, - "pilz_fliegenpilz": { "poly": 80, "collision": { "shape": "none" } }, - "pilz_pfifferling": { "poly": 112, "collision": { "shape": "none" } }, - "pilz_steinpilz": { "poly": 80, "collision": { "shape": "none" } }, - "pilz_shiitake": { "poly": 80, "collision": { "shape": "none" } }, - "pilz_morchel": { "poly": 80, "collision": { "shape": "none" } }, - "pilz_austernseitling": { "poly": 112, "collision": { "shape": "none" } } + "barrier_sandbag": { + "poly": 36, + "collision": { + "shape": "box", + "size": [ + 2.0, + 0.9, + 0.8 + ] + } + }, + "baum_kiefer_1": { + "poly": 728, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 8.489 + } + }, + "baum_kiefer_2": { + "poly": 655, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 7.082 + } + }, + "baum_kiefer_3": { + "poly": 1012, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 7.141 + } + }, + "baum_kiefer_4": { + "poly": 1006, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 10.001 + } + }, + "baum_laub_1": { + "poly": 857, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 7.022 + } + }, + "baum_laub_2": { + "poly": 802, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 7.4 + } + }, + "baum_laub_3": { + "poly": 723, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 9.182 + } + }, + "baum_laub_4": { + "poly": 668, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 6.763 + } + }, + "baum_tot_1": { + "poly": 761, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 9.16 + } + }, + "beispiel_fass_01": { + "poly": 184, + "collision": { + "shape": "box", + "size": [ + 0.617, + 0.85, + 0.617 + ] + }, + "glb": "res://assets/objekte/military_desert/beispiel/beispiel_fass_01.glb", + "kategorie": "beispiel", + "name_de": "Beispielfass 01 (Ölfass grün)" + }, + "beispiel_fass_02": { + "poly": 184, + "collision": { + "shape": "box", + "size": [ + 0.617, + 0.85, + 0.617 + ] + }, + "glb": "res://assets/objekte/military_desert/beispiel/beispiel_fass_02.glb", + "kategorie": "beispiel", + "name_de": "Beispielfass 02 (Ölfass blau)" + }, + "blume_gross_1": { + "poly": 285, + "collision": { + "shape": "none" + } + }, + "blume_gross_2": { + "poly": 642, + "collision": { + "shape": "none" + } + }, + "blumen_strauss": { + "poly": 755, + "collision": { + "shape": "none" + } + }, + "boulder_small": { + "poly": 96, + "collision": { + "shape": "sphere", + "radius": 0.8 + } + }, + "bruecke_holz": { + "poly": 228, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + 0, + 0.85, + 0 + ], + "size": [ + 2, + 0.3, + 3 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 0.361, + -2.806 + ], + "size": [ + 2, + 0.3, + 2.89 + ], + "rot_deg": [ + 21.8, + 0, + 0 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 0.361, + 2.806 + ], + "size": [ + 2, + 0.3, + 2.89 + ], + "rot_deg": [ + -21.8, + 0, + 0 + ] + }, + { + "shape": "box", + "pos": [ + -0.93, + 1.5, + 0 + ], + "size": [ + 0.14, + 0.12, + 3 + ] + }, + { + "shape": "box", + "pos": [ + -0.93, + 0.964, + -2.564 + ], + "size": [ + 0.14, + 0.12, + 2.69 + ], + "rot_deg": [ + 21.8, + 0, + 0 + ] + }, + { + "shape": "box", + "pos": [ + -0.93, + 0.964, + 2.564 + ], + "size": [ + 0.14, + 0.12, + 2.69 + ], + "rot_deg": [ + -21.8, + 0, + 0 + ] + }, + { + "shape": "box", + "pos": [ + 0.93, + 1.5, + 0 + ], + "size": [ + 0.14, + 0.12, + 3 + ] + }, + { + "shape": "box", + "pos": [ + 0.93, + 0.964, + -2.564 + ], + "size": [ + 0.14, + 0.12, + 2.69 + ], + "rot_deg": [ + 21.8, + 0, + 0 + ] + }, + { + "shape": "box", + "pos": [ + 0.93, + 0.964, + 2.564 + ], + "size": [ + 0.14, + 0.12, + 2.69 + ], + "rot_deg": [ + -21.8, + 0, + 0 + ] + } + ] + } + }, + "bunker_concrete": { + "poly": 96, + "collision": { + "shape": "box", + "size": [ + 6.0, + 2.8, + 4.0 + ] + } + }, + "bush_small": { + "poly": 64, + "collision": { + "shape": "sphere", + "radius": 0.8 + } + }, + "crate_metal": { + "poly": 12, + "collision": { + "shape": "box", + "size": [ + 1.0, + 1.0, + 1.0 + ] + } + }, + "crate_wood": { + "poly": 12, + "collision": { + "shape": "box", + "size": [ + 1.2, + 1.2, + 1.2 + ] + } + }, + "fass": { + "poly": 128, + "collision": { + "shape": "cylinder", + "radius": 0.31, + "height": 0.88 + } + }, + "fels_moos_block_gross": { + "poly": 46, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + 0, + 0.4, + 0 + ], + "size": [ + 2, + 0.8, + 2 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 1.1, + 0 + ], + "size": [ + 1.2, + 0.7, + 1.2 + ] + } + ] + } + }, + "fels_moos_block_hoch": { + "poly": 64, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + 0, + 0.48, + 0 + ], + "size": [ + 1.4, + 0.95, + 1.4 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 1.35, + 0 + ], + "size": [ + 0.9, + 0.95, + 0.9 + ] + } + ] + } + }, + "fels_moos_platte": { + "poly": 32, + "collision": { + "shape": "box", + "size": [ + 2, + 0.915, + 2 + ] + } + }, + "fels_moos_scharte": { + "poly": 48, + "collision": { + "shape": "box", + "size": [ + 0.968, + 0.289, + 1.823 + ] + } + }, + "fels_trocken_block": { + "poly": 36, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + 0, + 0.5, + 0 + ], + "size": [ + 2.18, + 1, + 1.63 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 1.5, + 0 + ], + "size": [ + 1.5, + 1.15, + 1 + ] + } + ] + } + }, + "fels_trocken_klein": { + "poly": 20, + "collision": { + "shape": "box", + "size": [ + 0.894, + 0.724, + 0.851 + ] + } + }, + "fels_trocken_platte": { + "poly": 48, + "collision": { + "shape": "box", + "size": [ + 3.821, + 0.662, + 2 + ] + } + }, + "felsbogen": { + "poly": 156, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + -1.9, + 1.3, + 0 + ], + "size": [ + 1.2, + 2.6, + 2.4 + ] + }, + { + "shape": "box", + "pos": [ + 1.9, + 1.3, + 0 + ], + "size": [ + 1.2, + 2.6, + 2.4 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 3.1, + 0 + ], + "size": [ + 5, + 1, + 2.4 + ] + } + ] + } + }, + "fence_metal": { + "poly": 24, + "collision": { + "shape": "box", + "size": [ + 4.0, + 1.8, + 0.15 + ] + } + }, + "gras_bueschel": { + "poly": 494, + "collision": { + "shape": "none" + } + }, + "gras_hoch": { + "poly": 326, + "collision": { + "shape": "none" + } + }, + "gras_kurz": { + "poly": 155, + "collision": { + "shape": "none" + } + }, + "gras_wispy_hoch": { + "poly": 622, + "collision": { + "shape": "none" + } + }, + "hoehleneingang": { + "poly": 204, + "collision": { + "shape": "compound", + "parts": [ + { + "shape": "box", + "pos": [ + -1.8, + 1.6, + 0 + ], + "size": [ + 1.4, + 3.2, + 4 + ] + }, + { + "shape": "box", + "pos": [ + 1.8, + 1.6, + 0 + ], + "size": [ + 1.4, + 3.2, + 4 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 2.8, + 0 + ], + "size": [ + 5, + 0.8, + 4 + ] + }, + { + "shape": "box", + "pos": [ + 0, + 1.2, + 1.8 + ], + "size": [ + 2.2, + 2.4, + 0.4 + ] + } + ] + } + }, + "pflanze_farn": { + "poly": 288, + "collision": { + "shape": "none" + } + }, + "pflanze_klee": { + "poly": 379, + "collision": { + "shape": "none" + } + }, + "pflanze_niedrig": { + "poly": 120, + "collision": { + "shape": "none" + } + }, + "pflanze_teppich": { + "poly": 48, + "collision": { + "shape": "none" + } + }, + "pflanze_teppich_gross": { + "poly": 112, + "collision": { + "shape": "none" + } + }, + "pilz_austernseitling": { + "poly": 112, + "collision": { + "shape": "none" + } + }, + "pilz_fliegenpilz": { + "poly": 80, + "collision": { + "shape": "none" + } + }, + "pilz_morchel": { + "poly": 80, + "collision": { + "shape": "none" + } + }, + "pilz_pfifferling": { + "poly": 112, + "collision": { + "shape": "none" + } + }, + "pilz_shiitake": { + "poly": 80, + "collision": { + "shape": "none" + } + }, + "pilz_steinpilz": { + "poly": 80, + "collision": { + "shape": "none" + } + }, + "rock_large": { + "poly": 128, + "collision": { + "shape": "sphere", + "radius": 1.5 + } + }, + "stein_kiesel_1": { + "poly": 136, + "collision": { + "shape": "none" + } + }, + "stein_mittel_1": { + "poly": 342, + "collision": { + "shape": "box", + "size": [ + 3.225, + 1.989, + 2.989 + ] + } + }, + "stein_mittel_2": { + "poly": 522, + "collision": { + "shape": "box", + "size": [ + 3.42, + 2.001, + 3.476 + ] + } + }, + "strauch_blumen": { + "poly": 1368, + "collision": { + "shape": "none" + } + }, + "strauch_gruen": { + "poly": 900, + "collision": { + "shape": "none" + } + }, + "tree_pine": { + "poly": 180, + "collision": { + "shape": "cylinder", + "radius": 0.4, + "height": 12.0 + } + }, + "wall_concrete": { + "poly": 12, + "collision": { + "shape": "box", + "size": [ + 4.0, + 2.5, + 0.4 + ] + } + }, + "watchtower_wood": { + "poly": 240, + "collision": { + "shape": "box", + "size": [ + 3.0, + 6.0, + 3.0 + ] + } + } } } diff --git a/tools/sync_objects.sh b/tools/sync_objects.sh new file mode 100755 index 0000000..0334bf1 --- /dev/null +++ b/tools/sync_objects.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# Editor-Sync für die Objekt-Bibliothek (Fundament A6, 19.10.2026). +# +# Was das Script macht: +# 1. Merge im Match-Server-Sibling prüfen (tools/merge_object_library.py --check) +# 2. library/objects.json in die Editor-Kopie ziehen (Editor-`note` bleibt erhalten) +# 3. Thumbnails neu rendern (tools/gen_thumbs.gd, 128 px PNG nach library/thumbs/) +# 4. Objekt-Zahl der Bibliothek ausgeben +# +# Aufruf (aus dem Editor-Repo): +# tools/sync_objects.sh # normal +# tools/sync_objects.sh --keine-thumbs # nur Kopie + Prüfung (schnell) +# SCOPEDVR_MATCH_SERVER_DIR=/pfad tools/sync_objects.sh +# +# Godot: $GODOT > $HOME/bin/godot4 > godot4 im PATH. Thumbs brauchen echtes +# Rendering (Display oder xvfb-run) — auf Slys PC als slyphax starten: +# runuser -u slyphax -- env HOME=/home/slyphax tools/sync_objects.sh +set -u +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +EDITOR_JSON="$DIR/library/objects.json" +THUMBS=1 +[ "${1:-}" = "--keine-thumbs" ] && THUMBS=0 + +# --- Match-Server-Repo finden (Sibling wie in project.godot / glb_quellen) --- +MS="${SCOPEDVR_MATCH_SERVER_DIR:-}" +if [ -z "$MS" ]; then + for k in "$DIR/../scopedvr-match-server" "$DIR/../../scopedvr-match-server"; do + [ -f "$k/library/objects.json" ] && MS="$(cd "$k" && pwd)" && break + done +fi +if [ -z "$MS" ] || [ ! -f "$MS/library/objects.json" ]; then + echo "FEHLER: Match-Server-Repo nicht gefunden — SCOPEDVR_MATCH_SERVER_DIR setzen." + exit 1 +fi +echo "Match-Server: $MS" + +# --- 1. Merge-Stand prüfen (Karten sollen nie eine ungemergte Registry ziehen) --- +if [ -f "$MS/tools/merge_object_library.py" ]; then + if ! python3 "$MS/tools/merge_object_library.py" --check; then + echo "FEHLER: objects.json passt nicht zu den Fragmenten — erst im Match-Server mergen:" + echo " python3 tools/merge_object_library.py" + exit 1 + fi +fi + +# --- 2. Kopie ziehen, Editor-`note` schützen (wie objects_pipeline.gd::_registry_sync) --- +python3 - "$MS/library/objects.json" "$EDITOR_JSON" <<'PY' +import json, sys +src, dst = sys.argv[1], sys.argv[2] +neu = json.load(open(src, encoding="utf-8")) +try: + alt = json.load(open(dst, encoding="utf-8")) + if isinstance(alt.get("note"), str) and alt["note"]: + neu["note"] = alt["note"] +except FileNotFoundError: + pass +with open(dst, "w", encoding="utf-8") as fh: + json.dump(neu, fh, ensure_ascii=False, indent=2) + fh.write("\n") +print("kopiert: %s -> %s (%d Objekte)" % (src, dst, len(neu.get("objects", {})))) +PY + +# --- 3. Thumbs rendern --- +if [ "$THUMBS" = "1" ]; then + GODOT_BIN="${GODOT:-}" + [ -z "$GODOT_BIN" ] && [ -x "$HOME/bin/godot4" ] && GODOT_BIN="$HOME/bin/godot4" + [ -z "$GODOT_BIN" ] && command -v godot4 >/dev/null 2>&1 && GODOT_BIN="godot4" + [ -z "$GODOT_BIN" ] && command -v godot >/dev/null 2>&1 && GODOT_BIN="godot" + if [ -z "$GODOT_BIN" ]; then + echo "WARNUNG: kein Godot gefunden — Thumbs übersprungen (GODOT=/pfad setzen)." + else + ARGS=(--rendering-driver opengl3 --path "$DIR" --script res://tools/gen_thumbs.gd) + if [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]; then + echo "Thumbs: $GODOT_BIN ${ARGS[*]}" + GODOT_SILENCE_ROOT_WARNING=1 "$GODOT_BIN" "${ARGS[@]}" || { echo "FEHLER: Thumb-Lauf fehlgeschlagen."; exit 1; } + else + echo "Thumbs: xvfb-run -a $GODOT_BIN ${ARGS[*]}" + GODOT_SILENCE_ROOT_WARNING=1 xvfb-run -a "$GODOT_BIN" "${ARGS[@]}" || { echo "FEHLER: Thumb-Lauf fehlgeschlagen."; exit 1; } + fi + fi +fi + +echo "FERTIG — Bibliothek im Editor: $(python3 -c "import json;print(len(json.load(open('$EDITOR_JSON'))['objects']))") Objekte, Thumbs: $(ls "$DIR/library/thumbs" 2>/dev/null | grep -c '\.png$') PNG"