Author with Gymnast Tool Suite
Gymnast Tool Suite provides the Blender authoring scene, IK controls, model tools and native animation exporter. Eclipse supplies validation and packaging into a regular Lua mod with a map battle. Start here for visual character authoring.
The tested combination is Gymnast 1.1.5, repository revision b44dea8ae549ff52ec8d08d7d1ad86f53db80702, and Blender 5.0.1. The upstream add-on advertises Blender 4.4+, but its current SF2 scenes use file format 405.91: Blender 4.4.3 and 4.5.3 warn about possible data loss. Use Blender 5.0+ with the bridge. Your Blender 3.6 installation can remain installed separately.
Eclipse does not bundle or modify Gymnast. The bridge loads the checkout you supply and registers its add-on for that Blender session. The upstream repository includes its GPL license; retain attribution and check asset permissions when distributing authoring files or exported content.
Prepare and open the scene
Section titled “Prepare and open the scene”Run from the Eclipse repository root. Obtain Blender from its official downloads. A portable build works.
git clone https://github.com/FlipThoseTitle/Gymnast-Tool-Suite.git Temp/Gymnast-Tool-Suitegit -C Temp/Gymnast-Tool-Suite checkout b44dea8ae549ff52ec8d08d7d1ad86f53db80702dotnet run --project Tools/AssetPacker -- extract Assets/StreamingAssets/SF2Content/ArtBundles/MODELS.tar.lz4 Temp/CharacterCore$blender = 'C:\Program Files\Blender Foundation\Blender 5.0\blender.exe'.\Tools\Animation\OpenGymnast.ps1 -Blender $blender -Suite Temp/Gymnast-Tool-Suite -Rig Temp/CharacterCore/models/mdl_skeleton.xml -Blend Temp/MyGymnast/character.blendSet $blender to your actual executable. If the checkout or extracted assets already exist, reuse them. The open command creates the authoring file only when it is missing; subsequent runs open your existing work. It does not overwrite the earlier Temp/MyCharacter/character.blend point-rig experiment or change Blender preferences.
The prepared copy has the upstream visible capsule body and IK armature, framed in an orthographic viewport. The armature is selected in Pose Mode. Point labels are hidden and the underlying node objects are protected from accidental selection. They remain present for export. The animation panel is configured for the SF2 IK armature and canonical skeleton. Press N for Gymnast’s sidebar if needed.
Animate with IK controls
Section titled “Animate with IK controls”Use the armature’s HandIK_1, HandIK_2, HeelIK_1, HeelIK_2 and body controls. Insert location/rotation keyframes on the controls; the native point objects follow through the upstream rig constraints. Start with a visible arm motion and check both the body and its controls while scrubbing.
The prepared range is frames 1–60 at 60 fps. Every frame exports as one native sample with mid_frames = 0. For existing 20 fps sample data, use --mid-frames 2 and a 20 fps scene; the bridge verifies the relationship instead of silently retiming. Native end frame is sample_count - 1: frame bounds index stored samples. Interpolation changes playback timing, with nominal sample spacing (mid_frames + 1) / 60 seconds.
Keep Gymnast’s scene scale. Its native coordinate conversion is (Blender X, Blender Z, -Blender Y) without a ×100 multiplier. The earlier low-level importer used different Blender units; do not mix its point objects into a Gymnast scene. Keep every required object name and use the same dependency rig when importing and exporting animations.
The upstream animation guide explains animation import, mirroring, interpolation and weapon-node options.
Author models and equipment
Section titled “Author models and equipment”Use Gymnast’s Model Tool to import native XML geometry or export modeled geometry. Choose the appropriate model type and dependency rig. Its head/body/foot gear and weapon workflows handle the corresponding native attachments. Save optional geometric overlays as XML files before packaging.
Pass character overlays with --skin. They are appended to the body/equipment composition. Equipment replacements should use the matching typed equipment API; a skin overlay does not automatically replace the character’s weapon or armor. Preserve original rig names/order when reusing native moves and equipment. Native rigs, attachment math and collision behavior still constrain custom models.
Export an installable preview mod
Section titled “Export an installable preview mod”Save your .blend, then run:
& $blender --background --factory-startup Temp/MyGymnast/character.blend --python-exit-code 1 --python Tools/Animation/GymnastBridge.py -- export --suite Temp/Gymnast-Tool-Suite --rig Temp/CharacterCore/models/mdl_skeleton.xml --output Temp/MyGymnast/move.bin --package Temp/MyGymnast/local.character-preview --mod-id local.character-previewAdd --skin Temp/MyGymnast/skin.xml for an exported overlay; repeat for up to 16 files. Use fresh output paths for subsequent exports. Existing files/packages are refused to protect edits. The package folder’s name must match --mod-id.
The bridge checks missing node objects before invoking Gymnast’s exporter, verifies finite evaluated coordinates and compares every exported point against the evaluated Blender pose. It then validates the body, optional skins, node counts and binary payload. The upstream exporter can otherwise write zero coordinates for missing nodes. The standalone packager also rejects required bindings collapsed to zero for the entire clip, but cannot prove the names of an arbitrary binary’s points because native binaries do not contain them.
If you already exported through Gymnast’s UI, package that .bin directly:
python Tools/Animation/PackageCharacter.py --rig Temp/CharacterCore/models/mdl_skeleton.xml --animation Temp/MyGymnast/move.bin --output Temp/MyGymnast/local.character-preview --mod-id local.character-previewThis path validates file structure; only the Blender bridge can compare the output with its source pose. Neither path rescales, reorders or rewrites the animation bytes. Eclipse stores the same payload as assets/animations/authored.bytes.
Play your exported character
Section titled “Play your exported character”Add --playable to the bridge’s export --package command, or to the standalone
packager. The generated fight then uses your owned warrior as its player and as
its AI opponent. Without the flag, the player keeps the normal campaign character
and only the opponent uses the export. The option defaults to false; it does not
change the model or animation bytes, rig order, timing, or campaign profile.
python Tools/Animation/PackageCharacter.py --rig Temp/CharacterCore/models/mdl_skeleton.xml --animation Temp/MyGymnast/punch.bin --skin Temp/MyGymnast/skin.xml --output Temp/MyGymnast/local.playable-character --mod-id local.playable-character --playableEnable the complete generated mod and enter its map preview. Punch plays your
primary clip; additional clips use their declared controls. The opponent uses
its generated Lua tactic to choose eligible authored clips. The generated move
conditions, events and intervals use the current declarative Lua format. Moves
use direction = "face_enemy" to face the opponent when playback starts. For
example, { character = character } restricts your Punch override to this
warrior. The encounter’s player_character
selects the owned warrior; no combat form-swap or persistent profile replacement
is needed. Use a fresh package path to preserve earlier authored work.
--playable on the Blender bridge requires export and --package; using it for
prepare/open or an unpackaged binary is an error. It combines with standalone
--clip packaging, including each clip’s control and timing. It changes only the
generated encounter role and player instructions. The primary and additional
preview moves have no attack intervals; inherited native attacks can still deal
damage. To build a combat moveset, add the typed attacks and hit timing in Lua.
Package several animations together
Section titled “Package several animations together”Export each motion separately with the same dependency rig, then add named clips
to the standalone packager. Each --clip takes name, control, mid-frames, file:
python Tools/Animation/PackageCharacter.py --rig Temp/CharacterCore/models/mdl_skeleton.xml --animation Temp/MyGymnast/punch.bin --clip kick Kick 0 Temp/MyGymnast/kick.bin --clip flourish Magic 2 Temp/MyGymnast/flourish.bin --output Temp/MyGymnast/local.moveset --mod-id local.movesetThe primary --animation keeps the authored_move name and Punch input.
Additional names require 1–48 lowercase letters/digits/underscores, starting with
a letter; authored and authored_move are reserved. Controls must be distinct:
Kick, Ranged, Magic, Up, Down, Forward, or Back. Forward/Back are relative
to facing. This allows eight preview clips including the primary one. Directional
bindings may replace ordinary movement for the authored warrior; choose combat
buttons first when testing. Edit the generated Lua for advanced input combinations
or a larger moveset rather than relying on this preview binding scheme.
Each clip’s mid-frames is an integer from 0 to 8 and must match its source sampling. It changes interpolation spacing, not binary sample count or native end-frame indices. Clip bytes stay unchanged. Every clip is checked against the shared rig before publishing the package; an invalid clip prevents the output directory from being created. The package permits at most two million node samples in total. All existing output protection and skin validation still apply.
Each additional clip receives assets/animations/<name>.bytes, its own
<name>.rig.json timing/hash/control sidecar, and preview-<name>.html.
The original preview stays at preview.html. scripts/character.lua returns
warrior, the original move, and a moves table keyed by authored_move and
your additional names. The preview AI cycles through eligible clips, skipping
unavailable ones and waiting between requests. All generated moves still deal
no damage until you author attack intervals.
The package contains a manifest, native assets, localization, scripts/character.lua, scripts/main.lua, a rig fingerprint sidecar, and a point-motion preview.html. The preview respects sample spacing. Body and skin appearance should be inspected in Blender and the game, not inferred from the point preview.
Test in Eclipse
Section titled “Test in Eclipse”Copy the complete local.character-preview folder into Eclipse’s Mods directory, preserving any existing work under that ID. Enable it through Mods → Apply & Restart and find Character Preview using the bottom map-page dots.
The repeatable fight uses your authored warrior as the opponent, and also as the player when packaged with --playable. Its Lua AI selects eligible authored clips with a pause between requests. This allows you to watch the export without creating another fight script. Authored preview moves have no attack intervals; inherited native moves can still deal damage. Entry costs and rewards are empty.
Edit scripts/character.lua to add the typed attack intervals, change input conditions or supply your own tactic. scripts/main.lua is ordinary mod code and can be replaced by your own battles. Inspect both facing directions, rig/skin deformation, equipment attachment, movement, hit reactions and contact timing. A successful binary read does not establish all of those behaviors.
Verification and limits
Section titled “Verification and limits”Tools/Animation/TestGymnastPipeline.ps1 -Blender <executable> -Suite <checkout> exercises the supplied IK/body scene, an authored hand motion, upstream model and animation exports, source-pose comparison, packaging, real Lua map/mode/AI bindings, the watched and playable package roles, and the unchanged Unity animation reader. It writes an inspection render and test artifacts under Temp.
Tools/Tests/Modding/TestModAiEligibility.ps1 executes the recovered AI shortlist and priority
methods with controlled model/animation services. It checks that character
restrictions, uninterruptible state and higher-priority input moves filter the
candidate list; event-only animations are excluded. Generated package tests also
exercise Lua clip cycling, pacing and unavailable-clip fallback. Neither test
simulates contact physics or proves that authored geometry looks correct in a fight.
The low-level point-rig tools remain available for format work. They also include explicit armature retargeting using a creator-supplied bone mapping and calibration frame. They are not the recommended visual authoring interface. Automatic skeleton matching, arbitrary Blender shaders, complete custom character controllers/forms and full-game visual/combat acceptance remain separate requirements.
The full-game Tools/Tests/CharacterForms/TestPackagedCharacterUnity.ps1 runner
accepts a generated Gymnast integration package. It uses a marked isolated
project and fresh profile to check native models/weighted skin helpers, player
selection, native Punch dispatch, both facing directions, exported point motion,
opponent Lua AI and cleanup. Its controlled test uses the canonical 67-point
rig and the integration scene/skin; it is not arbitrary mesh/rig, attack-contact,
physical-device, mobile, or exported-platform acceptance. Existing format and
reader checks remain narrower than a game playtest.
Both generated roles have full-game acceptance in Unity 6.6: 28 checks for the playable package and 16 for the default opponent-only package. The exported test skin is a small original triangle bound to head landmarks. Native macro-node weights update XY only; these checks do not prove animated skin depth or a complete original outfit. Exported preview clips still need authored attack intervals before they become damaging combat moves.