NTM’s weapon animation system — contributed by MellowArpeggiation — stores all weapon animations as JSON files that are loaded alongside OBJ models at runtime. This approach keeps file sizes small while supporting full skeletal-style animation with per-part keyframes, Bezier and easing curves, parent–child hierarchies, and rest-pose offsets. The Blender addons in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/hbmmods/hbm-s-nuclear-tech-git/llms.txt
Use this file to discover all available pages before exploring further.
tools/ directory let you author animations visually in Blender and export them directly to the JSON format that NTM reads, or import existing animation files back into Blender for editing. This page explains the file format, the addon workflow, and where everything lives in the repository.
Animation File Format
Each animation JSON file sits next to its corresponding OBJ model inside:Fire, Reload, Inspect, Jammed). Each clip drives one or more named parts (mesh objects), and each part carries keyframe data for location and rotation_euler channels on the x, y, and z axes. Keyframe tuples encode the value, the timestamp in milliseconds, the interpolation mode (e.g., BEZIER, EXPO, CONSTANT), optional easing, and Bezier handle positions where applicable.
The top-level structure of a file looks like this:
| Key | Purpose |
|---|---|
anim | All animation clips, keyed by clip name, then by part name |
offset | Rest-pose world-space position of each part (set from frame 0) |
hierarchy | Parent–child relationships between parts |
rotmode | Euler rotation order per part (default YZX for best in-game accuracy) |
com.hbm.animloader and is driven by AnimationController, AnimatedModel, Animation, and AnimationWrapper. The controller interpolates between keyframe pairs each render frame and applies the resulting transforms as OpenGL matrix operations.
Axes are swizzled on export: Blender’s
+Y (up) maps to NTM’s +Z, and +Z (Blender forward) maps to +Y. The export scripts handle this automatically so you do not need to rotate your Blender scene.Blender Addons
Available versions
Thetools/ directory contains three Python addon scripts, one per supported Blender version:
| File | Blender version |
|---|---|
tools/export-json-animation-2_79.py | Blender 2.79 |
tools/export-json-animation-3_2.py | Blender 3.2 |
tools/export-json-animation-4_0.py | Blender 4.0 |
Check the comment block at the top of each script for version-specific usage notes. The header comments are the authoritative source of truth for that script’s quirks and requirements.
Installing the addon
Install from file
Click Install… (Blender 3.x / 4.x) or Install Add-on from File… (Blender 2.79). Navigate to the
tools/ directory in the NTM repository and select the .py file that matches your Blender version.Export Workflow
This workflow takes you from a rigged and animated Blender scene to a.json file ready to drop into the repository.
Set up your action names
Every action in your Blender file must follow the naming convention
AnimationName.PartName. For example, an action named Reload.Gun will export as the Reload animation clip driving the Gun part. Actions that do not contain exactly one . separator are silently skipped.Start all actions at frame 0
Every action must begin at frame 0. The exporter reads offsets from frame 0, so parts must be in their rest poses on that frame. If you get unexpected offset issues in-game, verify that the model is in its rest pose at frame 0 before exporting.
Set rotation mode to YZX Euler
Select each animated mesh object, open the Object Properties panel, and set Rotation Mode to YZX Euler. This ensures rotations match what NTM expects at runtime.
Run the export
Go to File → Export → Export NTM .json. Choose a destination filename — by convention, use the weapon’s registry name in lowercase (e.g.,
spas12.json). Click Export NTM .json to write the file.Import Workflow
Importing lets you load an existing.json animation file back into Blender to inspect or modify it.
Open the import dialog
Go to File → Import → Import NTM .json and navigate to the
.json animation file you want to open.Select the file and import
Click Import NTM .json. The addon will:
- Create Blender Actions from the
animdata, naming each actionAnimationName.PartName. - Apply rest-pose offsets from the
offsetblock by moving each mesh object’s origin. - Reconstruct parent–child relationships from the
hierarchyblock. - Restore per-object rotation modes from the
rotmodeblock.
Assign actions to objects in the Action Editor
Imported actions are stored in
bpy.data.actions but are not automatically assigned to the objects in your scene. Open the Action Editor (or NLA Editor) and assign each AnimationName.PartName action to the corresponding mesh object to preview and edit it.Runtime Integration
The Java-side animation system incom.hbm.animloader works as follows:
| Class | Role |
|---|---|
Animation | Data container: keyframe count, total length, per-part Transform[] arrays |
Transform | A single interpolated transform snapshot (position + rotation) |
AnimationWrapper | Wraps an Animation with playback state: start time, speed scale, loop/end behavior |
AnimationController | Attached to an AnimatedModel; drives the active AnimationWrapper each frame |
AnimatedModel | Renderable node in a model hierarchy; applies the controller’s transform via GL11 matrix calls |
ColladaLoader | Legacy COLLADA (.dae) loader kept alongside the JSON system |
AnimationController for the weapon’s AnimatedModel and call the appropriate start method with the animation name and desired EndResult (e.g., END, REPEAT, STAY).
The
AnimatedModel.renderAnimated(long sysTime) method drives interpolation using System.currentTimeMillis() as the time source, so animation speed is frame-rate independent.