---
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<EntityStore> 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<EntityStore> 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<Ref<EntityStore>, Integer> pulsingEntities = new ConcurrentHashMap<>();

// Call this method each tick
public void onTick(float deltaTime) {
    for (Map.Entry<Ref<EntityStore>, Integer> entry : pulsingEntities.entrySet()) {
        Ref<EntityStore> 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<EntityStore> entityRef) {
    pulsingEntities.put(entityRef, 0);
}

public void stopPulsingLight(Ref<EntityStore> 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 >}}
