Dynamic Lighting
Dynamic Lighting
Section titled “Dynamic Lighting”Dynamic lighting allows entities to emit light that moves with them. The system supports both temporary runtime lights and persistent lights that survive entity respawn.
Package Location
Section titled “Package Location”- Components:
com.hypixel.hytale.server.core.modules.entity.component - Systems:
com.hypixel.hytale.server.core.modules.entity.dynamiclight
Overview
Section titled “Overview”Dynamic lights are ECS components attached to entities. Two component types exist:
| Component | Persistence | Use Case |
|---|---|---|
DynamicLight | Runtime only | Temporary effects (spell glow, fire) |
PersistentDynamicLight | Saved with entity | Permanent lights (lantern entity) |
Components
Section titled “Components”DynamicLight
Section titled “DynamicLight”Runtime light component for entities:
package com.hypixel.hytale.server.core.modules.entity.component;
public class DynamicLight implements Component<EntityStore> { public DynamicLight(); public DynamicLight(ColorLight colorLight);
public ColorLight getColorLight(); public void setColorLight(ColorLight colorLight); public boolean consumeNetworkOutdated();
public static ComponentType<EntityStore, DynamicLight> getComponentType();}PersistentDynamicLight
Section titled “PersistentDynamicLight”Serializable light component that persists with entity data:
package com.hypixel.hytale.server.core.modules.entity.component;
public class PersistentDynamicLight implements Component<EntityStore> { public static final BuilderCodec<PersistentDynamicLight> CODEC;
public PersistentDynamicLight(ColorLight colorLight);
public ColorLight getColorLight(); public void setColorLight(ColorLight colorLight);
public static ComponentType<EntityStore, PersistentDynamicLight> getComponentType();}ColorLight
Section titled “ColorLight”Light color and radius definition:
package com.hypixel.hytale.protocol;
public class ColorLight { public byte radius; public byte red; public byte green; public byte blue;
public ColorLight(); public ColorLight(byte radius, byte red, byte green, byte blue); public ColorLight(ColorLight other);
public ColorLight clone();}ECS Systems
Section titled “ECS Systems”DynamicLightSystems
Section titled “DynamicLightSystems”Contains systems for managing dynamic lights:
package com.hypixel.hytale.server.core.modules.entity.dynamiclight;
public class DynamicLightSystems { // creates DynamicLight from PersistentDynamicLight when entity is added public static class Setup extends HolderSystem<EntityStore> { // query: has PersistentDynamicLight AND NOT DynamicLight // onEntityAdd: creates DynamicLight from persistent light }
// notifies clients when a DynamicLight component is removed public static class EntityTrackerRemove extends RefChangeSystem<EntityStore, DynamicLight> { // onComponentRemoved: sends ComponentUpdateType.DynamicLight to trackers }}Usage Examples
Section titled “Usage Examples”Adding Dynamic Light to Entity
Section titled “Adding Dynamic Light to Entity”import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight;import com.hypixel.hytale.protocol.ColorLight;
// create light (radius 8, warm orange glow)ColorLight torchLight = new ColorLight((byte) 8, (byte) 15, (byte) 10, (byte) 5);
// add dynamic light component to entityDynamicLight light = new DynamicLight(torchLight);store.addComponent(entityRef, DynamicLight.getComponentType(), light);Adding Persistent Light to Entity
Section titled “Adding Persistent Light to Entity”import com.hypixel.hytale.server.core.modules.entity.component.PersistentDynamicLight;import com.hypixel.hytale.protocol.ColorLight;
// create persistent light (survives respawn/reload)ColorLight lanternLight = new ColorLight((byte) 12, (byte) 15, (byte) 15, (byte) 12);PersistentDynamicLight persistentLight = new PersistentDynamicLight(lanternLight);
// add to entity — DynamicLight will be auto-created by the Setup systemstore.addComponent(entityRef, PersistentDynamicLight.getComponentType(), persistentLight);Updating Light Color
Section titled “Updating Light Color”import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight;import com.hypixel.hytale.protocol.ColorLight;
// get existing light componentDynamicLight light = store.getComponent(entityRef, DynamicLight.getComponentType());
// update to new color (flickering effect)ColorLight flickerLight = new ColorLight( light.getColorLight().radius, (byte) random.nextInt(12, 16), (byte) random.nextInt(8, 12), (byte) random.nextInt(3, 7));light.setColorLight(flickerLight);Removing Dynamic Light
Section titled “Removing Dynamic Light”import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight;
// remove light component — EntityTrackerRemove system will notify clientsstore.removeComponent(entityRef, DynamicLight.getComponentType());Querying Entities with Lights
Section titled “Querying Entities with Lights”import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight;import com.hypixel.hytale.component.query.Query;
// query for entities with dynamic lightsQuery<EntityStore> lightQuery = Query.builder(EntityStore.class) .with(DynamicLight.getComponentType()) .build();
for (ArchetypeChunk<EntityStore> chunk : store.query(lightQuery)) { DynamicLight[] lights = chunk.getComponentArray(DynamicLight.getComponentType()); for (int i = 0; i < chunk.getEntityCount(); i++) { ColorLight color = lights[i].getColorLight(); }}Light Values
Section titled “Light Values”ColorLight has no built-in presets. You define your own values using the byte fields directly.
Here are some illustrative examples to get you started:
| Example | Radius | R | G | B | Description |
|---|---|---|---|---|---|
| Warm torch | 8 | 15 | 10 | 5 | Orange glow |
| Bright lantern | 12 | 15 | 15 | 12 | Warm white |
| Red glow | 7 | 15 | 0 | 0 | Pure red |
| Cool blue | 10 | 5 | 12 | 15 | Blue-cyan |
// illustrative — define your own presetsColorLight warmTorch = new ColorLight((byte) 8, (byte) 15, (byte) 10, (byte) 5);ColorLight brightLantern = new ColorLight((byte) 12, (byte) 15, (byte) 15, (byte) 12);Network Synchronization
Section titled “Network Synchronization”Dynamic lights are automatically synchronized to clients:
- On Add: Light component sent with entity spawn
- On Update:
setColorLight()marks network dirty - On Remove:
EntityTrackerRemovesystem notifies trackers - Update Type:
ComponentUpdateType.DynamicLight
Integration with Chunk Lighting
Section titled “Integration with Chunk Lighting”Dynamic entity lights work alongside chunk-based lighting:
- Chunk Light: Static, calculated once, stored in
ChunkLightData - Dynamic Light: Real-time, follows entity, rendered client-side
The client combines both light sources for final illumination.
Persistent Light Serialization
Section titled “Persistent Light Serialization”PersistentDynamicLight is saved with entity data:
{ "Components": { "Light": { "Radius": 8, "Red": 15, "Green": 10, "Blue": 5 } }}The codec is defined on PersistentDynamicLight.CODEC and uses ProtocolCodecs.COLOR_LIGHT via BuilderCodec with the key "Light".
Best Practices
Section titled “Best Practices”- Use Persistent for permanent lights: Lanterns, glowing items, etc.
- Use Runtime for effects: Spell glows, fire, temporary buffs
- Limit light count: Many dynamic lights can impact performance
- Reasonable radius: Keep radius under 15 for best results
- Update frequency: Don’t update every tick unless needed (flickering)
Related
Section titled “Related”- Light Propagation - Chunk-based lighting
- Entity System - Entity management
- ECS Overview - Component architecture