Entities, particles & interaction · Spawning entities out of thin air on the client, catching clicks, laying out particle shapes¶
This page covers three groups of capabilities:
entity*(37): protocol-layer custom entities — conjure an entity on the client out of a vanilla entity type; suited to NPC shells, decorative mobs and armour-stand props. The server does not have this entity: no AI, no collision, nothing written to the save, and no part in any server-side logic.ghost*(2): interaction event polling — when a player clicks one of those protocol entities, the library routes the click into an event and puts it in a queue, and your script polls it out itself.particle*(22): particle shapes — lay out points, lines, rectangular rings, filled planes, box frames, six faces and polyhedra from vanilla particles, with translation, smooth movement, rotation, spin, scaling and following a player.
All three groups only handle "draw it" and "catch the click"; the business logic (commands, permissions, persistence) lives in your script.
In this section's examples,
idis the library id returned by an entity creation function, andpidis the shape id returned by a particle creation function. They are two unrelated numbering spaces: entity ids increment from 1 (you can also specify one or take a random one), and particle ids increment from 1.
Quick start¶
const entityCreate = ll.import("HologramLib", "entityCreate");
const entitySetNametag = ll.import("HologramLib", "entitySetNametag");
const ghostPollInteractions = ll.import("HologramLib", "ghostPollInteractions");
const particleCreateBox = ll.import("HologramLib", "particleCreateBox");
// 1. Spawn an armour stand in the Overworld at (100.5, 64, 100.5) (dim: 0=Overworld 1=Nether 2=End)
const id = entityCreate("armor_stand", 100.5, 64, 100.5, 0);
// 2. Give it a nametag (§ colour codes go straight into the text)
entitySetNametag(id, "§eGuard");
// 3. Take click events every 200 milliseconds — events go into a queue, you must poll yourself
setInterval(() => {
for (const line of ghostPollInteractions()) {
logger.info(line); // e.g. player=Steve action=2 domain=entity id=1
}
}, 200);
// 4. Wrap a particle box around it (interval=2: re-send every 2 ticks; lifetime=0: permanent)
const pid = particleCreateBox("demo", 0, 100.5, 64.5, 100.5, 1.5, 1.5, 1.5, 1, "minecraft:endrod", 2, 0);
Custom entities · Creation¶
This group creates the entity. Once created it appears on the clients of players who meet the visibility conditions: same dimension, inside the view distance, enabled switched on, and on the whitelist (no whitelist set means everyone).
Create a custom entity¶
entityCreate(identifier, x, y, z, dim)
- Parameters:
identifier:String
the entity type, such asminecraft:coworarmor_stand; a short name (cow) gets theminecraft:prefix added automaticallyx:Float
the world coordinate X (a float;.5lands at the centre of a block)y:Float
the world coordinate Y (a float;.5lands at the centre of a block)z:Float
the world coordinate Z (a float;.5lands at the centre of a block)dim:Integer
the dimension,0Overworld /1Nether /2End- Return value: the library entity id (every later
entity*call uses it); returns-1whenidentifieris empty - Return type:
Integer -
Example:
Set orientation, scale and nametag at creation¶
entityCreateAdvanced(identifier, x, y, z, dim, yaw, pitch, scale, nametag)
- Parameters:
identifier:String
the same asentityCreatex:Float
the same asentityCreatey:Float
the same asentityCreatez:Float
the same asentityCreatedim:Integer
the same asentityCreateyaw:Float
the yaw angle (degrees), the horizontal facingpitch:Float
the pitch angle (degrees), looking up / downscale:Float
overall scaling; it is clamped to0.0625 ~ 10when the packet is sentnametag:String
the nametag text, supporting§colour codes; an empty string = no nametag- Return value: the library entity id; returns
-1whenidentifieris empty - Return type:
Integer -
Example:
Create an entity with a random id¶
entityCreateRandom(identifier, x, y, z, dim)
- Parameters:
identifier:String
the same asentityCreatex:Float
the same asentityCreatey:Float
the same asentityCreatez:Float
the same asentityCreatedim:Integer
the same asentityCreate- Return value: the library entity id, taken from
[0x10000000, 0x7FFFFFFF)(kept apart from the incrementing range for good, so they never collide); returns-1when no free id can be found - Return type:
Integer -
Example:
Create an entity under an id you choose¶
entityCreateWithId(identifier, x, y, z, dim, desiredId)
- Parameters:
identifier:String
the same asentityCreatex:Float
the same asentityCreatey:Float
the same asentityCreatez:Float
the same asentityCreatedim:Integer
the same asentityCreatedesiredId:Integer
the library id you want to occupy; it must be> 0- Return value: on success it is exactly
desiredId;desiredId <= 0, or an id that is already taken, returns-2 - Return type:
Integer -
Example:
const entityCreateWithId = ll.import("HologramLib", "entityCreateWithId"); const entityIsIdUsed = ll.import("HologramLib", "entityIsIdUsed"); const wanted = 1001; // the id you saved to disk yourself const id = entityIsIdUsed(wanted) ? -2 : entityCreateWithId("armor_stand", 100.5, 64, 100.5, 0, wanted);
Custom entities · Properties¶
Every property change takes effect "on the next tick": structural changes (type, pose, equipment, flags and the like) merge into a single rebuild, while coordinates / orientation / nametag / scale / invisibility go out as delta packets — neither case flickers.
Change the entity type¶
entitySetIdentifier(id, identifier)
- Parameters:
id:Integer
the entity ididentifier:String
the new entity type; a short name getsminecraft:added automatically; an empty string is refused- Return value:
truewhen the change went through;falsewhen the id does not exist oridentifieris empty - Return type:
Boolean -
Example:
Move the entity to new coordinates¶
entitySetPosition(id, x, y, z, dim)
- Parameters:
id:Integer
the entity idx:Float
the new world coordinate Xy:Float
the new world coordinate Yz:Float
the new world coordinate Zdim:Integer>= 0puts the entity in that dimension;< 0= change the coordinates only and leave the dimension alone- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the entity's orientation¶
entitySetRotation(id, yaw, pitch)
- Parameters:
id:Integer
the entity idyaw:Float
the yaw angle (degrees), the horizontal facingpitch:Float
the pitch angle (degrees)- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the nametag above its head¶
entitySetNametag(id, text)
- Parameters:
id:Integer
the entity idtext:String
the nametag text, supporting§colour codes; an empty string = clear the nametag- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the entity's scale¶
entitySetScale(id, scale)
- Parameters:
id:Integer
the entity idscale:Float
the target scale (the model and the hitbox grow together);<= 0is refused outright; when the packet is actually sent it is clamped to the client's valid range0.0625 ~ 10- Return value:
trueon success;falsewhenscale <= 0or the id does not exist - Return type:
Boolean -
Example:
Scale relative to the current size¶
entityScaleBy(id, factor)
- Parameters:
id:Integer
the entity idfactor:Float
the multiplier,> 1enlarges and0 < factor < 1shrinks; the result is clamped to0.0625 ~ 10automatically- Return value:
trueon success;falsewhenfactor <= 0or the id does not exist - Return type:
Boolean -
Example:
Set the main variant number¶
entitySetVariant(id, variant)
- Parameters:
id:Integer
the entity idvariant:Integer
the variant number (the skin / subspecies); the same number means different things on different entities (a tropical fish's body shape, a pufferfish's puff state, say), and the library does not validate it- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the secondary variant number¶
entitySetMarkVariant(id, markVariant)
- Parameters:
id:Integer
the entity idmarkVariant:Integer
the secondary variant number; what it means depends on the entity type (a tropical fish's pattern, a horse's markings, say)- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the colour index¶
entitySetColorIndex(id, colorIndex)
- Parameters:
id:Integer
the entity idcolorIndex:Integer
the colour number, used for dyeable entities such as sheep and collars- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Overwrite the raw flags bitmask¶
entitySetFlags(id, flags)
- Parameters:
id:Integer
the entity idflags:Integer
the raw bitmask value (an advanced use), e.g.0x01= on fire,0x20= invisible; it replaces the whole block and is not merged with the old value- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Toggle entity invisibility¶
entitySetInvisible(id, on)
- Parameters:
id:Integer
the entity idon:Booleantrueinvisible /falsevisible again; it touches only that one bit, and it also returnstruewhen the value already matches (a repeated call has no side effects)- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the entity pose¶
entitySetPose(id, pose)
- Parameters:
id:Integer
the entity idpose:Integer
the pose number (PoseIndex), which only works on models that pose accordingly;0..13(0=standing,1=no base plate,2=show arms,3..13are sitting / sleeping / dancing and the like); an out-of-range value is clamped into this range automatically- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the item in an equipment slot¶
entitySetEquipmentSlot(id, slot, name, aux, nbt)
- Parameters:
id:Integer
the entity idslot:Integer0=mainhand1=offhand2=head3=chest4=legs5=feet; any other value returnsfalsename:String
the item id; a short name getsminecraft:added automatically; an empty string = clear that slotaux:Integer
the item's data value; what exactly it means depends on the itemnbt:String
extra data as SNBT text; an empty string = no extra data- Return value:
trueon success;falsewhenslotis out of range or the id does not exist - Return type:
Boolean -
Example:
const entitySetEquipmentSlot = ll.import("HologramLib", "entitySetEquipmentSlot"); entitySetEquipmentSlot(id, 0, "diamond_sword", 0, ""); // a diamond sword in the main hand entitySetEquipmentSlot(id, 2, "golden_helmet", 0, ""); // a golden helmet on the head entitySetEquipmentSlot(id, 0, "", 0, ""); // clear the main hand
Custom entities · Visibility¶
Who can see this entity is decided by dimension + view distance + whitelist + master switch together; the four conditions stack.
Toggle master visibility¶
entitySetEnabled(id, enabled)
- Parameters:
id:Integer
the entity idenabled:Booleanfalse= withdraw it from every client,true= send it out again- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the per-player view radius¶
entitySetViewDistance(id, dist)
- Parameters:
id:Integer
the entity iddist:Float
the distance (blocks);<= 0= no distance limit. The default at creation time is 64 blocks- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Restrict visibility with a whitelist¶
entitySetVisiblePlayers(id, playerNames)
- Parameters:
id:Integer
the entity idplayerNames:Array<String>
an array of player names (matched by LSE'splayer.realName); an empty array = clear the restriction and go back to visible to everyone- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Show the entity to a single player¶
entitySetVisiblePlayer(id, playerName)
- Parameters:
id:Integer
the entity idplayerName:String
the one visible player's name; it replaces the whole list rather than appending to it. UseentitySetVisiblePlayerswhen you want several players to see it; on the script side this is the one to prefer (no array to build)- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Clear the whitelist and restore everyone¶
entityClearVisiblePlayers(id)
- Parameters:
id:Integer
the entity id- Return value:
trueon success (it also returnstruewhen no whitelist was set in the first place);falsewhen the id does not exist - Return type:
Boolean -
Example:
Custom entities · Riding & animation¶
Make the entity ride a player¶
entitySetRidePlayer(id, playerName)
- Parameters:
id:Integer
the entity idplayerName:String
the player name, which must be online; an empty string = clear the riding link- Return value:
trueon success (it also counts astruewhen there was no link at all, and when an empty string clears one);falsewhen the id does not exist or the player is not online - Return type:
Boolean -
Example:
Make the entity ride another custom entity¶
entitySetRideEntity(id, vehicleEntityId)
- Parameters:
id:Integer
the entity id (the passenger)vehicleEntityId:Integer
the library id of the vehicle entity;0= clear the link- Return value:
trueon success;falsewhen the vehicle does not exist, the vehicle is the entity itself, or the id does not exist - Return type:
Boolean -
Example:
Clear player and entity riding links¶
entityClearRide(id)
- Parameters:
id:Integer
the entity id- Return value:
trueon success (it also returnstruewhen there was no link in the first place);falsewhen the id does not exist - Return type:
Boolean -
Example:
Play a vanilla animation for players who have seen it¶
entityPlayAnimation(id, animation, stopExpression, durationTicks)
- Parameters:
id:Integer
the entity idanimation:String
the animation identifier in the resource pack, such asanimation.humanoid.base_pose; an empty string is refusedstopExpression:String
a Molang stop expression; the animation stops when the expression is true; an empty string = it stays and never stops by itselfdurationTicks:Integer
when> 0, a stop is sent out automatically after that many ticks;0= no time limit- Return value:
truemeans it has been queued for sending (it reaches the client in about 2 ticks);falsewhen the id does not exist,animationis empty, the entity has been switched off withentitySetEnabled, or no player has seen this entity yet - Return type:
Boolean -
Example:
Custom entities · Per-client appearance¶
One entity, showing different nametags, scales and equipment to different players. An override takes effect only on the client of the player you name; everyone else still sees the shared configuration.
Change the nametag one player sees¶
entitySetPlayerNametag(id, playerName, text)
- Parameters:
id:Integer
the entity idplayerName:String
the viewer's name; they must be online and must have already seen this entitytext:String
the text only this player can see; an empty string = clear that player's override and go back to the shared nametag- Return value:
trueon success;falsewhen the id does not exist, the player is not online, or that player has not seen this entity yet - Return type:
Boolean -
Example:
Change the scale one player sees¶
entitySetPlayerScale(id, playerName, scale)
- Parameters:
id:Integer
the entity idplayerName:String
the viewer's name; they must be online and must have already seen this entityscale:Float
the scale that player sees, clamped to0.0625 ~ 10;<= 0= clear the override and go back to the shared scale- Return value:
trueon success;falsewhen the id does not exist, the player is not online, or that player has not seen this entity yet - Return type:
Boolean -
Example:
Change the equipment one player sees¶
entitySetPlayerEquipmentSlot(id, playerName, slot, name, aux, nbt)
- Parameters:
id:Integer
the entity idplayerName:String
the viewer's name; they must be online and must have already seen this entityslot:Integer0=mainhand1=offhand2=head3=chest4=legs5=feet; any other value returnsfalsename:String
the item id; an empty string = this slot falls back to the shared equipment for that playeraux:Integer
the item's data value; what exactly it means depends on the itemnbt:String
extra data as SNBT text; an empty string = no extra data- Return value:
trueon success;falsewhenslotis out of range, the id does not exist, the player is not online, or that player has not seen this entity yet - Return type:
Boolean -
Example:
Clear one player's appearance overrides¶
entityClearPlayerAppearance(id, playerName)
- Parameters:
id:Integer
the entity idplayerName:String
the viewer's name; they must be online- Return value:
truemeans the overrides really were cleared; returnsfalsewhen that player had no overrides at all, the id does not exist, or the player is not online - Return type:
Boolean -
Example:
Custom entities · Queries & destruction¶
Find the nearest custom entity¶
entityFindNearest(x, y, z, dim, maxDist)
- Parameters:
x:Float
the reference point's world coordinate Xy:Float
the reference point's world coordinate Yz:Float
the reference point's world coordinate Zdim:Integer
only entities in the same dimension are searched (a different dimension is skipped outright)maxDist:Float
the maximum distance (blocks);<= 0= no limit- Return value: the library id of the nearest entity;
-1when no entity is in range - Return type:
Integer -
Example:
Read the entity runtime summary¶
entityGetInfo(id)
- Parameters:
id:Integer
the entity id- Return value: the summary text (a diagnostic probe: id, dimension, coordinates, type, switch, scale, pose, equipment count, view distance, whitelist, number of players who have seen it, riding); returns
"not_found"when the id does not exist - Return type:
String -
Example:
Check whether an entity exists¶
entityExists(id)
- Parameters:
id:Integer
the entity id- Return value:
truewhen it exists,falsewhen it does not - Return type:
Boolean -
Example:
Check whether an id is taken¶
entityIsIdUsed(id)
It looks at the same record as entityExists, with a name that fits the "probe before you create" use better.
- Parameters:
id:Integer
the entity id- Return value:
truewhen it is taken,falsewhen it is free - Return type:
Boolean -
Example:
List every entity id¶
entityGetAllIds()
- Return value: the id array; an empty array when there are no entities at all
- Return type:
Array<Integer> -
Example:
Destroy one entity¶
entityDestroy(id)
- Parameters:
id:Integer
the entity id- Return value:
truewhen it really was destroyed;falsewhen the id does not exist. The one on the client disappears along with it - Return type:
Boolean -
Example:
Destroy every custom entity¶
entityDestroyAll()
- Return value: no return value
- Return type:
Null -
Example:
Interaction events (ghost*)¶
ghost* has only two functions, but they are used differently from the other domains; read these three points first:
- Events go into a queue; there is no callback. When a player clicks a library protocol entity (a custom entity / an item display / a fake-player NPC), the library puts that interaction into a pending queue, and you have to call
ghostPollInteractions()yourself, per tick or on a timer, to take it out; if you never take it, it just piles up in the queue. - The events come from client interaction packets. The library hooks the packet-receiving path, looks the target of each interaction packet from the client back up to its library id, and formats the result into a string for the queue. Only interactions that hit a library protocol entity enter this queue — a click on a real server-side entity (a vanilla mob, a player) never shows up here.
- The queue has a limit. It holds at most 256 entries, and once it is full a new event pushes the oldest one out; not polling = losing events.
Take and clear the interaction events¶
ghostPollInteractions()
- Return value: each entry is one event string; an empty array when the queue is empty
- Return type:
Array<String>
The format: player=<playerName> action=<1..6> domain=<entity|itemDisplay|npc> id=<libraryId>; when the client carries coordinates (InteractUpdate and the like) a pos=(x,y,z) is appended at the end.
action values: 1=Interact (right-click interaction) 2=Attack (left-click attack) 3=StopRiding 4=InteractUpdate 5=NpcOpen 6=OpenInventory. Check action before handling, and do not assume there are only 1 and 2.
domain says which kind was clicked: entity = a custom entity, itemDisplay = an FMBE item display, npc = a fake-player NPC.
- Example:
```js
const ghostPollInteractions = ll.import("HologramLib", "ghostPollInteractions");
setInterval(() => {
for (const line of ghostPollInteractions()) {
const m = line.match(/player=(\S+) action=(\d+) domain=(\S+) id=(-?\d+)/);
if (!m) continue;
const [, who, action, domain, targetId] = m;
if (action === "1" && domain === "entity") logger.info(`${who} right-clicked entity ${targetId}`);
if (action === "2" && domain === "entity") entityDestroy(Number(targetId)); // left-click = knock it out
}
}, 100);
```
Discard unhandled interaction events¶
ghostClearInteractions()
- Return value: no return value
- Return type:
Null -
Example:
Particle shapes · Creation¶
Particle shapes are defined in world coordinates; once created, the library emits and re-sends them on its own tick and you only control them. Seven shapes:
| Function | What it lays out |
|---|---|
particleCreatePoint |
a single point |
particleCreateLine |
a line between two points |
particleCreateRect |
a rectangular outline (a ring) |
particleCreatePlane |
a filled rectangular face (a mesh) |
particleCreateBox |
the 12-edge wireframe of a cuboid |
particleCreateBoxFaces |
all six faces of a cuboid, filled |
particleCreatePoly |
a custom polyhedron (you supply the vertices and edges) |
Several of the creation parameters are shared:
owner: a creator name tag. It is used only for the diagnostic display ofparticleGetInfoand has no effect on who can see the shape — visibility is decided byparticleSetVisible.dimId: the dimension,0Overworld /1Nether /2End.step: the sampling step (blocks), which is roughly how far apart two neighbouring particles are; anything below0.25is treated as0.25. The smaller the step, the denser the particles and the more packets are sent.effect: the particle effect name, such asminecraft:endrodorminecraft:heart_particle; an empty string uses the defaultminecraft:endrod.interval: the whole-batch re-send interval (ticks). Particles are transient by nature, so re-sending at this interval is what keeps the "resident" look; anything below1is treated as1.lifetime: how long it lives (ticks);0= permanent, and the shape disappears by itself when the time is up.
Lay out a particle point¶
particleCreatePoint(owner, dimId, x, y, z, effect, interval, lifetime)
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes aboveeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes abovex:Float
the world coordinate X the particles sit aty:Float
the world coordinate Y the particles sit atz:Float
the world coordinate Z the particles sit at- Return value: the shape id (incrementing from 1); a negative number on failure
- Return type:
Integer -
Example:
Lay out a particle line¶
particleCreateLine(owner, dimId, x1, y1, z1, x2, y2, z2, step, effect, interval, lifetime)
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovestep:Float
see the shared notes aboveeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes abovex1:Float
the world coordinate X of the first endpointy1:Float
the world coordinate Y of the first endpointz1:Float
the world coordinate Z of the first endpointx2:Float
the world coordinate X of the second endpointy2:Float
the world coordinate Y of the second endpointz2:Float
the world coordinate Z of the second endpoint- Return value: the shape id; a negative number on failure. The anchor is the line's midpoint: later rotation and scaling both happen about the midpoint
- Return type:
Integer -
Example:
Lay out a particle rectangle outline¶
particleCreateRect(owner, dimId, cx, cy, cz, w, h, axis, step, effect, interval, lifetime)
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovestep:Float
see the shared notes aboveeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes abovecx:Float
the world coordinate X of the rectangle's centrecy:Float
the world coordinate Y of the rectangle's centrecz:Float
the world coordinate Z of the rectangle's centrew:Float
the rectangle's width, its size along the plane's first axis; a negative number is treated as0h:Float
the rectangle's height, its size along the plane's second axis; a negative number is treated as0axis:Integer
the plane the rectangle lies in:0=XY (walong X,halong Y),1=YZ (walong Z,halong Y),2=XZ (walong X,halong Z); any other value is treated as0- Return value: the shape id; a negative number on failure. The anchor is the rectangle's centre
- Return type:
Integer -
Example:
Lay out a filled particle plane¶
particleCreatePlane(owner, dimId, cx, cy, cz, w, h, axis, step, effect, interval, lifetime)
The parameters are exactly the same as particleCreateRect.
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovecx:Float
the world coordinate X of the plane's centrecy:Float
the world coordinate Y of the plane's centrecz:Float
the world coordinate Z of the plane's centrew:Float
the plane's size along its first axis; a negative number is treated as0h:Float
the plane's size along its second axis; a negative number is treated as0axis:Integer
the plane's orientation,0=XY1=YZ2=XZ; any other value is treated as0step:Float
see the shared notes above. With face shapes, turnstepdown carefully — the particle count grows with the areaeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes above- Return value: the shape id; a negative number on failure. The anchor is the plane's centre
- Return type:
Integer -
Example:
Lay out a particle box wireframe¶
particleCreateBox(owner, dimId, cx, cy, cz, hx, hy, hz, step, effect, interval, lifetime)
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovestep:Float
see the shared notes aboveeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes abovecx:Float
the world coordinate X of the cuboid's centrecy:Float
the world coordinate Y of the cuboid's centrecz:Float
the world coordinate Z of the cuboid's centrehx:Float
the half size in the X direction (in blocks), i.e. half the edge length; a negative number is treated as0hy:Float
the half size in the Y direction (in blocks), i.e. half the edge length; a negative number is treated as0hz:Float
the half size in the Z direction (in blocks), i.e. half the edge length; a negative number is treated as0- Return value: the shape id; a negative number on failure. The anchor is the cuboid's centre
- Return type:
Integer -
Example:
Lay out a particle box with all six faces filled¶
particleCreateBoxFaces(owner, dimId, cx, cy, cz, hx, hy, hz, step, effect, interval, lifetime)
The parameters are exactly the same as particleCreateBox.
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovecx:Float
the world coordinate X of the cuboid's centrecy:Float
the world coordinate Y of the cuboid's centrecz:Float
the world coordinate Z of the cuboid's centrehx:Float
the half size in the X direction; a negative number is treated as0hy:Float
the half size in the Y direction; a negative number is treated as0hz:Float
the half size in the Z direction; a negative number is treated as0step:Float
see the shared notes above. All six faces are filled, so the particle count is many times that of the wireframeeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes above- Return value: the shape id; a negative number on failure. The anchor is the cuboid's centre
- Return type:
Integer -
Example:
Lay out a custom polyhedron¶
particleCreatePoly(owner, dimId, verts, edges, step, effect, interval, lifetime)
- Parameters:
owner:String
see the shared notes abovedimId:Integer
see the shared notes abovestep:Float
see the shared notes aboveeffect:String
see the shared notes aboveinterval:Integer
see the shared notes abovelifetime:Integer
see the shared notes aboveverts:String
the vertex string, in world coordinates, in the format"x,y,z;x,y,z;...", with at least 2 verticesedges:String
the edge string, pairs of vertex indices, in the format"i-j;i-j", with indices starting at0and having to fall inside the vertex range- Return value: the shape id; returns
-1when there are fewer than 2 vertices, not one usable edge in the edge string, or an index is out of range. The anchor is the centroid of all the vertices, and rotation and scaling happen about the centroid - Return type:
Integer -
Example:
Particle shapes · Movement & transforms¶
Every transform happens about the shape's anchor (line = midpoint, rectangle / plane / cuboid = centre, polyhedron = centroid).
Teleport the particle shape¶
particleSetPos(id, x, y, z)
- Parameters:
id:Integer
the shape idx:Float
the new world coordinate X of the shape's anchory:Float
the new world coordinate Y of the shape's anchorz:Float
the new world coordinate Z of the shape's anchor- Return value:
trueon success;falsewhen the id does not exist. On the next emission the whole batch of particles appears at the new position - Return type:
Boolean -
Example:
Move the shape by an offset¶
particleMoveBy(id, dx, dy, dz)
- Parameters:
id:Integer
the shape iddx:Float
the offset in the X direction (blocks)dy:Float
the offset in the Y direction (blocks)dz:Float
the offset in the Z direction (blocks)- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Slide the shape smoothly to a target point¶
particleMoveTo(id, x, y, z, durationTicks)
- Parameters:
id:Integer
the shape idx:Float
the target world coordinate X of the anchory:Float
the target world coordinate Y of the anchorz:Float
the target world coordinate Z of the anchordurationTicks:Integer
the slide duration (ticks);<= 0= arrive at once (equivalent toparticleSetPos)- Return value:
truemeans it has started moving;falsewhen the id does not exist. A whole face, or the whole shape, moves along with it - Return type:
Boolean -
Example:
Set the shape's three-axis Euler angles¶
particleSetRot(id, rx, ry, rz)
- Parameters:
id:Integer
the shape idrx:Float
the rotation angle about the X axis (degrees), rotating about the anchorry:Float
the rotation angle about the Y axis (degrees), rotating about the anchorrz:Float
the rotation angle about the Z axis (degrees), rotating about the anchor- Return value:
trueon success;falsewhen the id does not exist. It sets absolute angles, so it overwrites whatever angleparticleSpinhas accumulated - Return type:
Boolean -
Example:
Make the shape spin continuously¶
particleSpin(id, sx, sy, sz)
- Parameters:
id:Integer
the shape idsx:Float
the spin rate about the X axis (degrees/tick);0,0,0= stop spinningsy:Float
the spin rate about the Y axis (degrees/tick);0,0,0= stop spinningsz:Float
the spin rate about the Z axis (degrees/tick);0,0,0= stop spinning- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Scale the shape about its anchor¶
particleSetScale(id, s)
- Parameters:
id:Integer
the shape ids:Float
the scale factor; a value of0.01or less is treated as0.01- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Make the shape follow a player¶
particleFollow(id, uuid, offX, offY, offZ)
- Parameters:
id:Integer
the shape iduuid:String
the uuid string of the player to follow (not the player name); a string that does not parse into a uuid is refused outrightoffX:Float
the offset relative to the player in the X direction (blocks); a halo at the player's feet, for instance, uses0, 0.3, 0offY:Float
the offset relative to the player in the Y direction (blocks); a halo at the player's feet, for instance, uses0, 0.3, 0offZ:Float
the offset relative to the player in the Z direction (blocks); a halo at the player's feet, for instance, uses0, 0.3, 0- Return value:
trueon success;falsewhenuuidis not a valid uuid or the id does not exist - Return type:
Boolean -
Example:
Release the follow¶
particleUnfollow(id)
- Parameters:
id:Integer
the shape id- Return value:
trueon success;falsewhen the id does not exist. After releasing, the anchor goes back to the coordinates the shape recorded for itself (following never overwrote them), so the shape jumps back to where it was created or where the lastparticleSetPosput it - Return type:
Boolean -
Example:
Particle shapes · Appearance & visibility¶
Swap the particle effect¶
particleSetEffect(id, effect)
- Parameters:
id:Integer
the shape ideffect:String
the new particle effect name, such asminecraft:flame; an empty string is refused- Return value:
trueon success;falsewheneffectis empty or the id does not exist. It takes effect from the next emission - Return type:
Boolean -
Example:
Restrict who can see the shape¶
particleSetVisible(id, playersCsv)
- Parameters:
id:Integer
the shape idplayersCsv:String
a comma-separated string of player uuids, such as"uuid1,uuid2"; an empty string = everyone in the shape's dimension can see it. Entries that do not parse into a uuid are dropped- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Change the particle re-send interval¶
particleSetInterval(id, ticks)
- Parameters:
id:Integer
the shape idticks:Integer
the new re-send interval (ticks); anything below1is treated as1- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Set the per-player culling radius¶
particleSetViewDistance(id, blocks)
- Parameters:
id:Integer
the shape idblocks:Integer
the culling radius (blocks);0= no culling (a negative value is treated as0)- Return value:
trueon success;falsewhen the id does not exist. The defaults at creation time: a point shape is0(no culling) and the other shapes are96blocks - Return type:
Boolean -
Example:
Reset the particle lifetime¶
particleSetLifetime(id, ticks)
- Parameters:
id:Integer
the shape idticks:Integer
how many more ticks it can live from now on;0= make it permanent- Return value:
trueon success;falsewhen the id does not exist - Return type:
Boolean -
Example:
Particle shapes · Queries & destruction¶
Destroy a particle shape at once¶
particleDestroy(id)
- Parameters:
id:Integer
the shape id- Return value:
truewhen it really was destroyed;falsewhen the id does not exist - Return type:
Boolean -
Example:
Read the particle shape summary¶
particleGetInfo(id)
- Parameters:
id:Integer
the shape id- Return value: the summary text (a diagnostic probe: shape type,
owner, dimension, anchor, rotation, spin, scale, particle-point count,step, effect name, visible range, view distance, re-send interval, end time, whether it is moving smoothly); when the id does not exist it returns an empty string"" - Return type:
String -
Example:
Notes¶
ghost*must be polled. Interaction events do not go into a callback, they only sit in the queue; if you never callghostPollInteractions()you will never receive them. The queue holds at most 256 entries, and once it is full the oldest is dropped.- Only interactions that hit a library protocol entity enter the queue. Clicks on a custom entity, an item display or a fake-player NPC carry a
domainand a libraryid; a click on a real server-side entity (a vanilla mob, a player) never appears in the return value ofghostPollInteractions(). - A custom entity does not "appear the moment it is created". Who can see it is recalculated by the library on a timer, so a newly created entity shows up on the client within about 1 second at the latest; a property change triggers a recalculation along the way, which is usually faster.
- Protocol entities take no part in server-side logic. They have no AI, no collision and nothing written to the save: hitting one does not cost health, walking through one does not bump into it, and they all vanish after a restart — if you need persistence, save the ids yourself and restore them with
entityCreateWithId. - Visibility is the intersection of four conditions. Only a player who satisfies dimension + view distance + whitelist + the
entitySetEnabledswitch sees the entity; the whitelist does not "append", andentitySetVisiblePlayerreplaces the whole list. - By default a nametag only shows when the crosshair is on it. There is no function on the LSE side to switch "always shown" on; if you want it visible all the time like holographic text, hang a separate line of text on it with the
holo*domain. - Per-client orientation has no LSE export. "Each player sees a different orientation" (the
setPlayerRotationfamily) exists only on the C++ interface; the per-client functions on this page cover nametags, scale and equipment only. entityPlayAnimationsends one packet and does not persist. A player who only sees this entity later does not get the animation re-sent automatically; calling it whileentitySetEnabledhas the entity switched off returnsfalseoutright.- Particle shapes have no "destroy all" or "list every id" export. Your script has to keep the ids returned at creation itself, and
particleDestroythem one by one when tidying up. - The particle whitelist works by uuid and stacks with the dimension. When not one valid player on the whitelist is in the shape's dimension, the shape is removed automatically (it does not stay around waiting for someone); a shape whose dimension is merely empty is kept, spinning idle.
- Particles are a transient visual, kept alive by re-sending.
intervaldecides both the look and the packet volume: a larger interval saves more bandwidth and makes the "batch by batch" flicker easier to see; a smallerstepmeans denser particles, and with face shapes the particle count deserves particular care. - Purely visual, with no change to server-side state. These capabilities appear on the client only; the server's real world, save and logic are completely unaffected.