Skip to content

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.

Drop a sprite sheet, numbered frames, a GIF / APNG or an .aseprite file
Runs in your browser. Files are not uploaded.
Studio Sprite workspace: a 48 px samurai sheet with the detected grid, 60 frames in 10 animations, before Apply
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

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 ms

If 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

  1. Drop the sheet and press Apply (or drop frames, a GIF or an .aseprite file).
  2. Name one tag per animation and set the pivots.
  3. In Pack & Export choose GameMaker.
  4. Import each strip in GameMaker and set the origin from gamemaker.json.

Files you get

Pack & Export › GameMaker writes (for a file called hero):

FileWhat it is for
spr_hero_run_strip6.pngOne horizontal strip per animation; the name carries the frame count.
gamemaker.jsonPer sprite: file, frames, cell width and height, xorigin, yorigin, playbackSpeed in frames per second, loop, durationsMs, and verified: false.
README-GAMEMAKER.mdThe import steps and, for every strip, its frame count, cell size, origin and speed.

In GameMaker (from the GameMaker manual; not run here)

  1. 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 _stripN suffix is what makes GameMaker cut it into N frames.
  2. Check that the sprite shows the frame count and cell size listed in the README, for example 6 frames of 64 × 64.
  3. Set the origin to the custom x and y from the README or gamemaker.json, for example x 32, y 64.
  4. Set the speed to Frames per second and enter the value from the README, for example 8.
  5. Choose the collision mask mode the sprite needs (Automatic, Full Image or Manual).
  6. 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 run takes 6 × 125 = 750 ms.

Troubleshooting

SymptomLikely causeHow to checkFix
The whole strip arrives as one wide frameThe file was renamed and lost _stripN (a download may add " (1)")Look at the file name before importingRename it back to …_stripN.png with the frame count
Frames are cut through the middleThe N in the name does not match the frames in the imageStrip width ÷ N should equal the cell width in the READMEUse the name Nerulio wrote; it carries the real count
The character hops when the frames changeThe origin was left at the default top-left or set per frame by eyeOrigin fields in the Sprite EditorEnter the README origin; Nerulio already put every pivot on that point
An uneven animation plays evenlyA GameMaker sprite has one speed; the export used the tag rate and warnedThe export notes and uniformTiming: false in gamemaker.jsonDrive the frames from durationsMs in code, or even out the durations before export
The animation racesSpeed set as Frames per game frame instead of Frames per secondThe speed mode next to the valueSwitch to Frames per second
Pixel art looks soft in the gameInterpolate colours between pixels is onGame Options › your platform › GraphicsTurn it off. Nerulio cannot test any of these GameMaker settings: it has no GameMaker to run

Other ways to do it

OptionWhen it is the better choice
GameMaker's Image Editor: Convert to Frames or Import Strip ImageAn even grid whose frames already share one anchor; you type the frame count, size and offsets in GameMaker.
Start from the .aseprite fileTags become strips and their timing is kept in the JSON: Aseprite to GameMaker.
Separate PNG framesAnother 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.

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

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).