Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,20 @@ Open `godot/project.godot` in Godot 4. The scene plays the delivered per-frame t
godot --headless --path examples/godot --editor --quit
godot --headless --path examples/godot -- --smoke
```
Validated with Godot 4.7.2. The smoke check verifies frame advancement.
Validated with Godot 4.7.2. For a full-cycle check on a **fresh import**:

```sh
python3 scripts/import_sprite.py --engine godot --zip examples/source/walk.zip --out /tmp/dreamlayer-godot-check
godot --headless --editor --path /tmp/dreamlayer-godot-check --quit
godot --headless --path /tmp/dreamlayer-godot-check --script "$PWD/scripts/validate_godot.gd"
```

The validator checks seven frame textures, dimensions, transparent pixels,
per-frame durations, animation advancement, and looping. It exits nonzero on
failure or after a 30-second watchdog timeout; use it with short example clips.
For the included ZIP it verifies a 2.83-second cycle. Engine source APIs were
also inspected in Godot 4.8-dev; that source build has **not** been compiled or
runtime-tested. No engine-source checkout is required to import the assets.

## Unity
Copy `unity/Assets/DreamLayerDemo` into a new Unity 2D project. After scripts compile, choose **Tools > DreamLayer > Create sprite demo**, then press Play. The player preserves each frame's duration. Unity compilation/playback is pending; these files are not a verified Unity release.
Expand Down
69 changes: 69 additions & 0 deletions scripts/validate_godot.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Run against a fresh import: godot --headless --path PROJECT --script /absolute/path/validate_godot.gd
extends SceneTree

var failures: Array[String] = []
var frame_changes := 0
var loops := 0
var finished := false

func check(condition: bool, message: String) -> void:
if not condition:
failures.append(message)
push_error(message)

func _initialize() -> void:
watchdog.call_deferred()
run.call_deferred()

func watchdog() -> void:
await create_timer(30.0).timeout
push_error("Validation exceeded 30 seconds")
quit(1)

func run() -> void:
var packed = load("res://main.tscn")
if packed == null:
push_error("Missing imported main scene")
quit(1)
return
var scene = packed.instantiate()
root.add_child(scene)
await process_frame
var manifest = JSON.parse_string(FileAccess.get_file_as_string("res://frames/manifest.json"))
var actor: AnimatedSprite2D = scene.get("actor") as AnimatedSprite2D
if actor == null or not manifest is Dictionary:
push_error("Missing actor or manifest")
quit(1)
return
var frames: SpriteFrames = actor.sprite_frames
check(frames.get_frame_count("dreamlayer") == manifest.frames.size(), "Frame count mismatch")
check(is_equal_approx(frames.get_animation_speed("dreamlayer"), 1.0), "Timing expects 1 FPS base")
check(frames.get_animation_loop("dreamlayer") == manifest.loop, "Loop flag mismatch")
var duration := 0.0
for i in range(manifest.frames.size()):
var seconds: float = manifest.durations_ms[i] / 1000.0
duration += seconds
check(is_equal_approx(frames.get_frame_duration("dreamlayer", i), seconds), "Frame duration mismatch")
var texture: Texture2D = frames.get_frame_texture("dreamlayer", i)
check(texture != null, "Missing texture")
if texture != null:
check(texture.get_width() == manifest.width and texture.get_height() == manifest.height, "Frame dimensions mismatch")
var image: Image = texture.get_image()
check(image != null and image.detect_alpha() != Image.ALPHA_NONE, "Missing transparent pixels")
actor.frame_changed.connect(func(): frame_changes += 1)
actor.animation_looped.connect(func(): loops += 1)
actor.animation_finished.connect(func(): finished = true)
# Full cycle verifies loop/end behavior; checking a single frame after a fixed
# delay can accidentally inspect the same frame on a healthy looping sprite.
actor.stop()
actor.play("dreamlayer")
await create_timer(duration + 0.35).timeout
if manifest.frames.size() > 1:
check(frame_changes > 0, "Animation never advanced")
if manifest.loop:
check(loops >= 1 and actor.is_playing(), "Animation did not loop")
else:
check(finished and not actor.is_playing(), "Animation did not finish")
if failures.is_empty():
print("DREAMLAYER_VALIDATED frames=", manifest.frames.size(), " dimensions=", manifest.width, "x", manifest.height, " cycle_seconds=", duration, " loops=", loops, " frame_changes=", frame_changes)
quit(0 if failures.is_empty() else 1)
Loading