Custom Particle Types - MehVahdJukaar/polytone GitHub Wiki
Custom Particle Type
This feature allows you to create entirely NEW and unique particle or OVERRIDE existing ones.
These will be client side, so only you will be able to see them.
For older versions, the only way to actually spawn them is through block_properties_modifiers
's particle_emitters so refer to that section.
Getting started
To start you'll have to create two identically named files:
- A particle texture list json (vanilla concept)
- A custom particle type json (polytone concept)
Particle Texture List
This step is only mandatory for new Custom particles.
First place a particle list json in assets/[your namespace]/particles/[particle name].json
.
The particle ID will be [your namespace]:[particle name]
. You can choose any particle name, and put it under a custom namespace, or under the vanilla namespace, which would look like minecraft:[particle name]
.
The json content is a list of sprites as follows. The list of sprites play in order like an animated texture, for particles with a texture that is not animated, simply list one texture. All texture files must be located in the particles texture folder. This is a vanilla concept so refer to the official minecraft wiki on the subject. Here's an example one
{
"textures": [
"minecraft:spark_1",
"minecraft:spark_2"
]
}
Particle Type Json
The second file will have to be placed in assets/[particle namespace]/polytone/custom_particles/[particle name].json
.
This means that particle ID is [particle namespace]:[particle name]
.
Incase you want to override an existing particle this ID will have to match that.
For custom particles its good convention to use your own namespace.
Important to note that you must use the same particle ID as used in the texture list above. Not doing so will throw an error.
Here's an example of what this file could look like:
{
"initializer": {
"lifetime": "10",
"alpha": "0.5",
"size": "0",
"dx": "rand()",
"dy": "rand()",
"dz": "rand()"
},
"ticker": {
"dx": "0.05",
"dy": "-0.5",
"dz": "0.05",
"size": "0.1 * (AGE / 10)",
},
"render_type": "translucent",
"liquid_affinity": "non_liquids"
}
Following section will explain what you can add to this file to tweak how the particle behaves and looks.
Json Format
Once you have your Custom Particle Type json file you can add many attributes to create behavior of the particle. Additionally, you can copy the behavior of an existing vanilla particle. Here's the custom one.
Parameter | Description | Default value |
---|---|---|
render_type |
Particle render type. Can be opaque , translucent , invisible or additive_translucent (1.21 only) |
opaque |
model |
Allows specifying a 3d model for the particle | null |
offset |
Particle render offset | "offset": [0, 0, 0] |
rotation_mode |
The way this particle will rotate. Can be look_at_xyz , look_at_y , none , look_up or movement_aligned |
look_at_xyz |
light_level |
Particle block light emission, when combined with "lit" rendertype can set the brightness of a particle (0-15) | 0 |
colormap |
Defines the colormap set to a particle, must be a polytone colormap, not optifine. Overrides color info defined above. | null |
random_sprite |
When true the particle will pick a random sprite from its sprite set instead of cycling through them as it ages | |
has_physics |
Boolean value. Wether particle has physics or not. If true particle will despawn when not moving | true |
kill_on_contact |
Boolean value. Wether particle will despawn when colliding with anything. Collision will only occur when it has physics | false |
kill_when_still |
Boolean value. Wether particle will despawn when not moving. Will only occur when it has physics | true |
liquid_affinity |
Where this particle can exist in liquids or not. Can be non_liquids , liquids or any |
any |
initializer |
Particle initial parameters. See below for explanation | null |
ticker |
Particle ticker. How the particle parameters change with time | null |
sound_emitters |
A list of Particle Sound Emitters to run each tick | empty |
tick_rate |
After how many ticks the tick logic runs. Generally just used for optimization purposes | 1 |
exclusion_radius |
Radius in which this particle won't spawn if another particle of the same type is aleady present | 0 |
particle_emitters |
A list of Particle Particle Emitters to run each tick | empty |
If you instead wish to Copy an existing particle behavior (with different sprites of course), you can use this simpler syntax here, just specify a particle ID. In this example we are adding a particle that behaves like minecraft:flame
. Please note that particles with copied behaviour cannot be modified by most other parameters.
{
"copy_from": "minecraft:flame"
}
Information below will now only be relevant to the Full Custom type
Initializer
This object is a set of Block Expressions (refer to the scripting section), that determine how the particle initial parameters wil be setup. Here's a list of all of them with their function. All parameters are optional.
Parameter | Description | Default value |
---|---|---|
size |
Particle visual size (Size 1 = 2 Blocks) | random number from 0.1 to 2 (vanilla logic) |
hitbox_size |
Particle hitbox size. Used when particle has physics | 0.1 |
lifetime |
Particle max age in ticks | Random number between 4 and 40 (vanilla logic) |
red |
Particle red channel (from 0 to 1) | "1" |
green |
Particle green channel (from 0 to 1) | "1" |
blue |
Particle blue channel (from 0 to 1) | "1" |
alpha |
Particle alpha channel (from 0 to 1) | "1" |
roll |
Particle z axis rotation | "0" |
friction |
Particle friction or drag | "0.98" |
custom |
A variable that you can fill with whatever you want | 0 |
Note that things like x,y,z, dx,dy,dz will be determined by the Particle Emitter logic
Here's an example
{
"initializer":{
"lifetime": "10+rand()*10",
"size": "1+sin((GAMETIME%300)/300*pi)",
"red": "0.3",
"has_physics": false
}
}
Ticker
Similar to the initializer this block will contain expressions that will be run every tick and re assing values to the particle parameters. All parameters are optional and when missing wont be applied. All parameters are of type of Particle Expression. See Scripting section for more.
Parameter | Description |
---|---|
x |
Force sets particle x position |
y |
Force sets particle y position |
z |
Force sets particle z position |
dx |
Particle x movement |
dy |
Particle y movement |
dz |
Particle z movement |
size |
Particle size |
red |
Particle red channel (from 0 to 1) |
green |
Particle green channel (from 0 to 1) |
blue |
Particle blue channel (from 0 to 1) |
alpha |
Particle alpha channel (from 0 to 1) |
roll |
Particle z axis rotation |
remove_condition |
Kills this particle when this expression is not 0 |
custom |
A variable that you can fill with whatever you want |
In this example we'll make a particle that accelerates on the x axis and loses red color as time goes on while also rotating on z axis.
{
"ticker":{
"dx": "DX*1.01",
"red": "max(0,RED-0.01)",
"roll": "(GAMETIME%50)/50*2*pi"
}
}
Particle Emission
With this feature you can make a particle spawn other particles just like an explosion emitter particle would. This feature is VERY similar to Block Modifiers Particle Emitters so refer to that section frist. The main difference with that one is that these use Particle Expressions insetead of Block Expressions (refer to the Scripting page).
You'll be able to do so by adding the particle_emitters
field as follows:
{
"particle_emitters": [
{
"particle": "minecraft:flame",
"chance": "0.2",
"x": "cos(AGE)+0.5",
"z": "cos(AGE)+0.5",
"y": "1"
"dy": "DX"
}
]
}
In this example we are creating a flame particle on the current particle in a circle pattern, rotating and giving it the same Y velocity as the spawner particle.
The value of each parameter is a Particle Expression. Refer to the Scripting Section for more info.
Here is a table explaining in more detail what each of the parameters do. Most parameters are optional.
Parameter | Description | Type |
---|---|---|
particle |
Id of the target Particle Type you want to spawn | String |
chance |
Chance that this particle will be spawned | Particle Expression |
x |
Particle x position, relative to spawn_location | Particle Expression |
y |
Particle y position, relative to spawn_location | Particle Expression |
z |
Particle z position, relative to spawn_location | Particle Expression |
dx |
Particle x velocity | Particle Expression |
dy |
Particle y velocity | Particle Expression |
dz |
Particle z velocity | Particle Expression |
state_predicate |
Additional Rule Test object to filter the blockstate where particle is. Can be expensive if overused. Check out [official MC wiki] | |
biomes |
List of biomes ids or biome tags or just biome tag (Holder set) where these can spawn | String list |
Note that what each particle do with the last 3 parameters (dx,dy,dz) is up to their own classes and may not equal their velocity all the time. Some for example might just use one for different purpose like noteblock particles that for example use dx for the note color. Refer to the Minecraft Wiki for more info on this.
Sound Emission
These too are very similar to their Block Modifiers counterpart with only difference being the type of Expression type used (Particle Expressions instead of Block Expressions)
Sound emission works very similar to particle emission. Just like that one you will need to be in particle ticking range for it to trigger.
You can start by adding a sound_emitters
field as in the following example:
{
"sound_emitters": [
{
"sound": "my_pack:my_custom_sound",
"chance": "rand()*0.3",
"pitch": "0.2+gaussian()*0.3",
"volume": "SPEED"
}
]
}
Here we create a sound that changes its volume depending on the particle speed
Here are all the parameters on an emitter.
Parameter | Description | Type |
---|---|---|
sound |
ID of the sound event to play | String |
chance |
Chance that this sound will be spawned | Particle Expression |
x |
Sound x position | Particle Expression |
y |
Sound y position | Particle Expression |
z |
Sound z position | Particle Expression |
pitch |
Sound Pitch | Particle Expression |
volume |
Sound Volume | Particle Expression |
distance_delay |
Wether this sound is delayed the further you are (like fireworks) | Boolean |
biomes |
List of biomes ids or biome tags or just biome tag (Holder set) where these can spawn | String list |