GameMaker Sprite Strip Maker — _stripN per Animation
GameMaker wants one sprite per animation, and its strip importer reads the frame count from _stripN in the file name. This export cuts one strip per tag with every cell aligned on the pivot — built the way that importer cuts strips, but not loaded in GameMaker here.
GameMaker imports a horizontal strip whose file name ends in _stripN as a sprite of N frames, each strip width ÷ N wide: spr_hero_run_strip6.png at 384 × 64 becomes six 64 × 64 frames. It wants one sprite per animation, each with one origin and one speed. Nerulio cuts a sprite sheet (or GIF, loose frames, .aseprite) into one such strip per animation, every frame aligned on its pivot, plus gamemaker.json with origin and speed. UNVERIFIED in GameMaker: these files were never loaded in GameMaker; the naming and the steps follow the GameMaker manual.

- 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
How GameMaker reads a strip
In GameMaker a sprite asset is one animation: its frames, an origin (top-left by default, or a preset or custom point), a playback speed in Frames per second or Frames per game frame, and a collision mask. The manual's strip rule: frames laid out horizontally from the left, the file name ending in _stripN, and each frame the strip width divided by N. A strip can be brought in with the Sprite Editor's Import button or by dragging it into the IDE.
A full sheet with several rows is not a strip. GameMaker's Image Editor can split one image itself (Convert to Frames, or Import Strip Image), where you give the number of frames, the frame width and height and offsets. That is the manual route; it takes the numbers you type and places nothing on a pivot.
A sprite has one origin, so every frame must have its anchor point on the same pixel of its cell, or the character hops when the frames change. Nerulio draws every frame's full canvas onto one common cell per animation, shifted so its pivot lands on the same point, and that point becomes the origin in gamemaker.json and the README. The cell is as wide as the largest distance left of the pivot plus the largest distance right of it.
A sprite also has one speed. When all frames of an animation last the same, Nerulio writes speed = 1000 ÷ ms; when they differ it writes the animation's rate (10 FPS for Studio tags), warns you and keeps every frame's milliseconds in durationsMs for your own code.
- _stripN
- File name suffix telling GameMaker to cut the image into N frames.
- Origin
- The sprite's anchor point, set as a preset or custom x / y in the Sprite Editor.
- Frames per second / per game frame
- The two speed modes of a GameMaker sprite.
- Convert to Frames
- GameMaker Image Editor command that splits one image by frame count, size and offset.
Worked example: one row becomes one strip
Sheet row "run": 6 frames of 64 × 64, 125 ms each, pivot bottom centre (32, 64)
Nerulio strip: spr_hero_run_strip6.png 6 × 64 = 384 px wide, 64 px high
GameMaker cut: 384 / 6 = 64 px per frame (the manual's strip rule)
Origin x 32, y 64 Speed 1000 / 125 = 8 frames per second
Row "attack": 4 frames, 100, 100, 150, 250 ms → a sprite has one speed
playbackSpeed 10 (the tag rate) + a warning; durationsMs keeps 100, 100, 150, 250
at 10 frames per second GameMaker shows 4 × 100 = 400 ms instead of 600 msIf the whole attack must keep its rhythm, time the frames yourself from durationsMs, or give all its frames the same length before export.
What it does
- One PNG per animation named spr_<name>_<tag>_stripN.png, N = frame count.
- Cells aligned on the pivot, so the origin is the same in every frame.
- gamemaker.json with each sprite's origin, speed and per-frame milliseconds.
- UNVERIFIED in GameMaker: there is no headless GameMaker to test with; the strips were cut and compared with the source.
How to do it
- Drop the sheet and press Apply (or drop frames, a GIF or an .aseprite file).
- Name one tag per animation and set the pivots.
- In Pack & Export choose GameMaker.
- Import each strip in GameMaker and set the origin from gamemaker.json.
Files you get
Pack & Export › GameMaker writes (for a file called hero):
| File | What it is for |
|---|---|
spr_hero_run_strip6.png | One horizontal strip per animation; the name carries the frame count. |
gamemaker.json | Per sprite: file, frames, cell width and height, xorigin, yorigin, playbackSpeed in frames per second, loop, durationsMs, and verified: false. |
README-GAMEMAKER.md | The import steps and, for every strip, its frame count, cell size, origin and speed. |
In GameMaker (from the GameMaker manual; not run here)
- For each strip, create a sprite and use Import in the Sprite Editor, or drag the PNG into the IDE. Keep the file name: the
_stripNsuffix is what makes GameMaker cut it into N frames. - Check that the sprite shows the frame count and cell size listed in the README, for example 6 frames of 64 × 64.
- Set the origin to the custom x and y from the README or
gamemaker.json, for example x 32, y 64. - Set the speed to Frames per second and enter the value from the README, for example 8.
- Choose the collision mask mode the sprite needs (Automatic, Full Image or Manual).
- For pixel art, turn off Interpolate colours between pixels in the Graphics section of your target platform's Game Options; the manual lists it as on by default.
Check the result
- The Sprite Editor shows N frames, each the strip width ÷ N wide.
- The origin cross sits on the feet in every frame of the sprite.
- The preview runs at the speed from the README, and one cycle of
runtakes 6 × 125 = 750 ms.
Troubleshooting
| Symptom | Likely cause | How to check | Fix |
|---|---|---|---|
| The whole strip arrives as one wide frame | The file was renamed and lost _stripN (a download may add " (1)") | Look at the file name before importing | Rename it back to …_stripN.png with the frame count |
| Frames are cut through the middle | The N in the name does not match the frames in the image | Strip width ÷ N should equal the cell width in the README | Use the name Nerulio wrote; it carries the real count |
| The character hops when the frames change | The origin was left at the default top-left or set per frame by eye | Origin fields in the Sprite Editor | Enter the README origin; Nerulio already put every pivot on that point |
| An uneven animation plays evenly | A GameMaker sprite has one speed; the export used the tag rate and warned | The export notes and uniformTiming: false in gamemaker.json | Drive the frames from durationsMs in code, or even out the durations before export |
| The animation races | Speed set as Frames per game frame instead of Frames per second | The speed mode next to the value | Switch to Frames per second |
| Pixel art looks soft in the game | Interpolate colours between pixels is on | Game Options › your platform › Graphics | Turn it off. Nerulio cannot test any of these GameMaker settings: it has no GameMaker to run |
Other ways to do it
| Option | When it is the better choice |
|---|---|
| GameMaker's Image Editor: Convert to Frames or Import Strip Image | An even grid whose frames already share one anchor; you type the frame count, size and offsets in GameMaker. |
| Start from the .aseprite file | Tags become strips and their timing is kept in the JSON: Aseprite to GameMaker. |
| Separate PNG frames | Another tool or engine wants one file per frame: sprite sheet to PNG frames. |
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.
| Target | Files | Check |
|---|---|---|
| Godot 4 | .tres SpriteFrames · .tscn AnimatedSprite2D · .png.import | Verified 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 · AnimationClip | Verified Unity 6000.5.3f1Batch mode: sprite rects, pivots, pixels, clip keys and durations checked. |
| Phaser 3 / 4 | atlas JSON (multiatlas) · .anims.json | Verified Phaser 3.90 + 4.2Frames and animations drawn by both versions. |
| PixiJS 8 | spritesheet JSON · animations · anchor · meta.scale | Verified PixiJS 8.21Rotated and multi-page atlases included. |
| Aseprite JSON | hash / array · frameTags · slices | Verified Phaser load.aseprite · PixiJS 8.21Tags keep their direction and repeat count. |
| .aseprite | layers · tags · durations · slices | Verified Aseprite 1.3.18Opened and rendered by the Aseprite command line. |
| Spine / libGDX | .atlas | Verified spine-canvas 4.2Every region drawn by the Spine runtime, rotated and trimmed; libGDX itself was not run. |
| Starling / Sparrow XML | XML per page | Verified 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ÖVE | Lua quads · nerulio_atlas.lua · main.lua | Verified LÖVE 11.5Every frame drawn and every animation stepped through the shipped helper. |
| Defold | .atlas · .tilesource | Built Defold bob.jar 1.13.1Built by Defold's command-line builder; the built texture's UVs were read back. |
| GameMaker | spr_<name>_stripN.png · gamemaker.json | UNVERIFIEDNot loaded in GameMaker (no headless GameMaker). The strips are cut the way its strip importer cuts them. |
| CSS sprites | .css · preview .html | Verified ChromiumEvery class drawn from the shipped stylesheet. |
| GIF / APNG | one file per animation | Decoded PillowEvery frame and delay decoded again after export; APNG is exact. |
Evidence
GIF decoder: 408 of 408 frames identical to Pillow on 29 real GIFs; APNG 132 of 132 on 16 files. .aseprite: 231 corpus files imported, re-written and reopened in Aseprite 1.3.18 with the same tags, durations and pixels (231/231). 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.
Limits
- UNVERIFIED in GameMaker: no GameMaker ran on these files; only the strips were decoded (Pillow) and compared with the source frames.
- Hitboxes and collision polygons are not written for GameMaker.
- One speed per sprite: per-frame durations only survive as data in gamemaker.json.
- A grid or island guess is a preview with a confidence; nothing is cut until you press Apply, and every choice has one-click alternatives.
- .aseprite files whose layers do not compose exactly (e.g. group opacity) are imported flattened, and the Import panel says why.
- Rotated frames in an imported atlas stay rotated; their export is UNVERIFIED.
- Images up to 32,768 px per side (268 million pixels), subject to your browser's memory.
Versions and sources
What was checked: the GameMaker strips of a 288 × 480 samurai sheet decoded with Pillow, with every cell equal to its source frame. GameMaker itself was not run: there is no headless GameMaker in the verification setup, so the Studio labels this target UNVERIFIED. The _stripN rule, the import routes, the origin and speed settings and the interpolation option come from the GameMaker manual.
Official documentation used
Questions
Was this tested in GameMaker?
No. GameMaker cannot run headless here, so the export is labelled UNVERIFIED; the strips were cut the way GameMaker's strip importer cuts them and compared with the source frames.
Does GameMaker read the timing?
Strips carry no timing; the speed and per-frame milliseconds are in gamemaker.json for you to enter.
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).