Skip to content

Make a Spriter creature

This guide takes a creature from a Spriter project to a local mod. You need the installed Windows game, its ExampleMod/ folder, Mod Prep, a text editor, and Spriter for creating or editing animations. You do not need the game's source code, Visual Studio, or a content compiler.

Spriter Pro is separate software. This guide uses its built-in atlas export, which BrashMonkey documents as a Pro feature. You can complete the first test with the already exported Jacked Kangit before buying or opening Spriter. Demina and its XNA prerequisite are for a different animation format; they are not needed for this workflow.

1. Get a working creature into your own pack

Start with Make your first mod and create a Mod Prep project with UniqueModName set to my_creatures. Use a separate editable project folder and Install / Refresh Test Copy when testing.

From ExampleMod/ beside the game executable, copy these into that project:

  • creature_jackedkangit.json
  • The complete Creatures/JackedKangit/ directory, including its Lua script and Animations/ files

Rename the copied JSON file to creature_my_kangit.json. Inside its Creature object, change UniqueIdentifier to my_kangit and Name to My Kangit. Keep the other fields unchanged for this first test. The new full creature ID is my_creatures.my_kangit. The asset folder and Lua table can keep their original names; they are not the creature's saved identity.

Use your own permanent IDs for a released pack. Changing the mod name or creature identifier later makes a different creature to saved games. Give creatures distinct Name values too; registration data is also looked up by name. Keep the original Example Mod disabled during this first test.

Press Validate, install the test copy, enable it in Mods, and restart the game. In a disposable single-player world, open chat and enter:

/creative
/spawn my_creatures.my_kangit

The creature spawns near your character and uses the sample's behavior. The included script is hostile, so allow room to observe it. A successful spawn checks your pack identity, copied files and paths before you change its art. The starter item created by Mod Prep can remain during this test.

2. Prepare your animation project

Keep your editable Spriter project and original image pieces outside the export folder. The shipped Jacked Kangit is an already packed example:

Creatures/JackedKangit/
  jackedkangit.lua
  Animations/
    jacked_kangit.scml
    atlas.json
    image.png

Its SCML and atlas are useful references for names, pivots and the output layout. Keep your own unpacked art/project as your editable master when making a new rig.

Use a single entity in the exported SCML. The game selects the first entity; there is no creature JSON field for choosing another entity in that file. Author the unflipped rig facing left; the game mirrors it for right-facing movement. Keep the feet close to the project's ground origin so body alignment is easy to adjust.

The copied Lua script and the game's movement actions expect these clip names:

Clip Loop? Purpose
idle Yes Standing and the default pose
walk Yes Walking actions
run Yes Running actions
bite, swipe No The sample's two attacks
flinch No The sample's damage reaction
death No The sample's death animation

Keep this spelling and casing when following the example. A different script can request other clips, but changing names requires updating every request. Give one-shots a useful duration and turn off looping in Spriter; a looping attack will not send the completion callback used to release the script's attack lock. The shipped flinch is a very short pose, not a full reaction animation.

Use clear, unique names for the visible sprite timelines you intend to use as hit locations. The example names include jacked_kangit_head and jacked_kangit_mandible. A skeletal bone label and the attached sprite timeline's name can differ; the collision fields below should use the actual sprite timeline names. Keep the rig hierarchy consistent between clips so the game can blend their poses.

3. Export SCML with a texture atlas

Use the atlas workflow described in BrashMonkey's export instructions:

  1. Save the editable project. Choose File → Generate spritesheets for project images.
  2. Select a separate export folder, outside the editable project's image directory.
  3. Enable save spritesheeted project, so the export includes an SCML clone that refers to the atlas. A PNG alone is insufficient.
  4. Start with Never generate multiple spritesheets. Choose an atlas size large enough to fit the art; 1024 is the documented default, not a required game size. Increase it if the export cannot fit.
  5. Export, then copy the resulting SCML, atlas JSON and PNG together into your mod's creature animation directory. Point AnimationPath at this exported SCML clone.

Use SCML (XML), rather than SCON or a baked frame-strip export. The runtime plays the rig and its timelines. It reads ordinary PNG and JSON files directly; there is no XNB conversion or game rebuild step for these mod assets.

Keep the exported filenames and relative layout consistent:

Reference Must resolve to
Creature JSON AnimationPath The SCML file, relative to the mod root
SCML atlas entry (<atlas><i name="atlas.json"/></atlas> in the example) The atlas JSON, relative to the SCML directory
SCML folder atlas="0" The matching atlas entry's ID
Atlas JSON meta.image The PNG, relative to the SCML directory
Each SCML image file name An exact key in that atlas's frames object

The names atlas.json and image.png are the example's choices, not mandatory filenames. Keeping all three output files together is the simplest layout. Use relative paths and matching case throughout; do not leave drive-letter paths to your art folder.

The atlas must use a JSON object/hash for frames, keyed by image names. An exporter option that writes frames as an array is a different format. Retain the export's frame rectangles, original sizes, trim offsets and rotation flags. The game uses that metadata to place trimmed/rotated pieces correctly; resizing or rearranging the packed PNG alone breaks it. Export at the original image scale (1×); the atlas's meta.scale does not rescale the rig at runtime.

The loader can read multiple atlas entries, but each SCML folder must select the correct atlas and all its named images must exist there. Start with one atlas before attempting a larger layout. Use an atlas for creature releases: loose-image loading does not provide the same sprite-based hit detection. Keep soundlines out of this first export. Spriter's embedded sounds are not the mod's ordinary loose-audio workflow; add audio through the documented World API instead.

4. Connect the art and behavior

In your copied creature_my_kangit.json, keep the Creature root and update the fields for your exported rig:

Field What to set
AnimationPath Pack-relative path to the exported SCML, including .scml
DefaultAnimation idle for this example
LuaScriptPath Pack-relative path to the creature's Lua script
BodyWidth / BodyHeight Physics box width/height in game pixels
AnimationOffsetX / AnimationOffsetY Move the drawing relative to that box
ConfigJumpHeight, WalkSpeed, RunSpeed, ConfigViewRange Movement and target-search settings used by the creature
CritBoneNames Sprite timeline names that receive critical hits
MeleeBones Named melee contact locations and optional offsets
RegistrationData Health, melee damage, description and codex category
DropData Optional item drops; use full registered item IDs

The rig is drawn at the bottom center of the physics box, plus the animation offsets. The animation's visible outline does not resize that box. Check feet, walls and steps in-game; adjust the box for movement and the offsets for art alignment. The sample's numeric values fit Jacked Kangit and are not universal defaults for a new creature.

Keep the sample Lua script for the first art replacement. It already imports Content/Lua/Creature, creates the creatureTable expected by the loader, and implements movement, targeting, attacks, damage and death. When adapting it, preserve that setup and use the allowlisted Creature API. AnimationPath supplies art; it does not generate AI behavior.

The sample calls self.creature:PerformAction("IDLE"), "WALK_LEFT" / "WALK_RIGHT", and "RUN_LEFT" / "RUN_RIGHT" for locomotion. It starts an attack with, for example, self.creature:TransitionToAnimation("bite", 0.1); the 0.1 is a transition in seconds. Update the script's clip names and fallback lock durations when your exported attack lengths change. Its World:getTimeDeltaMS() timers use milliseconds.

Melee contact and attack timing

For the sample rig, a melee location looks like this inside MeleeBones:

{ "BoneName": "jacked_kangit_head", "OffsetX": -28.5, "OffsetY": 15.2600002 }

Use a sprite timeline that is present during the strike. The offset moves the contact point in game axes from that sprite's animated position; X mirrors with facing, but the offset does not rotate with the limb. Use zero offsets first and tune them in both facings.

Requesting bite, swipe or attack opens melee collision immediately, including during the transition into the clip. This is the sample's default contact model. Spriter event keys can close and reopen the window as the clip advances:

Where in the clip Event name
At the beginning of playback disableCollisions
At the first damaging pose enableCollisions
After the last damaging pose disableCollisions

Use event timelines named enableCollisions and disableCollisions, with keys at those points; these are not sound labels or ordinary bone names. The script can also receive them through keyframeTriggerEvent. A time-zero disable event is processed when playback advances, so it does not guarantee a harmless initial blend. Test contact during the transition as well as the visible strike.

For a fully event-controlled windup, a custom clip name does not automatically open collisions. Adapting the sample for that requires stopping locomotion before the transition, authoring the enable/disable events, and updating the script's attack lock and completion-name checks. Custom names also lack the standard attacks' automatic foot-planting behavior. Keep the standard sample attacks for the first working creature, then change this behavior deliberately.

Do not issue idle/walk/run actions during the attack: those actions clear the collision window. The copied script holds an attack lock, releases it from animationCompleted(animationName), and lets the next update choose movement. Keep this pattern. Do not start another transition from inside animationCompleted; set a flag or clear a lock and transition in update. That callback is for non-looping Spriter clips. Demina's animationComplete keyframe marker is not required to finish a Spriter clip.

5. Test the exported copy

After every export or JSON/Lua edit:

  1. Validate in Mod Prep, then Install / Refresh Test Copy.
  2. Restart Signs of Life. Load Now does not reload an already Loaded pack; a restart also clears the cached animation and atlas files.
  3. Open a disposable single-player test world and spawn my_creatures.my_kangit again.
  4. Observe idle, walking and running in both directions. Check feet, facing, pivots, drawing order, trimming and the body's fit against terrain.
  5. Let it attack from both sides. Check the windup, damaging pose, recovery and return to movement. Check that flinch/death stop looping and that damage/drop values match your JSON.
  6. Save and reopen the test world with the same pack enabled. Before distributing a multiplayer creature, test matching pack versions on host and client too; the host runs its spawning and behavior.

Validation catches pack errors; it does not prove the rig's alignment, all timeline names, combat timing or Lua behavior. Keep a known-working exported copy so you can compare one change at a time.

Registering the creature does not make it spawn naturally. Once manual spawning works, add an ambient spawn rule or a spawn entry in a custom world, using your full creature ID.

Troubleshooting

Symptom Check
Unknown creature when spawning Pack enabled/Loaded, creature_ filename prefix, Creature root, exact mod.id and a restart after edits
Missing image or atlas lookup failure Exported SCML clone, SCML atlas references, meta.image, relative paths/case and object-style frames keys
Pieces shifted, cropped or rotated incorrectly PNG and atlas JSON from the same export, including trim/rotation metadata
Creature floats, clips into ground or catches on walls Physics box separately from drawing offsets and rig origin
Animation does not change Clip spelling, requested clip actually exported, script installed and current pack reloaded
Attack repeats or never releases its lock Non-looping clip, animationCompleted handler, and a fallback lock longer than the new clip
Attack looks right but causes no damage Named sprite exists in the strike pose, melee points reach the target, collision events are ordered, and locomotion is not canceling the window
Old artwork persists Refresh the installed test copy and fully restart the game

Distribute the playable files

Keep modinfo.json, the creature_*.json definition, Lua script, exported SCML, every referenced atlas JSON and its PNGs inside your pack. Keep the editable master project and original art backed up separately. Other players need the exported files, not a Spriter installation.

Use Mod Prep to validate and stage the complete pack, then follow the publishing steps. Local folder/ZIP sharing can be tested without Workshop; Workshop submission requires Steam and an internet connection.