--- title: Dynamic Lights type: docs weight: 2 --- Dynamic lights add glow effects to entities using the `DynamicLight` component. ## ColorLight Structure The `ColorLight` class defines light properties: ```java import com.hypixel.hytale.protocol.ColorLight; public class ColorLight { public byte radius; // 0-255 (light radius/intensity) public byte red; // 0-255 (red channel) public byte green; // 0-255 (green channel) public byte blue; // 0-255 (blue channel) public ColorLight(byte radius, byte red, byte green, byte blue) { this.radius = radius; this.red = red; this.green = green; this.blue = blue; } } ``` ## DynamicLight Component Add temporary glow effects to entities: ```java import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight; import com.hypixel.hytale.protocol.ColorLight; // Create colored light (radius, R, G, B) ColorLight light = new ColorLight( (byte) 15, // Radius (0-255) (byte) 255, // Red (0-255) (byte) 100, // Green (0-255) (byte) 50 // Blue (0-255) ); // Add DynamicLight component DynamicLight dynamicLight = new DynamicLight(light); componentAccessor.putComponent( entityRef, DynamicLight.getComponentType(), dynamicLight ); ``` ## PersistentDynamicLight Component Use this component when light should be saved with entity data: ```java import com.hypixel.hytale.server.core.modules.entity.component.PersistentDynamicLight; // Create persistent light PersistentDynamicLight persistentLight = new PersistentDynamicLight(light); componentAccessor.putComponent( entityRef, PersistentDynamicLight.getComponentType(), persistentLight ); ``` ## Updating Light Properties ```java // Get existing light component DynamicLight dynamicLight = store.getComponent( entityRef, DynamicLight.getComponentType() ); if (dynamicLight != null) { // Create new light properties ColorLight newLight = new ColorLight( (byte) 20, // New radius (byte) 0, // No red (byte) 255, // Full green (byte) 100 // Some blue ); // Update and mark for network sync dynamicLight.setColorLight(newLight); // isNetworkOutdated is set automatically } ``` ## Removing Light ```java // Remove the component to disable light componentAccessor.removeComponent( entityRef, DynamicLight.getComponentType() ); ``` ## Common Light Configurations ### Fire/Warm Glow ```java ColorLight fireLight = new ColorLight( (byte) 12, (byte) 255, // High red (byte) 150, // Medium orange (byte) 50 // Low blue ); ``` ### Ice/Cold Glow ```java ColorLight iceLight = new ColorLight( (byte) 10, (byte) 100, // Low red (byte) 200, // Medium green (byte) 255 // High blue ); ``` ### Magic/Purple Glow ```java ColorLight magicLight = new ColorLight( (byte) 15, (byte) 200, // High red (byte) 50, // Low green (byte) 255 // High blue ); ``` ### Healing/Green Glow ```java ColorLight healLight = new ColorLight( (byte) 10, (byte) 50, // Low red (byte) 255, // High green (byte) 100 // Medium blue ); ``` ## Practical Examples ### Adding a Glow Effect to a Player ```java // Add temporary glow effect to a player public void addGlowEffect(Player player, ComponentAccessor componentAccessor, ScheduledExecutorService scheduler) { World world = player.getWorld(); // Add temporary glow ColorLight glow = new ColorLight( (byte) 8, (byte) 255, (byte) 215, (byte) 0 // Gold color ); DynamicLight light = new DynamicLight(glow); Ref entityRef = player.getReference(); componentAccessor.putComponent( entityRef, DynamicLight.getComponentType(), light ); // Remove after 3 seconds using standard Java scheduling scheduler.schedule(() -> { world.execute(() -> { if (entityRef.isValid()) { componentAccessor.removeComponent( entityRef, DynamicLight.getComponentType() ); } }); }, 3, TimeUnit.SECONDS); } ``` {{< callout type="warning" >}} **Note:** Use `player.getReference()` to get the entity reference, not `player.getEntityRef()`. Use standard Java `ScheduledExecutorService` for delayed tasks. {{< /callout >}} ### Pulsing Light Effect Implement pulsing effects by updating the light in a tick handler: ```java // Track pulsing entities private final Map, Integer> pulsingEntities = new ConcurrentHashMap<>(); // Call this method each tick public void onTick(float deltaTime) { for (Map.Entry, Integer> entry : pulsingEntities.entrySet()) { Ref entityRef = entry.getKey(); int tick = entry.getValue() + 1; entry.setValue(tick); // Calculate pulsing intensity double pulse = Math.sin(tick * 0.1) * 0.5 + 0.5; byte radius = (byte) (5 + pulse * 10); ColorLight light = new ColorLight( radius, (byte) 255, (byte) (int)(100 + pulse * 100), (byte) 50 ); DynamicLight dynamicLight = store.getComponent( entityRef, DynamicLight.getComponentType() ); if (dynamicLight != null) { dynamicLight.setColorLight(light); } } } public void startPulsingLight(Ref entityRef) { pulsingEntities.put(entityRef, 0); } public void stopPulsingLight(Ref entityRef) { pulsingEntities.remove(entityRef); } ``` ## Network Synchronization {{< callout type="info" >}} **Sync Details:** - `DynamicLight` changes are automatically marked for sync when using `setColorLight()` - The `isNetworkOutdated` flag triggers client updates - Use `consumeNetworkOutdated()` before manual sync operations {{< /callout >}} ## DynamicLight vs PersistentDynamicLight | Feature | DynamicLight | PersistentDynamicLight | |---------|--------------|------------------------| | Saved to disk | No | Yes | | Survives restart | No | Yes | | Use case | Temporary effects | Permanent glows | | Performance | Lighter | Slightly heavier | ## Best Practices {{< callout type="warning" >}} **Light Guidelines:** - Keep radius values reasonable (5-20 for most effects) - Don't add lights to too many entities simultaneously - Remove temporary lights when no longer needed - Use `PersistentDynamicLight` only when persistence is required {{< /callout >}}