Skip to content

Aseprite to GameMaker — One Sprite Strip per Tag

GameMaker cuts an image whose name ends in _stripN into N frames on import and wants one sprite per animation. Drop the .aseprite file and export for GameMaker: each tag becomes its own strip with every cell aligned on the pivot, plus a gamemaker.json with origin, speed and milliseconds. UNVERIFIED in GameMaker: no headless GameMaker exists to load the files, so the strips were cut and compared with the source only.

GameMaker does not open .aseprite files; it imports images, and a PNG named …_stripN becomes a sprite of N frames. Drop the file into Nerulio, check the tags and export for GameMaker: every tag becomes its own strip (spr_hero_attack_strip4.png), with reverse and ping-pong written out, every frame placed on its pivot so one origin fits all, and gamemaker.json with the origin, the speed and each frame's milliseconds. A GameMaker sprite has one speed, so uneven timing is kept only as data. UNVERIFIED in GameMaker: the strips were decoded and compared with the source, never loaded in GameMaker.

Drop frame images, a GIF or an .aseprite file to pack
Runs in your browser. Files are not uploaded.
Studio Pack & Export: CC0 ninja frames packed on one page and the list of all 18 export formats, each with its own Export button
The real Studio with a CC0 asset (OpenGameArt).
Exports to
  • GameMakerUNVERIFIED
  • Godot 4Verified· Godot 4.7.2
  • Unity 6Verified· Unity 6000.5.3f1
  • Phaser 3 / 4Verified· Phaser 3.90 + 4.2
  • PixiJS 8Verified· PixiJS 8.21
  • Aseprite JSONVerified· Phaser load.aseprite · PixiJS 8.21
  • .asepriteVerified· Aseprite 1.3.18
  • Spine / libGDXVerified· spine-canvas 4.2
  • Starling / Sparrow XMLVerified· Phaser 4.2
  • LÖVEVerified· LÖVE 11.5
  • DefoldBuilt· Defold bob.jar 1.13.1
  • CSS spritesVerified· Chromium
  • GIF / APNGDecoded· Pillow

From tags with timing to sprites with one speed

Aseprite keeps a whole character in one file: frames with their own durations, tags for each action with a direction and a repeat count, layers, and slices that can hold a pivot. GameMaker keeps each action as a separate sprite asset with frames, one origin and one playback speed, and the manual's strip rule lets one PNG carry all frames of that sprite.

Nerulio composites the visible layers per frame and walks each tag in playback order: a reverse tag is written backwards and a ping-pong tag of 3 frames becomes 0-1-2-1, so N counts the steps of one cycle. All frames of a tag are drawn on one common cell with the pivot on the same pixel; that pixel is the origin. File names are lower-cased with anything but letters, digits and underscores turned into _.

Timing is where the formats differ most. If every frame of a tag lasts the same, the speed is exactly 1000 ÷ ms frames per second. If not, the strip gets the tag's rate (10 FPS for Studio tags), the export warns you, and the true milliseconds stay in durationsMs. The repeat count becomes a loop flag in the JSON; the strip itself carries no timing or loop setting.

Tag
A named frame range in Aseprite with a direction and a repeat count.
Strip
One horizontal PNG with all frames of a sprite, named …_stripN.
Common cell
The frame box shared by all frames of a strip, sized so every pivot lands on one point.
durationsMs
The exact milliseconds of every frame, kept in gamemaker.json.

Example: three tags of a 32 × 32 hero

idle    4 × 125 ms, ∞         → spr_hero_idle_strip4.png     speed 1000 / 125 = 8, loop true
jump    3 × 80 ms, ping-pong   → order 0-1-2-1 → spr_hero_jump_strip4.png   speed 12.5
attack  100, 100, 150, 250 ms  → spr_hero_attack_strip4.png   speed 10 + warning, loop false

attack pivots on the 32 × 32 frames: x = 16, 16, 20, 12 (a lunge), y = 31
  cell width  = max left 20 + max right (32 − 12) 20 = 40
  cell height = 31 + (32 − 31) = 32        origin x 20, y 31
  strip = 4 × 40 = 160 × 32 px

The attack cell is wider than the 32 px frame because the pivot moves inside the drawing; placing every pivot on x 20 is what keeps the body still while the arm lunges.

What survives the conversion

In AsepriteIn Nerulio's GameMaker filesIn GameMaker
TagOne strip per tag, e.g. spr_hero_attack_strip4.pngOne sprite, cut into N frames on import
Direction reverse / ping-pongFrame order written out; N = steps of one cycleN frames in that order
Equal frame durationsplaybackSpeed = 1000 ÷ msSpeed in Frames per second
Mixed frame durationsTag rate + a warning; exact ms in durationsMsOne speed; per-frame time only through your code
Pivot slice or P pivotEvery frame on a common cell; xorigin, yoriginCustom origin
Repeat ∞ / a countloop: true / loop: false in the JSONNot set by the import; stop play-once sprites in code
Visible layersComposited; hidden layers left outFlattened frames
Hit / hurt slicesNot written (use the Generic JSON export)Collision mask set in GameMaker

What it does

  • One strip per tag named spr_<file>_<tag>_stripN.png, where N is the number of frames in playback order, reverse and ping-pong included.
  • Every cell has the same size with the pivot on the same point, so the sprite origin is identical in every frame and nothing jumps.
  • gamemaker.json per sprite: xorigin and yorigin, playbackSpeed in frames per second, loop, and durationsMs for every frame.
  • Visible layers are composited into the strip; hidden layers stay out.
  • A README with the import steps: Create Sprite › Import (or drag the PNG into the Asset Browser), then set Origin and Speed.

How to do it

  1. Drop the .aseprite file and check its tags on the Timeline.
  2. Set the pivot with P, or keep the pivot slice from the file; it becomes the origin.
  3. Open Pack & Export, choose GameMaker and export.
  4. In GameMaker, import each strip and enter the origin and speed from gamemaker.json or the README.
  5. For pixel art, turn off Interpolate colours between pixels in the Graphics section of your platform's Game Options.

Files you get

FileWhat it is for
spr_hero_attack_strip4.pngOne strip per tag, cells of equal size with the pivot on one point.
gamemaker.jsonFor each sprite: file, frame count, cell size, origin, speed in frames per second, loop, durationsMs, uniformTiming, verified: false.
README-GAMEMAKER.mdImport steps and the origin and speed of every strip.

Bring the strips into GameMaker (manual-based; not run here)

  1. Unzip the bundle: one PNG per tag. Import each one into its own sprite with the Sprite Editor's Import button, or drag it into the IDE, without renaming it.
  2. Name the sprite asset after the file without the suffix (spr_hero_attack), so your code can refer to it.
  3. Set the origin to the custom x and y from the README; for the attack above, x 20 and y 31.
  4. Set the speed to Frames per second with the README value: 8 for idle, 12.5 for jump, 10 for attack.
  5. For play-once tags (loop: false), switch back to the idle sprite in your code after the last frame.
  6. For pixel art, switch off Interpolate colours between pixels in your platform's Game Options › Graphics.

Check the result

  • spr_hero_jump has 4 frames in the order 0-1-2-1 and spr_hero_attack 4 frames of 40 × 32.
  • The origin cross stays on the feet through every frame of attack.
  • Idle cycles in 4 × 125 = 500 ms, the same as Aseprite's preview.

From .aseprite to GameMaker files

In the .asepriteIn the GameMaker export
Tag "run" with 8 framesspr_hero_run_strip8.png
Frames with equal durations, e.g. 100 msplaybackSpeed 10 frames per second
Frames with different durationsplaybackSpeed = the tag's fps, exact ms in durationsMs, and a warning
Pivot slice or a pivot set with Pxorigin / yorigin, the same point in every cell
Repeat 0 (loop forever)loop: true
Reverse or ping-pong directionwritten out as the frame order of the strip
Hit and hurt slicesnot written here (use the Generic JSON)
VerificationUNVERIFIED in GameMaker; strips decoded and compared with the source

Troubleshooting

SymptomLikely causeHow to checkFix
The attack plays faster than in AsepriteMixed durations: the sprite has one speed (10), so the 150 and 250 ms frames last 100 msuniformTiming: false and the export warningTime the frames from durationsMs in code, or give the tag equal durations in Aseprite
A ping-pong sprite has more frames than the tagThe back-and-forth order is written into the strip (3 frames → 4)Frame order 0-1-2-1Expected; play the sprite forwards and do not reverse it again
Idle and attack have different originsEach strip has its own cell, so the numbers differ even when the anchor is the same point of the artCompare the README values per stripEnter each sprite's own origin; do not copy one origin to all
A layer is missing or a hidden one appearsOnly the layers visible in the file are compositedLayer visibility in AsepriteShow or hide the layer in Aseprite (or on Nerulio's timeline) and export again
The file name differs from the tag nameNames are lower-cased and spaces or symbols become _ ("Attack 2" → attack_2)The README lists every fileUse the file name as written, or rename the tag in Aseprite
Something is off in GameMaker itselfThis export was never loaded in GameMaker—Nerulio cannot check GameMaker behaviour; compare with the manual, and report the case so it can be fixed

Other ways to do it

OptionWhen it is the better choice
Aseprite's File › Export Sprite Sheet as a horizontal strip per tag, renamed to _stripNYou already own Aseprite and a tag has one pivot and even timing; you set origin and speed by hand.
A sprite sheet you already haveGameMaker strips from a sprite sheet.
Another engine with per-frame timingAseprite to Godot keeps every frame's duration.

Engine exports and how each was checked

"Verified" means the exported files were loaded by the real engine or tool on real CC0 assets and the result was compared with the source. Anything that was not loaded is labelled as such.

TargetFilesCheck
Godot 4.tres SpriteFrames · .tscn AnimatedSprite2D · .png.importVerified Godot 4.7.2Loaded by Godot; every animation frame drawn and compared with the source file. The scene uses Nearest filtering; rotation is never used.
Unity 6.unity.json · Editor/NerulioSpriteImporter.cs · AnimationClipVerified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked.
Phaser 3 / 4atlas JSON (multiatlas) · .anims.jsonVerified Phaser 3.90 + 4.2Frames and animations drawn by both versions.
PixiJS 8spritesheet JSON · animations · anchor · meta.scaleVerified PixiJS 8.21Rotated and multi-page atlases included.
Aseprite JSONhash / array · frameTags · slicesVerified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count.
.asepritelayers · tags · durations · slicesVerified Aseprite 1.3.18Opened and rendered by the Aseprite command line.
Spine / libGDX.atlasVerified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run.
Starling / Sparrow XMLXML per pageVerified Phaser 4.2Phaser 3.90 draws trimmed XML frames wrongly (its own bug); the "Sparrow XML (Phaser 3)" preset turns trim off and passes in 3.90 and 4.2.
LÖVELua quads · nerulio_atlas.lua · main.luaVerified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper.
Defold.atlas · .tilesourceBuilt Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back.
GameMakerspr_<name>_stripN.png · gamemaker.jsonUNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them.
CSS sprites.css · preview .htmlVerified ChromiumEvery class drawn from the shipped stylesheet.
GIF / APNGone file per animationDecoded PillowEvery frame and delay decoded again after export; APNG is exact.

Evidence

Exports: 49 runs in the real engines on real CC0 assets, 47 pass — the 2 failures are Phaser 3.90's trimmed-XML bug, which the Phaser 3 preset avoids. Packer head-to-head on 5 real frame sets (CodeAndWeb free web packer, GAPTools, free-tex-packer): smallest sheet on all 5 with rotation allowed, 4 of 5 without; every frame restored pixel-exact.

Limits

  • UNVERIFIED in GameMaker: the strips were decoded and compared with the source frames only.
  • One speed per sprite: uneven timing survives only in gamemaker.json.
  • No hitboxes or collision shapes in the GameMaker files.
  • Polygon (mesh) packing is not offered: none of the verified engines draws a mesh atlas from exported data.
  • GameMaker strips are UNVERIFIED in GameMaker itself.
  • Scale variants (@0.5x–@4x) use nearest-neighbour only.
  • Trimmed Starling XML is drawn wrongly by Phaser 3.90; use the "Sparrow XML (Phaser 3)" preset there.

Versions and sources

Checked: the GameMaker strips decode with Pillow and every cell equals its source frame; the .aseprite reader reopened 231 real files in Aseprite 1.3.18 with the same tags, durations and pixels. Not checked: loading anything in GameMaker, which has no headless mode in the verification setup. The strip naming, import routes, origin, speed modes and the interpolation option follow the GameMaker manual.

Official documentation used

Questions

Has anyone opened these strips in GameMaker?

Not in our checks. GameMaker has no headless mode we could run, so the target is labelled UNVERIFIED. What was checked: the strips decode (Pillow) and every cell matches its source frame; the naming follows the GameMaker manual's sprite strip rule.

My tag has frames of different lengths. What does GameMaker get?

A GameMaker sprite has one playback speed. When a tag's durations differ, the strip uses the tag's fps and the export warns you; the exact milliseconds stay in durationsMs if you want to time frames in code.

Do hitboxes come along?

Not in the GameMaker files, which hold the image, origin and timing only. Boxes and collision polygons are in the Generic JSON export.

Is it free, and do I need an account?

Everything on these pages is free and works without an account. There is no watermark and no export that is held back.

Are my sprites uploaded?

No. The Studio decodes, packs and exports in this browser tab. Projects are autosaved in the browser (IndexedDB) and can be saved as a .nerulio file.

Does it need Aseprite or an engine plugin installed?

No. .aseprite files are read and written in the browser, and each engine bundle carries what that engine needs (for Godot, the import settings and scene; for Unity and the Godot TileSet, a small editor script).