extends SceneTree const RECIPE_PATH := "res://data/recipe-book.json" const CATALOG_PATH := "res://data/art-catalog.json" const MAIN_SCRIPT_PATH := "res://src/main.gd" func _initialize() -> void: var failures: Array[String] = [] var recipe := _read_json(RECIPE_PATH) var catalog := _read_json(CATALOG_PATH) if recipe.is_empty(): failures.append("Could not read recipe book.") if catalog.is_empty(): failures.append("Could not read art catalog.") if failures.is_empty(): failures.append_array(_check_items(recipe, catalog)) failures.append_array(_check_machines(recipe, catalog)) failures.append_array(_check_files(catalog)) failures.append_array(_check_main_uses_generated_art()) if failures.is_empty(): print("ART_CATALOG_SMOKE_OK items=%d machines=%d logistics=%d materials=%d" % [ (catalog.get("items", []) as Array).size(), (catalog.get("machines", []) as Array).size(), (catalog.get("logistics", []) as Array).size(), (catalog.get("materials", []) as Array).size(), ]) quit(0) else: for failure in failures: push_error(failure) quit(1) func _check_items(recipe: Dictionary, catalog: Dictionary) -> Array[String]: var failures: Array[String] = [] var by_id := _index_by_id(catalog.get("items", [])) for item_variant in recipe.get("items", []): var item: Dictionary = item_variant var item_id := String(item.get("id", "")) if not by_id.has(item_id): failures.append("Recipe item %s has no art catalog entry." % item_id) continue var entry: Dictionary = by_id[item_id] if String(entry.get("icon", "")).is_empty() or String(entry.get("render", "")).is_empty(): failures.append("Art catalog item %s is missing icon or render." % item_id) return failures func _check_machines(recipe: Dictionary, catalog: Dictionary) -> Array[String]: var failures: Array[String] = [] var by_id := _index_by_id(catalog.get("machines", [])) for machine_variant in recipe.get("machines", []): var machine: Dictionary = machine_variant var machine_id := String(machine.get("id", "")) if not by_id.has(machine_id): failures.append("Recipe machine %s has no art catalog entry." % machine_id) continue if String(by_id[machine_id].get("render", "")).is_empty(): failures.append("Art catalog machine %s is missing a render." % machine_id) return failures func _check_files(catalog: Dictionary) -> Array[String]: var failures: Array[String] = [] var paths: Array[String] = [] for item_variant in catalog.get("items", []): var item: Dictionary = item_variant paths.append(String(item.get("icon", ""))) paths.append(String(item.get("render", ""))) for machine_variant in catalog.get("machines", []): paths.append(String((machine_variant as Dictionary).get("render", ""))) for logistics_variant in catalog.get("logistics", []): paths.append(String((logistics_variant as Dictionary).get("render", ""))) for material_variant in catalog.get("materials", []): paths.append(String((material_variant as Dictionary).get("albedo", ""))) for path in paths: if path.is_empty() or not FileAccess.file_exists("res://" + path.trim_prefix("res://")): failures.append("Missing generated art file: %s" % path) return failures func _check_main_uses_generated_art() -> Array[String]: var failures: Array[String] = [] var file := FileAccess.open(MAIN_SCRIPT_PATH, FileAccess.READ) if file == null: failures.append("Could not read main scene script.") return failures var source := file.get_as_text() if source.find("kenney_factory_kit") >= 0: failures.append("Playable scene still references Kenney Factory Kit models.") if source.find("assets/generated/renders/") < 0: failures.append("Playable scene does not load generated renders.") return failures func _index_by_id(rows: Array) -> Dictionary: var lookup := {} for row_variant in rows: var row: Dictionary = row_variant lookup[String(row.get("id", ""))] = row return lookup func _read_json(path: String) -> Dictionary: var file := FileAccess.open(path, FileAccess.READ) if file == null: return {} var parsed: Variant = JSON.parse_string(file.get_as_text()) if typeof(parsed) != TYPE_DICTIONARY: return {} return parsed