Add two-stage charged-crystal demo and original art set.

This commit is contained in:
2026-08-13 13:18:41 +08:00
commit e9f5f81f46
686 changed files with 25601 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
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