moonpixelanimkit

MoonBit-native pixel animation asset parser, validator, runtime model, and export toolkit.

aseprite
sprite
animation
pixel-art
game-dev
moonbit
moon add WangYF0829/moonpixelanimkit@0.1.1
Download zip
Version
0.1.1
License
MIT
Last updated
17 days ago
Downloads
4
README

#MoonPixelAnimKit

MoonPixelAnimKit 是一个 MoonBit 原生像素动画资产解析、校验与运行时工具链,面向 2D 游戏、Canvas/WebAssembly 可视化、教学示例和自动化资源流水线。

项目 v1 支持 Aseprite 导出的 sprite sheet JSON,并提供 .ase/.aseprite 文件基础结构解析、动画 clip 构建、帧级 hitbox/hurtbox/collision box 提取、资源校验、Phaser/Canvas 适配数据导出和 CLI smoke 示例。

#项目状态

  • MoonBit 主体实现:JSON 解析、二进制结构解析、校验、runtime、导出、报告和测试。
  • 当前版本:0.1.1
  • Mooncakes 包名:WangYF0829/moonpixelanimkit
  • 许可证:MIT。
  • 参考说明:本项目不移植 Aseprite 源码,不打包 Aseprite 程序,只依据公开文件格式说明、导出 JSON 结构和自制 fixture 实现兼容解析。

#安装

Mooncakes 安装命令:

moon add WangYF0829/moonpixelanimkit

本地开发:

moon check moon test moon run examples/basic moon run cmd/main moon run cmd/main -- --json moon run cmd/main -- --ase

#最小示例

let parsed = @moonpixelanimkit.parse_sprite_sheet_json(json_text)
if parsed.ok {
let library = @moonpixelanimkit.build_animation_library(parsed.sheet)
let player = @moonpixelanimkit.AnimationPlayer::new(library, clip_name="idle")
let next = player.step(120)
println(next.current_frame().unwrap().name)
}

#核心功能

功能API
解析 Aseprite sprite sheet JSONparse_sprite_sheet_json(input)
校验资源结构validate_sprite_sheet(sheet) / validate_sprite_sheet_json(input)
解析 .ase/.aseprite 基础结构parse_aseprite_binary(bytes)
构建动画库build_animation_library(sheet)
动画播放推进AnimationPlayer::step(delta_ms)
提取 hitbox/hurtbox/collision boxbuild_frame_box_table(sheet)
导出 runtime manifestexport_runtime_manifest(sheet)
导出 Phaser 动画计划export_phaser_animation_plan(sheet)
导出 Canvas draw planbuild_canvas_draw_plan(sheet)
统计 atlas 与动画时长analyze_sprite_sheet(sheet)
构建帧时间轴build_sheet_timeline(sheet) / build_tag_timeline(sheet, tag)
检查游戏素材策略check_asset_policy(sheet, policy)
检查导出目标兼容性check_export_compatibility(sheet) / validate_sprite_sheet_json_for_export(input)
检查帧命名序列group_frame_names(sheet) / inspect_frame_name_groups(sheet)
CLI 报告moon run cmd/main

#支持范围

已支持:

  • Aseprite JSON frames 数组形式和对象形式。
  • framedurationrotatedtrimmedspriteSourceSizesourceSize
  • meta.imagemeta.sizemeta.frameTagsmeta.layersmeta.slices
  • .ase/.aseprite header、frame header、layer chunk、cel chunk、tags chunk、palette chunk、slice chunk 的元数据解析。
  • forward、reverse、pingpong 动画方向映射。
  • 动画 clip、player、frame sampling。
  • 资源错误与警告报告,包括重复帧名、非法矩形、非法 tag 范围、缺失 box slice 等。
  • atlas 利用率、duration bucket、帧时间轴和素材策略检查。
  • Phaser、Canvas 和 runtime manifest 导出前兼容性预检。
  • hero_run_0 这类帧命名序列分组、编号缺口检查和命名报告。

暂不支持:

  • 不做 Aseprite 编辑器,不做播放器。
  • v1 不解压 zlib compressed cel 像素,只识别并报告压缩 cel。
  • 不做图像滤镜、像素 diff、纹理打包算法。
  • 不替代 Phaser、Canvas、Godot、Unity 的渲染系统。

#工程验收

moon check moon build moon test moon run cmd/main moon run cmd/main -- --json moon run cmd/main -- --ase moon run examples/basic moon publish --dry-run

CI 已覆盖检查、构建、测试、CLI text/json/ase smoke 和 basic example。

#开源合规

本项目采用 MIT 许可证。测试数据均为代码内自制 fixture,不包含第三方图片、音频、字体或 Aseprite 官方二进制文件。Aseprite 是第三方软件,本项目仅实现对其公开导出格式和公开文件结构的兼容读取。

#
AnimationClip

pub(all) struct AnimationClip {
name : String
direction : TagDirection
loop_mode : LoopMode
frames : Array[AnimationFrameRef]
total_duration_ms : Int
} derive(Eq,
Debug
)

#
AnimationClip::frame_at

fn AnimationClip::frame_at(self : AnimationClip, index : Int) -> AnimationFrameRef?

#
AnimationClip::frame_count

fn AnimationClip::frame_count(self : AnimationClip) -> Int

#
AnimationClip::is_valid

fn AnimationClip::is_valid(self : AnimationClip) -> Bool

#
AnimationClip::new

fn AnimationClip::new(name : String, frames : Array[AnimationFrameRef], direction? : TagDirection, loop_mode? : LoopMode) -> AnimationClip

#
AnimationFrameRef

pub(all) struct AnimationFrameRef {
name : String
frame_index : Int
duration_ms : Int
rect : Rect
} derive(Eq,
Debug
)

#
AnimationFrameRef::from_frame

fn AnimationFrameRef::from_frame(frame : FrameInfo) -> AnimationFrameRef

#
AnimationLibrary

pub(all) struct AnimationLibrary {
texture_image : String
atlas_size : Size
clips : Array[AnimationClip]
} derive(Eq,
Debug
)

#
AnimationLibrary::empty

#
AnimationLibrary::find_clip

fn AnimationLibrary::find_clip(self : AnimationLibrary, name : String) -> AnimationClip?

#
AnimationPlayer

pub(all) struct AnimationPlayer {
library : AnimationLibrary
clip_name : String
frame_cursor : Int
elapsed_in_frame_ms : Int
playing : Bool
completed : Bool
forward : Bool
} derive(Eq,
Debug
)

#
AnimationPlayer::current_clip

fn AnimationPlayer::current_clip(self : AnimationPlayer) -> AnimationClip?

#
AnimationPlayer::current_frame

fn AnimationPlayer::current_frame(self : AnimationPlayer) -> AnimationFrameRef?

#
AnimationPlayer::new

fn AnimationPlayer::new(library : AnimationLibrary, clip_name? : String) -> AnimationPlayer

#
AnimationPlayer::pause

#
AnimationPlayer::play

#
AnimationPlayer::reset

#
AnimationPlayer::set_clip

fn AnimationPlayer::set_clip(self : AnimationPlayer, clip_name : String) -> AnimationPlayer

#
AnimationPlayer::step

fn AnimationPlayer::step(self : AnimationPlayer, delta_ms : Int) -> AnimationPlayer

#
AseChunk

pub(all) struct AseChunk {
frame_index : Int
offset : Int
size : Int
kind : Int
kind_name : String
name : String
layer_index : Int
cel_type : Int
opacity : Int
child_level : Int
extra : String
} derive(Eq,
Debug
)

#
AseChunk::end_offset

fn AseChunk::end_offset(self : AseChunk) -> Int

#
AseChunk::new

fn AseChunk::new(frame_index : Int, offset : Int, size : Int, kind : Int, kind_name : String, name? : String, layer_index? : Int, cel_type? : Int, opacity? : Int, child_level? : Int, extra? : String) -> AseChunk

#
AseFile

pub(all) struct AseFile {
header : AseHeader
frames : Array[AseFrame]
source_length : Int
} derive(Eq,
Debug
)

#
AseFile::chunk_count

fn AseFile::chunk_count(self : AseFile) -> Int

#
AseFile::empty

fn AseFile::empty() -> AseFile

#
AseFrame

pub(all) struct AseFrame {
index : Int
offset : Int
size : Int
duration_ms : Int
chunk_count : Int
chunks : Array[AseChunk]
} derive(Eq,
Debug
)

#
AseFrame::new

fn AseFrame::new(index : Int, offset : Int, size : Int, duration_ms : Int, chunk_count : Int, chunks : Array[AseChunk]) -> AseFrame

#
AseHeader

pub(all) struct AseHeader {
file_size : Int
frame_count : Int
width : Int
height : Int
color_depth : Int
flags : Int
speed_ms : Int
transparent_index : Int
color_count : Int
pixel_width : Int
pixel_height : Int
} derive(Eq,
Debug
)

#
AseHeader::canvas_size

fn AseHeader::canvas_size(self : AseHeader) -> Size

#
AseHeader::empty

fn AseHeader::empty() -> AseHeader

#
AseParseResult

pub(all) struct AseParseResult {
ok : Bool
file : AseFile
error : PixelAnimError
} derive(Eq,
Debug
)

#
AseParseResult::failure

#
AseParseResult::success

fn AseParseResult::success(file : AseFile) -> AseParseResult

#
AssetPolicy

pub(all) struct AssetPolicy {
min_frames : Int
max_frames : Int
require_tags : Bool
require_box_slices : Bool
allow_rotated_frames : Bool
max_frame_duration_ms : Int
max_atlas_waste_milli : Int
} derive(Eq,
Debug
)

#
AssetPolicy::game_sprite_default

fn AssetPolicy::game_sprite_default() -> AssetPolicy

#
AssetPolicy::relaxed

fn AssetPolicy::relaxed() -> AssetPolicy

#
AssetReport

pub(all) struct AssetReport {
parse_ok : Bool
validation_ok : Bool
frame_count : Int
tag_count : Int
slice_count : Int
layer_count : Int
duration_ms : Int
fps : Int
manifest_bytes : Int
message : String
} derive(Eq,
Debug
)

#
AssetReport::empty

fn AssetReport::empty() -> AssetReport

#
BoxKind

pub(all) enum BoxKind {
BoxHit
BoxHurt
BoxCollision
BoxOrigin
BoxCustom(String)
} derive(Eq,
Debug
)

#
BoxKind::from_slice_name

fn BoxKind::from_slice_name(name : String) -> BoxKind

#
BoxKind::to_string

fn BoxKind::to_string(self : BoxKind) -> String

#
ByteReader

pub(all) struct ByteReader {
bytes : Array[Int]
offset : Int
} derive(Eq,
Debug
)

Non-owning reader over byte arrays. Values outside 0..255 are masked so generated fixtures and host-provided byte arrays behave consistently.

#
ByteReader::ascii_fixed_at

fn ByteReader::ascii_fixed_at(self : ByteReader, offset : Int, size : Int) -> String

#
ByteReader::ascii_z_at

fn ByteReader::ascii_z_at(self : ByteReader, offset : Int, limit : Int) -> String

#
ByteReader::at

fn ByteReader::at(bytes : Array[Int], offset : Int) -> ByteReader

#
ByteReader::byte_at

fn ByteReader::byte_at(self : ByteReader, offset : Int) -> Int

#
ByteReader::can_read

fn ByteReader::can_read(self : ByteReader, count : Int) -> Bool

#
ByteReader::fourcc_at

fn ByteReader::fourcc_at(self : ByteReader, offset : Int) -> String

#
ByteReader::length

fn ByteReader::length(self : ByteReader) -> Int

#
ByteReader::matches_u16

fn ByteReader::matches_u16(self : ByteReader, offset : Int, value : Int) -> Bool

#
ByteReader::new

fn ByteReader::new(bytes : Array[Int]) -> ByteReader

#
ByteReader::remaining

fn ByteReader::remaining(self : ByteReader) -> Int

#
ByteReader::slice

fn ByteReader::slice(self : ByteReader, offset : Int, size : Int) -> Array[Int]

#
ByteReader::slice_can_read

fn ByteReader::slice_can_read(self : ByteReader, offset : Int, count : Int) -> Bool

#
ByteReader::u16_le_at

fn ByteReader::u16_le_at(self : ByteReader, offset : Int) -> Int

#
ByteReader::u32_le_at

fn ByteReader::u32_le_at(self : ByteReader, offset : Int) -> Int

#
CanvasDrawCommand

pub(all) struct CanvasDrawCommand {
frame_name : String
source : Rect
destination : Rect
duration_ms : Int
} derive(Eq,
Debug
)

#
CanvasDrawCommand::new

fn CanvasDrawCommand::new(frame_name : String, source : Rect, destination : Rect, duration_ms : Int) -> CanvasDrawCommand

#
DurationBucket

pub(all) struct DurationBucket {
name : String
min_ms : Int
max_ms : Int
count : Int
} derive(Eq,
Debug
)

#
DurationBucket::new

fn DurationBucket::new(name : String, min_ms : Int, max_ms : Int, count? : Int) -> DurationBucket

#
ExportCompatibilityOptions

pub(all) struct ExportCompatibilityOptions {
target : RuntimeTarget
require_frame_tags : Bool
require_layer_metadata : Bool
require_slice_boxes : Bool
require_hitbox : Bool
require_hurtbox : Bool
require_collision_box : Bool
require_image_name : Bool
allow_rotated_frames : Bool
allow_trimmed_frames : Bool
max_atlas_width : Int
max_atlas_height : Int
min_frame_duration_ms : Int
max_frame_duration_ms : Int
} derive(Eq,
Debug
)

#
ExportCompatibilityOptions::canvas2d

#
ExportCompatibilityOptions::phaser3

#
ExportCompatibilityOptions::runtime_manifest

#
ExportCompatibilityOptions::strict_game_asset

#
FrameBox

pub(all) struct FrameBox {
frame_index : Int
frame_name : String
name : String
kind : BoxKind
bounds : Rect
pivot : Point
has_pivot : Bool
} derive(Eq,
Debug
)

#
FrameBox::new

fn FrameBox::new(frame_index : Int, frame_name : String, name : String, kind : BoxKind, bounds : Rect, pivot? : Point, has_pivot? : Bool) -> FrameBox

#
FrameBoxTable

pub(all) struct FrameBoxTable {
boxes : Array[FrameBox]
} derive(Eq,
Debug
)

#
FrameBoxTable::count_kind

fn FrameBoxTable::count_kind(self : FrameBoxTable, kind : BoxKind) -> Int

#
FrameBoxTable::empty

#
FrameBoxTable::find_named

fn FrameBoxTable::find_named(self : FrameBoxTable, frame_index : Int, name : String) -> FrameBox?

#
FrameBoxTable::for_frame

fn FrameBoxTable::for_frame(self : FrameBoxTable, frame_index : Int) -> Array[FrameBox]

#
FrameInfo

pub(all) struct FrameInfo {
name : String
index : Int
rect : Rect
rotated : Bool
trimmed : Bool
sprite_source_size : Rect
source_size : Size
duration_ms : Int
} derive(Eq,
Debug
)

#
FrameInfo::duration_seconds

fn FrameInfo::duration_seconds(self : FrameInfo) -> Double

#
FrameInfo::is_valid

fn FrameInfo::is_valid(self : FrameInfo) -> Bool

#
FrameInfo::new

fn FrameInfo::new(name : String, index : Int, rect : Rect, duration_ms : Int, rotated? : Bool, trimmed? : Bool, sprite_source_size? : Rect, source_size? : Size) -> FrameInfo

#
FrameNameGroup

pub(all) struct FrameNameGroup {
stem : String
count : Int
first_frame_index : Int
last_frame_index : Int
numeric_count : Int
min_number : Int
max_number : Int
} derive(Eq,
Debug
)

#
FrameNameGroup::has_number_gap

fn FrameNameGroup::has_number_gap(self : FrameNameGroup) -> Bool

#
FrameNameGroup::is_numbered

fn FrameNameGroup::is_numbered(self : FrameNameGroup) -> Bool

#
FrameNameGroup::new

fn FrameNameGroup::new(stem : String, frame : FrameInfo) -> FrameNameGroup

#
FrameNameParts

pub(all) struct FrameNameParts {
original : String
stem : String
suffix_number : Int
has_number : Bool
} derive(Eq,
Debug
)

#
FrameNameParts::new

fn FrameNameParts::new(original : String, stem : String, suffix_number? : Int, has_number? : Bool) -> FrameNameParts

#
FrameTag

pub(all) struct FrameTag {
name : String
from_index : Int
to_index : Int
direction : TagDirection
color : String
user_data : String
} derive(Eq,
Debug
)

#
FrameTag::contains_index

fn FrameTag::contains_index(self : FrameTag, index : Int) -> Bool

#
FrameTag::frame_count

fn FrameTag::frame_count(self : FrameTag) -> Int

#
FrameTag::new

fn FrameTag::new(name : String, from_index : Int, to_index : Int, direction? : TagDirection, color? : String, user_data? : String) -> FrameTag

#
FrameTimelineEntry

pub(all) struct FrameTimelineEntry {
frame_index : Int
frame_name : String
start_ms : Int
end_ms : Int
duration_ms : Int
} derive(Eq,
Debug
)

#
FrameTimelineEntry::contains

fn FrameTimelineEntry::contains(self : FrameTimelineEntry, ms : Int) -> Bool

#
FrameTimelineEntry::new

fn FrameTimelineEntry::new(frame_index : Int, frame_name : String, start_ms : Int, duration_ms : Int) -> FrameTimelineEntry

#
IssueSeverity

pub(all) enum IssueSeverity {
IssueError
IssueWarning
} derive(Eq,
Debug
)

#
IssueSeverity::to_string

fn IssueSeverity::to_string(self : IssueSeverity) -> String

#
LayerInfo

pub(all) struct LayerInfo {
name : String
opacity : Int
blend_mode : String
visible : Bool
} derive(Eq,
Debug
)

#
LayerInfo::is_visible

fn LayerInfo::is_visible(self : LayerInfo) -> Bool

#
LayerInfo::new

fn LayerInfo::new(name : String, opacity? : Int, blend_mode? : String, visible? : Bool) -> LayerInfo

#
LoopMode

pub(all) enum LoopMode {
LoopOnce
LoopRepeat
LoopPingPong
} derive(Eq,
Debug
)

#
LoopMode::to_string

fn LoopMode::to_string(self : LoopMode) -> String

#
NamingIssue

pub(all) struct NamingIssue {
stem : String
code : String
message : String
} derive(Eq,
Debug
)

#
NamingIssue::new

fn NamingIssue::new(stem : String, code : String, message : String) -> NamingIssue

#
PixelAnimError

pub(all) struct PixelAnimError {
kind : PixelAnimErrorKind
path : String
offset : Int
message : String
} derive(Eq,
Debug
)

#
PixelAnimError::code

fn PixelAnimError::code(self : PixelAnimError) -> String

#
PixelAnimError::is_error

fn PixelAnimError::is_error(self : PixelAnimError) -> Bool

#
PixelAnimError::new

fn PixelAnimError::new(kind : PixelAnimErrorKind, message : String, path? : String, offset? : Int) -> PixelAnimError

#
PixelAnimError::none

#
PixelAnimErrorKind

pub(all) enum PixelAnimErrorKind {
ErrorNone
ErrorJsonParse
ErrorExpectedObject
ErrorMissingField
ErrorInvalidField
ErrorInvalidFrame
ErrorInvalidTag
ErrorInvalidSlice
ErrorInvalidLayer
ErrorNotAseprite
ErrorUnsupportedChunk
ErrorChunkOutOfBounds
ErrorTruncatedData
ErrorUnsupportedCompression
ErrorRuntimeState
ErrorInvalidArgument
} derive(Eq,
Debug
)

Error categories used by the JSON parser, binary parser, validator, runtime builder, exporter, and CLI report model.

#
PixelAnimErrorKind::code

fn PixelAnimErrorKind::code(self : PixelAnimErrorKind) -> String

#
PixelAnimParseResult

pub(all) struct PixelAnimParseResult {
ok : Bool
sheet : SpriteSheet
error : PixelAnimError
} derive(Eq,
Debug
)

#
PixelAnimParseResult::failure

#
PixelAnimParseResult::success

#
Point

pub(all) struct Point {
x : Int
y : Int
} derive(Eq,
Debug
)

#
Point::new

fn Point::new(x : Int, y : Int) -> Point

#
Rect

pub(all) struct Rect {
x : Int
y : Int
width : Int
height : Int
} derive(Eq,
Debug
)

#
Rect::area

fn Rect::area(self : Rect) -> Int

#
Rect::bottom

fn Rect::bottom(self : Rect) -> Int

#
Rect::contains_point

fn Rect::contains_point(self : Rect, point : Point) -> Bool

#
Rect::contains_rect

fn Rect::contains_rect(self : Rect, other : Rect) -> Bool

#
Rect::empty

fn Rect::empty() -> Rect

#
Rect::intersects

fn Rect::intersects(self : Rect, other : Rect) -> Bool

#
Rect::is_positive

fn Rect::is_positive(self : Rect) -> Bool

#
Rect::new

fn Rect::new(x : Int, y : Int, width : Int, height : Int) -> Rect

#
Rect::right

fn Rect::right(self : Rect) -> Int

#
ReportFormat

pub(all) enum ReportFormat {
ReportText
ReportJson
} derive(Eq,
Debug
)

#
RuntimeTarget

pub(all) enum RuntimeTarget {
TargetRuntimeManifest
TargetCanvas2D
TargetPhaser3
TargetGenericEngine
} derive(Eq,
Debug
)

Runtime/export targets that commonly consume Aseprite animation metadata.

#
RuntimeTarget::expects_external_renderer

fn RuntimeTarget::expects_external_renderer(self : RuntimeTarget) -> Bool

#
RuntimeTarget::requires_box_metadata_by_default

fn RuntimeTarget::requires_box_metadata_by_default(self : RuntimeTarget) -> Bool

#
RuntimeTarget::to_string

fn RuntimeTarget::to_string(self : RuntimeTarget) -> String

#
Size

pub(all) struct Size {
width : Int
height : Int
} derive(Eq,
Debug
)

#
Size::area

fn Size::area(self : Size) -> Int

#
Size::empty

fn Size::empty() -> Size

#
Size::is_positive

fn Size::is_positive(self : Size) -> Bool

#
Size::new

fn Size::new(width : Int, height : Int) -> Size

#
SliceInfo

pub(all) struct SliceInfo {
name : String
color : String
keys : Array[SliceKey]
} derive(Eq,
Debug
)

#
SliceInfo::has_keys

fn SliceInfo::has_keys(self : SliceInfo) -> Bool

#
SliceInfo::key_for_frame

fn SliceInfo::key_for_frame(self : SliceInfo, frame_index : Int) -> SliceKey?

#
SliceInfo::new

fn SliceInfo::new(name : String, keys : Array[SliceKey], color? : String) -> SliceInfo

#
SliceKey

pub(all) struct SliceKey {
frame : Int
bounds : Rect
center : Rect
pivot : Point
has_center : Bool
has_pivot : Bool
} derive(Eq,
Debug
)

#
SliceKey::is_valid

fn SliceKey::is_valid(self : SliceKey) -> Bool

#
SliceKey::new

fn SliceKey::new(frame : Int, bounds : Rect, center? : Rect, pivot? : Point, has_center? : Bool, has_pivot? : Bool) -> SliceKey

#
SpriteSheet

pub(all) struct SpriteSheet {
frames : Array[FrameInfo]
meta : SpriteSheetMeta
source_length : Int
} derive(Eq,
Debug
)

#
SpriteSheet::duration_ms

fn SpriteSheet::duration_ms(self : SpriteSheet) -> Int

#
SpriteSheet::duration_seconds

fn SpriteSheet::duration_seconds(self : SpriteSheet) -> Double

#
SpriteSheet::empty

fn SpriteSheet::empty() -> SpriteSheet

#
SpriteSheet::find_frame

fn SpriteSheet::find_frame(self : SpriteSheet, name : String) -> FrameInfo?

#
SpriteSheet::find_tag

fn SpriteSheet::find_tag(self : SpriteSheet, name : String) -> FrameTag?

#
SpriteSheet::frame_at

fn SpriteSheet::frame_at(self : SpriteSheet, index : Int) -> FrameInfo?

#
SpriteSheet::frame_count

fn SpriteSheet::frame_count(self : SpriteSheet) -> Int

#
SpriteSheetMeta

pub(all) struct SpriteSheetMeta {
app : String
version : String
image : String
format : String
scale : String
size : Size
frame_tags : Array[FrameTag]
layers : Array[LayerInfo]
slices : Array[SliceInfo]
} derive(Eq,
Debug
)

#
SpriteSheetMeta::empty

#
SpriteSheetStats

pub(all) struct SpriteSheetStats {
frame_count : Int
tag_count : Int
slice_count : Int
layer_count : Int
atlas_area : Int
used_area : Int
utilization_milli : Int
trimmed_frames : Int
rotated_frames : Int
total_duration_ms : Int
shortest_duration_ms : Int
longest_duration_ms : Int
average_duration_ms : Int
} derive(Eq,
Debug
)

#
SpriteSheetStats::empty

#
SpriteSheetStats::utilization_percent

fn SpriteSheetStats::utilization_percent(self : SpriteSheetStats) -> Double

#
TagDirection

pub(all) enum TagDirection {
DirectionForward
DirectionReverse
DirectionPingPong
DirectionPingPongReverse
DirectionUnknown(String)
} derive(Eq,
Debug
)

#
TagDirection::from_string

fn TagDirection::from_string(value : String) -> TagDirection

#
TagDirection::is_pingpong

fn TagDirection::is_pingpong(self : TagDirection) -> Bool

#
TagDirection::to_string

fn TagDirection::to_string(self : TagDirection) -> String

#
ValidationIssue

pub(all) struct ValidationIssue {
severity : IssueSeverity
path : String
code : String
message : String
} derive(Eq,
Debug
)

#
ValidationIssue::error

fn ValidationIssue::error(message : String, path? : String, code? : String) -> ValidationIssue

#
ValidationIssue::warning

fn ValidationIssue::warning(message : String, path? : String, code? : String) -> ValidationIssue

#
ValidationReport

pub(all) struct ValidationReport {
ok : Bool
issues : Array[ValidationIssue]
error_count : Int
warning_count : Int
} derive(Eq,
Debug
)

#
ValidationReport::empty

#
ValidationReport::new

#
ValidationReport::summary

fn ValidationReport::summary(self : ValidationReport) -> String

#
analytics_summary_text

fn analytics_summary_text(sheet : SpriteSheet) -> String

#
analyze_sprite_sheet

fn analyze_sprite_sheet(sheet : SpriteSheet) -> SpriteSheetStats

#
analyze_sprite_sheet_json

fn analyze_sprite_sheet_json(input : String) -> AssetReport

#
ase_binary_report

fn ase_binary_report(bytes : Array[Int], format? : ReportFormat) -> String

#
ase_file_supports_runtime_manifest

fn ase_file_supports_runtime_manifest(file : AseFile) -> Bool

#
ase_has_compressed_cels

fn ase_has_compressed_cels(file : AseFile) -> Bool

#
asset_report_from_json

fn asset_report_from_json(input : String, format? : ReportFormat) -> String

#
boxes_intersect

fn boxes_intersect(a : FrameBox, b : FrameBox) -> Bool

#
build_animation_library

fn build_animation_library(sheet : SpriteSheet) -> AnimationLibrary

#
build_canvas_draw_plan

fn build_canvas_draw_plan(sheet : SpriteSheet, scale? : Int) -> Array[CanvasDrawCommand]

#
build_duration_buckets

fn build_duration_buckets(sheet : SpriteSheet) -> Array[DurationBucket]

#
build_frame_box_table

fn build_frame_box_table(sheet : SpriteSheet) -> FrameBoxTable

#
build_sheet_timeline

fn build_sheet_timeline(sheet : SpriteSheet) -> Array[FrameTimelineEntry]

#
build_tag_timeline

fn build_tag_timeline(sheet : SpriteSheet, tag_name : String) -> Array[FrameTimelineEntry]

#
canvas_command_to_text

fn canvas_command_to_text(command : CanvasDrawCommand) -> String

#
check_asset_policy

fn check_asset_policy(sheet : SpriteSheet, policy : AssetPolicy) -> ValidationReport

#
check_export_compatibility

fn check_export_compatibility(sheet : SpriteSheet, options? : ExportCompatibilityOptions) -> ValidationReport

#
clip_to_json

fn clip_to_json(clip : AnimationClip) -> String

#
collect_ase_chunk_names

fn collect_ase_chunk_names(file : AseFile) -> Array[String]

#
collect_frame_names

fn collect_frame_names(sheet : SpriteSheet) -> Array[String]

#
collect_slice_names

fn collect_slice_names(sheet : SpriteSheet) -> Array[String]

#
collect_tag_names

fn collect_tag_names(sheet : SpriteSheet) -> Array[String]

#
estimate_clip_fps

fn estimate_clip_fps(clip : AnimationClip) -> Int

#
export_canvas_draw_plan_text

fn export_canvas_draw_plan_text(sheet : SpriteSheet, scale? : Int) -> String

#
export_phaser_animation_plan

fn export_phaser_animation_plan(sheet : SpriteSheet) -> String

#
export_runtime_manifest

fn export_runtime_manifest(sheet : SpriteSheet) -> String

#
export_runtime_manifest_from_parts

fn export_runtime_manifest_from_parts(sheet : SpriteSheet, library : AnimationLibrary, boxes : FrameBoxTable) -> String

#
first_intersection

fn first_intersection(boxes : Array[FrameBox], kind_a : BoxKind, kind_b : BoxKind) -> (FrameBox, FrameBox)?

#
fixture_aseprite_binary

fn fixture_aseprite_binary() -> Array[Int]

#
fixture_aseprite_json

fn fixture_aseprite_json() -> String

#
fixture_catalog_passed

fn fixture_catalog_passed() -> Bool

#
fixture_invalid_sprite_json

fn fixture_invalid_sprite_json() -> String

#
fixture_malformed_json

fn fixture_malformed_json() -> String

#
fixture_not_aseprite_binary

fn fixture_not_aseprite_binary() -> Array[Int]

#
fixture_not_object_json

fn fixture_not_object_json() -> String

#
fixture_object_frames_json

fn fixture_object_frames_json() -> String

#
fixture_truncated_aseprite_binary

fn fixture_truncated_aseprite_binary() -> Array[Int]

#
frame_box_to_json

fn frame_box_to_json(box : FrameBox) -> String

#
frame_ref_to_json

fn frame_ref_to_json(frame : AnimationFrameRef) -> String

#
group_frame_names

fn group_frame_names(sheet : SpriteSheet) -> Array[FrameNameGroup]

#
has_required_box_kinds

fn has_required_box_kinds(table : FrameBoxTable, require_hit? : Bool, require_hurt? : Bool, require_collision? : Bool) -> Bool

#
infer_frame_rate

fn infer_frame_rate(sheet : SpriteSheet) -> Int

#
inspect_fixture_report

fn inspect_fixture_report(format? : ReportFormat) -> String

#
inspect_frame_name_groups

fn inspect_frame_name_groups(sheet : SpriteSheet) -> Array[NamingIssue]

#
library_smoke_passed

fn library_smoke_passed() -> Bool

#
merge_validation_reports

fn merge_validation_reports(first : ValidationReport, second : ValidationReport) -> ValidationReport

#
naming_report_text

fn naming_report_text(sheet : SpriteSheet) -> String

#
parse_aseprite_binary

fn parse_aseprite_binary(bytes : Array[Int]) -> AseParseResult

Parse an .ase or .aseprite byte array and return structural metadata. Pixel decompression is intentionally not exposed in v1.

#
parse_aseprite_file

fn parse_aseprite_file(bytes : Array[Int]) -> AseParseResult

#
parse_sprite_sheet_json

fn parse_sprite_sheet_json(input : String) -> PixelAnimParseResult

Parse Aseprite sprite sheet JSON exported with --format json-array or the default object form. This is the primary high-level entry point.

#
parse_sprite_sheet_value

fn parse_sprite_sheet_value(json : Json, source_length? : Int) -> PixelAnimParseResult

fn recommended_aseprite_export_flags(options? : ExportCompatibilityOptions) -> String

#
rect_to_json

fn rect_to_json(rect : Rect) -> String

#
sample_clip_at

fn sample_clip_at(clip : AnimationClip, elapsed_ms : Int) -> AnimationFrameRef?

#
sheet_has_rotated_frames

fn sheet_has_rotated_frames(sheet : SpriteSheet) -> Bool

#
sheet_uses_trimmed_frames

fn sheet_uses_trimmed_frames(sheet : SpriteSheet) -> Bool

#
size_to_json

fn size_to_json(size : Size) -> String

#
split_frame_name

fn split_frame_name(name : String) -> FrameNameParts

#
timeline_frame_at

fn timeline_frame_at(entries : Array[FrameTimelineEntry], elapsed_ms : Int, looped? : Bool) -> FrameTimelineEntry?

#
timeline_total_duration

fn timeline_total_duration(entries : Array[FrameTimelineEntry]) -> Int

#
validate_ase_file

fn validate_ase_file(file : AseFile) -> ValidationReport

#
validate_sprite_sheet

fn validate_sprite_sheet(sheet : SpriteSheet) -> ValidationReport

#
validate_sprite_sheet_json

fn validate_sprite_sheet_json(input : String) -> ValidationReport

Validate without forcing callers to keep the parsed value.

#
validate_sprite_sheet_json_for_export

fn validate_sprite_sheet_json_for_export(input : String, options? : ExportCompatibilityOptions) -> ValidationReport

#
validation_report_has_code

fn validation_report_has_code(report : ValidationReport, code : String) -> Bool