A MoonBit pipeline for Aseprite JSON sprite animation assets.
moon check --target all --deny-warn
moon test --target wasm
moon run cmd/main///|
test {
let json =
#|{"frames": [{"filename": "hero_0", "frame": {"x": 0, "y": 0, "w": 16, "h": 16}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x": 0, "y": 0, "w": 16, "h": 16}, "sourceSize": {"w": 16, "h": 16}, "duration": 100}], "meta": {"image": "hero.png", "size": {"w": 16, "h": 16}, "frameTags": [], "slices": []}}
let sheet = parse_aseprite_json(json)
let report = quality_report(sheet)
inspect(report.passed, content="true")
}| Layer | Responsibility |
|---|---|
| Parser | Decode array/hash Aseprite JSON and normalize optional fields |
| Model | Typed rectangles, frames, tags, slices, clips, and state machines |
| Atlas | Row, compact-row, checked, and power-of-two packing plans |
| Validation | Geometry, timeline, naming, slice, and collision diagnostics |
| Export | Generic bundle, quality report, Godot, Phaser, and MoonBit manifests |
| CLI | Runnable preview and a stable integration smoke test |
moon check --target all --deny-warn
moon test --target wasm
moon test --target wasm-gc
moon test --target js
moon fmt --check
moon info
moon run cmd/mainpub struct AnimationMachine {
initial : String
clips : Array[AnimationClip]
transitions : Array[StateTransition]
} derive(Eq, ToJson, Debug, FromJson)fn AnimationMachine::transition_target(self : AnimationMachine, from~ : String, event~ : String) -> String?fn AnimationMachine::with_transition(self : AnimationMachine, from~ : String, event~ : String, to~ : String) -> AnimationMachinepub struct AtlasProfile {
name : String
max_width : Int
padding : Int
strategy : AtlasStrategy
objective : AtlasObjective
mobile : Bool
} derive(Eq, ToJson, Debug, FromJson)pub struct AtlasRecommendation {
best : AtlasCandidate
candidates : Array[AtlasCandidate]
objective : AtlasObjective
} derive(Eq, ToJson, Debug, FromJson)fn AtlasRecommendation::candidate_named(self : AtlasRecommendation, strategy : AtlasStrategy) -> AtlasCandidate?pub struct EngineProfile {
name : String
target : RuntimeTarget
max_texture : Int
max_frames : Int
padding : Int
scale : Int
power_of_two : Bool
} derive(Eq, ToJson, Debug, FromJson)pub struct ExportBundle {
sheet : SpriteSheet
atlas : AtlasPlan
machine : AnimationMachine
nine_patches : Array[NinePatch]
diagnostics : Array[Diagnostic]
} derive(Eq, ToJson, Debug, FromJson)pub struct RuleFinding {
rule : ValidationRule
diagnostic : Diagnostic
} derive(Eq, ToJson, Debug, FromJson)pub struct RuntimeAdapter {
target : RuntimeTarget
extension_name : String
format_name : String
supports_nine_patch : Bool
supports_collisions : Bool
} derive(Eq, ToJson, Debug, FromJson)fn RuntimeAdapter::validate_bundle(self : RuntimeAdapter, bundle : ExportBundle) -> Array[Diagnostic]pub struct RuntimeManifest {
target : RuntimeTarget
name : String
extension : String
payload : String
diagnostics : Array[Diagnostic]
} derive(Eq, ToJson, Debug, FromJson)pub struct RuntimeOptions {
target : RuntimeTarget
indent : Int
include_diagnostics : Bool
include_slices : Bool
} derive(Eq, ToJson, Debug, FromJson)pub struct RuntimePreset {
name : String
target : RuntimeTarget
extension : String
indent : Int
include_diagnostics : Bool
include_slices : Bool
} derive(Eq, ToJson, Debug, FromJson)fn SpriteSheet::with_box(self : SpriteSheet, filename~ : String, name~ : String, rect~ : Rect) -> SpriteSheetfn TransformOptions::with_duration_scale(self : TransformOptions, percent : Int) -> TransformOptionsfn ValidationResult::findings_for(self : ValidationResult, rule : ValidationRule) -> Array[RuleFinding]pub struct WorkflowArtifact {
name : String
kind : ArtifactKind
payload : String
bytes : Int
} derive(Eq, ToJson, Debug, FromJson)pub struct WorkflowOptions {
name : String
mode : WorkflowMode
atlas_strategy : AtlasStrategy
max_width : Int
padding : Int
runtime : RuntimeTarget
include_diagnostics : Bool
} derive(Eq, ToJson, Debug, FromJson)fn WorkflowOptions::with_atlas(self : WorkflowOptions, strategy : AtlasStrategy, max_width : Int, padding : Int) -> WorkflowOptionsfn WorkflowOptions::with_runtime(self : WorkflowOptions, runtime : RuntimeTarget) -> WorkflowOptionspub struct WorkflowReport {
name : String
mode : WorkflowMode
artifacts : Array[WorkflowArtifact]
errors : Int
warnings : Int
frame_count : Int
animation_count : Int
passed : Bool
} derive(Eq, ToJson, Debug, FromJson)fn atlas_candidates_for_widths(sheet : SpriteSheet, widths : Array[Int], padding : Int) -> Array[AtlasCandidate]fn best_width_for_occupancy(sheet : SpriteSheet, widths : Array[Int], padding : Int) -> AtlasCandidate?fn pack_strategy(sheet : SpriteSheet, strategy~ : AtlasStrategy, options? : AtlasOptions) -> AtlasPlanfn pack_strategy_checked(sheet : SpriteSheet, strategy~ : AtlasStrategy, options? : AtlasOptions) -> AtlasPlan raisefn recommend_atlas(sheet : SpriteSheet, max_width~ : Int, padding~ : Int, objective? : AtlasObjective) -> AtlasRecommendationfn runtime_manifest(bundle : ExportBundle, name : String, target : RuntimeTarget) -> RuntimeManifestfn runtime_manifest_named(bundle : ExportBundle, name : String, target_name : String) -> RuntimeManifestA MoonBit pipeline for Aseprite JSON sprite animation assets.