Skeletal Animation
Polygon Engine imports a bounded hard-skinned FBX path for animated characters
and props. The importer bakes animation data into a compact .skn asset, and
the PS1 runtime evaluates its bone matrices before drawing through the normal
triangle, material, texture, lighting, and ordering-table path.
This is deliberately not a desktop-style general skinner. It is a predictable PlayStation 1 format with one bone influence per vertex, fixed capacities, and explicit memory budgets.
Import a Skeletal FBX
- Place the
.fbxsource inAssets/Models/. - Select it in the Project panel.
- In the Model Inspector, enable Import Hard-Skinned Animation.
- Set Target FPS from
1to30;15is the default PS1-friendly value. - Review the reported bone count, clips, runtime size, and clip names.
- Apply or reimport.
The skeletal importer uses the model's Axis, Scale, and Apply Unit Scale settings. Export the bind pose and clips in one FBX, then keep those settings stable between reimports.
When skeletal import succeeds, Polygon Engine writes:
Library/animations/<skin-guid>.skn
The asset database identifies it as SkeletalAnimation. Internally the file
uses the PSKN format signature. A normal OBJ or non-skinned FBX remains a
static .msh asset.
The PS1 Asset Optimizer currently accepts static meshes only. It blocks a skinned FBX instead of silently discarding bones, skin weights, or animation. Reduce and validate animated topology in the DCC before exporting the FBX.
Hard Skinning Rule
Each imported vertex is assigned to its dominant positive bone weight. Other weights are discarded. This hard-skin rule keeps runtime deformation bounded and avoids per-vertex weight blending on the PS1.
Prepare assets around that constraint:
- place joints where rigid sections should bend;
- avoid deformation that depends on smooth four-weight blending;
- inspect elbows, shoulders, faces, cloth, and other soft transitions;
- reduce bones and baked frames before reducing mesh clarity blindly.
The skeletal runtime format supports one material per skinned asset. If the source contains multiple materials, enable Single Material and reimport after combining the character into one material/atlas.
Animator Component
Assigning a model with generated skin data can add an Animator automatically and select the first imported clip. You can also configure it in the Inspector.
| Property | Meaning |
|---|---|
| Enabled | Includes the animator in runtime update and rendering |
| Skin | Imported skeletal-animation asset |
| Default Clip | Clip selected when the component starts |
| Playback Speed | Time multiplier, clamped by the Inspector to 0.01..8.0 |
| Loop | Restart the clip after its final frame |
| Play On Start | Begin the default clip when the scene starts |
The GameObject also needs a Mesh Renderer. Its material, texture, color, lighting, and renderer settings are used for the skinned draw path.
Playback can start from the component, Lua Animator,
a cutscene timeline, or a standalone Animation clip.
Animator.Play() defaults to looping when its optional third argument is
omitted.
Runtime Behavior
Animation time follows the selected PAL or NTSC runtime rate. The runtime interpolates between baked frames using fixed-point bone matrices, transforms the hard-skinned vertices and normals into a shared scratch buffer, and submits the resulting triangles through the engine's existing PS1 renderer.
Use the baked Target FPS to balance motion fidelity against matrix data. Runtime interpolation smooths the interval between baked frames, but it cannot restore deformation detail removed by hard skinning.
Fixed Limits
| Resource | Limit |
|---|---|
| Skinned meshes per scene | 16 |
| Bones per asset | 64 |
| Clips per asset | 16 |
| Vertices per asset | 4,096 |
| Indices per asset | 12,288 (4,096 triangles) |
| Geometry data per asset | 128 KiB |
| Geometry data per scene | 192 KiB |
| Shared deformation scratch | 64 KiB |
| Matrix data per asset | 192 KiB |
| Matrix data per scene | 256 KiB |
| Clip name | 24 characters maximum |
| Bone name | 31 characters maximum |
Shared scratch is sized for the largest active asset requirement; it is not summed once per skinned mesh. Geometry and matrix data are still accumulated against their scene budgets.
The PS1 Budget panel reports animator records, unique skeletal assets, geometry, matrix data, and shared scratch. It warns at 70% and blocks builds that exceed hard capacities.
Validation Checklist
- confirm that every
Animatorresolves a valid skin and default clip; - keep the source at one material and inside every per-asset cap;
- test non-loop completion if gameplay depends on it;
- review close camera angles and overlapping geometry like any PS1 asset;
- use the PS1 Budget report after every meaningful animation reimport;
- validate final poses, draw ordering, textures, and timing in a packaged DuckStation build and, for a release, on representative real hardware.
The current documentation does not promise moving-platform support, arbitrary weighted skinning, morph targets, or an editor deformation preview identical to the packaged runtime.