Skip to main content

FreeMinecraftModels Particles

FreeMinecraftModels plays the particle keyframes in a model's Blockbench animations. That covers custom entities, props and held items. Java players see the particles as packet-only sprites that FMM simulates on the server. Bedrock players get the original Snowstorm effect, drawn by their own client.

For animation names and playback rules, see Animations. For locators and the rest of the import contract, see Model Authoring Notes.

Authoring In Blockbench​

  1. Make the effect in Blockbench's particle editor (Snowstorm) and save it as a .json particle file.
  2. Add a locator to the model where the effect should come from. A locator inside a bone moves with that bone's animation, so a locator on a spinning arm leaves a trail along the arm's path.
  3. In an animation, open the Effects animator and add a particle keyframe. Set the effect name, the locator and the particle file. The optional script field runs as Molang before the effect starts, for example v.size = 2;.
  4. Put the particle file and its texture PNG next to the .bbmodel (or in a particles/ folder beside it) and ship them with the model.

A keyframe without a locator plays at the model's origin. A keyframe naming a locator the model does not have also plays at the origin and logs a warning.

Where FMM Finds Particle Files​

Blockbench only stores the author's local path to the particle file, so FMM searches by file name. For each effect it tries, in this order, first in the model's folder and then in a particles/ folder beside it:

  1. The file name stored in the keyframe
  2. <effect>.particle.json
  3. <effect>.json

A .json that is not a particle file (for example a display model with the same name as the effect) is skipped. When nothing is found, the console says Particle effect '<effect>' used by animation '<animation>' in <model> was not found, those keyframes are dropped, and the rest of the model loads normally.

Textures​

The particle file's basic_render_parameters.texture is matched by its last path segment: textures/particle/spark means FMM looks for spark.png, first beside the particle file, then beside the model, then in the model's particles/ folder.

If the PNG is missing, Java players see plain white sprites tinted by the effect's color, and the console warns. Bedrock keeps the original texture path, so a vanilla Bedrock texture such as textures/blocks/wool_colored_white still works there. Ship a PNG under the matching name to get the same look on Java.

When Effects Play​

  • An effect starts when its animation reaches the keyframe. In a looping animation the keyframe fires again on every loop, and its emitter restarts.
  • When the animation stops or switches, looping emitters stop spawning. Particles already in the air finish their lifetime.
  • Emitters pause while no Java player can see the model. filmicMode keeps every loaded model visible, so it keeps their particles running too.
  • Removing a model removes its emitters and every particle sprite straight away. That includes death, despawn, chunk unload and /fmm deleteall.

Props​

A prop plays only idle on its own. Put the particle keyframes in idle, or play the animation that has them from a prop Lua script:

context.prop:play_animation("sparkle", true, true)

Held Items​

Particles also play on FMM custom items, meaning items given with /fmm giveitem or the admin menu. The item's model must have particle keyframes. FMM reads the thirdperson_righthand and thirdperson_lefthand transforms of its display model (the sibling .json) to find where the item sits in the hand. Without a display model, Java places the particles as if the item had no display transform, and Bedrock gets no held-item particles.

  • FMM loops the model's held animation while the item is in either hand. Without a held animation that has particle keyframes, it uses the first animation, by name, that has some.
  • Bones do not animate on a held item. Locators stay at their rest position on the item.
  • Java: the server cannot know whether a player is in first person, third person or the front camera. FMM places the particles at the item's tip in the third-person pose, from the holder's body rotation, sneaking, which hand holds the item, their scale attribute and the display model transforms. Every Java player, including the holder, sees them at that one position. In first person the holder sees them where their third-person hand is, not on the first-person item. Arm swings and item-use poses are not tracked, so the particles can trail the item slightly while the arm moves. Java players within 48 blocks of the holder see the particles.
  • Bedrock: the particles are added to the item's Bedrock attachable, and the Bedrock client draws them on the real hand in every camera view. This needs ResourcePackManager's Bedrock conversion.

Java Rendering​

  • Each particle is an item_display packet entity. It never exists in the world, so other plugins cannot hit, save or remove it.
  • FMM moves particles every 2 ticks, and the client smooths the motion in between.
  • UV expressions are sampled at load into at most 16 texture variants per effect, and every flipbook frame of every variant becomes its own sprite. Those sprites go into the resource pack under assets/freeminecraftmodels/items/particle/<model>/<effect>/, with their texture at textures/entity/fmm_particles/<model>/<effect>.png. FMM also writes assets/freeminecraftmodels/rspm_item_java_only/particle/<model>/<effect>.json, which tells ResourcePackManager not to turn the sprite items into Bedrock custom items.
  • Particles render at full brightness unless the effect has minecraft:particle_appearance_lighting.
  • One effect on one model shows at most maxParticlesPerEmitter particles, or the file's own max_particles when that is lower. One Java player is shown at most maxParticlesPerViewer particles across all models. Over that limit, new particles for that player are skipped until older ones expire.
  • particleEffectsEnabled: false switches every effect off without editing models.

Components Java Supports​

ComponentJava support
emitter_rate_instant, emitter_rate_steadyFull
emitter_lifetime_once, emitter_lifetime_looping, emitter_lifetime_expressionFull
emitter_initializationCreation and per-update expressions
emitter_local_spacePosition and rotation
emitter_shape_point, _sphere, _box, _disc, _customOffset, radius, half dimensions, plane normal, surface_only, and outwards, inwards or custom direction
particle_initializationPer-update and per-render expressions
particle_initial_speed, particle_initial_spinFull
particle_motion_dynamicLinear acceleration and drag, rotation acceleration and drag
particle_lifetime_expressionmax_lifetime and expiration_expression
particle_appearance_billboardSize, facing mode, direction and UV, including flipbooks
particle_appearance_tintingFixed colors, per-channel expressions and gradients
particle_appearance_lightingTurns off the full-brightness default

Other components are ignored on Java, for example particle_motion_parametric, particle_motion_collision, emitter_rate_manual and emitter_shape_entity_aabb. The console lists them by name when the model loads. Bedrock players still see the full effect.

Facing modes map to display entity billboards. rotate_xyz, lookat_xyz and lookat_direction face the camera. rotate_y and lookat_y turn around the vertical axis only. direction_x, direction_y, direction_z and the emitter_transform_* modes keep a fixed orientation from the particle's direction or the emitter's rotation.

Molang​

Expressions support arithmetic, comparisons, ?:, ??, assignments and return. Math functions:

abs, acos, asin, atan, atan2, ceil, clamp, cos, die_roll, die_roll_integer, exp, floor, hermite_blend, lerp, lerprotate, ln, max, min, mod, pow, random, random_integer, round, sin, sqrt, trunc, and the constant math.pi.

Trigonometry works in degrees, like Bedrock. Built-in variables:

  • variable.particle_age, variable.particle_lifetime, variable.particle_random_1 to _4
  • variable.emitter_age, variable.emitter_lifetime, variable.emitter_random_1 to _4

Your own v. variables from initialization expressions and keyframe scripts work, as do curves (linear, catmull_rom, bezier, bezier_chain). Unknown variables and queries read as 0.

Bedrock​

With sendCustomModelsToBedrockClientsV2 enabled, the Bedrock bundle carries each effect as particles/<model>_<effect>.json with the identifier fmm:<model>_<effect>. It also carries the particle texture, the locators on the geometry bones and the particle keyframes in the Bedrock animations. Bedrock clients then play the effect natively, including components Java skips.

For held items, FMM writes assets/freeminecraftmodels/rspm_item_particles/display/<item>.json into its Java output. ResourcePackManager reads it while converting the item and adds the locators and a looping particle animation to the item's attachable.

Troubleshooting​

Particle effect '<effect>' ... was not found. FMM could not find the particle file. Put it next to the model as <effect>.json or <effect>.particle.json, or under the file name stored in the keyframe. See Where FMM Finds Particle Files.

... uses <components>, which Java players do not see yet. This is informational. Java plays everything else in the effect, and Bedrock plays all of it.

... uses texture '<path>', which is not next to <file>. Put the texture PNG beside the particle file, named after the last segment of that path.

... follows locator '<name>', which the model does not have. The locator was renamed or deleted. The effect plays at the model origin until the keyframe names an existing locator.

My prop's particles never appear. Props only play idle by themselves. Move the keyframes into idle or play the animation from a script.

My held item's particles float away from the item in first person. This is expected on Java. The server places them at the third-person hand. Other players and third-person views see them on the item.

My held item shows no particles. The item must be an FMM custom item (it carries fmm_item_id), and one of its model's animations must have particle keyframes whose files FMM found.