Skip to content

Colored Lights

MehVahdJukaar edited this page Oct 7, 2026 · 4 revisions

Colored Lights

This is an experimanle feature lets you make things cast actual colored light into the world, on blocks, entities or particles.

Important

This feature has the following configs:

  • Built-in (default): tints vanilla's block light on blocks, entities and particles. See Colored block light. block lights spread through the world and stop at walls. entity, item and particle lights are moving point lights: the 64 closest to the camera glow, and they shine through walls.
  • Hybrid: Built-in for block lights, and the Veil mod for entity, item and particle lights. Without Veil it is the same as Built-in.
  • Veil: needs the Veil mod. Veil does the rendering, Polytone tells it what glows. All light types work.
  • Off: these files are ignored and light stays vanilla.

Your pack works for everybody either way: players without colored lights just see vanilla light.

Getting Started

There are two ways to add colored lights:

First way is adding a file in assets/[your namespace]/polytone/colored_lights/[name].json. Second way is by using the `colored_light' field in Block, Particles, Item or Entity modifiers.

{
  "targets": ["minecraft:glowstone", "minecraft:sea_lantern"],
  "colored_light": "#FFD79B"
}

Fields

Field Description
colored_light The light. Either a color on its own, or an object with color, radius and brightness. Required.
target_type What you are lighting: block, entity, item or particle. Defaults to block.
targets What to light: an id, list, tag or regex. See Shared Concepts. Required.
state_predicate Blocks only. A Rule Test that picks which blockstates glow.

The long form of colored_light looks like this:

{
  "colored_light": {
    "color": "#4FD8D8",
    "radius": 12,
    "brightness": 0.8
  }
}

radius is in blocks and defaults to the block's own light level (8 for everything else). brightness multiplies the color and defaults to 1.

Target Types

item lights up the item, both when it's lying on the ground and when someone is holding it. A held item simply lights up whoever holds it, from the middle of their hitbox. entity lights up the mob itself:

{
  "target_type": "item",
  "targets": ["minecraft:torch", "minecraft:lantern"],
  "colored_light": "#FFB55C"
}

Shortcut: Modifiers

If you already have a modifier for the thing you want to light up, just add colored_light there instead of making a second file. It's the same field and it ends up in the same place:

// block_modifiers/sea_lantern.json
{
  "sound_type": "glass",
  "colored_light": { "color": "#8FE8DC", "radius": 14 }
}

This works on Block, Item, Entity and Particle Modifiers. Item modifiers light the dropped item, exactly like target_type: item.

Expressions

Every value takes an expression, so you can pick which states glow without a state_predicate, and you can animate the light. A brightness of 0 means no light:

{
  "targets": ["minecraft:redstone_torch", "minecraft:redstone_wall_torch"],
  "colored_light": {
    "color": "#FF2200",
    "brightness": "object.blockStateValue('lit') ? 1 : 0"
  }
}

Or make it flicker:

{
  "colored_light": {
    "color": "#FF8A3C",
    "brightness": "0.85 + 0.15 * sin(g.time() * 0.2)"
  }
}

Plain numbers and colors stay constant, so they cost nothing.

Note

Lights only cost performance while they're on screen. With Veil, Polytone caps at 512 block lights and 256 entity lights, nearest first. With Built-in, the 64 entity, item and particle lights closest to the camera glow. Don't put a light on something as common as stone.

For Mod Developers

Mods can add the same lights from code with VoxelVolumeApi.registerCallback (package net.mehvahdjukaar.polytone.api). Call it during client setup. The callback runs on every resource reload and can add block, entity, item and particle lights, per-block voxel flags, and per-block-entity voxel data. Pick Activation.WITH_COLORED_LIGHTS to only run it when a loaded pack has colored lights, or Activation.ALWAYS.

VoxelVolumeApi.registerCallback(VoxelVolumeApi.Activation.ONLY_WITH_COLORED_LIGHT_PACKS, e -> {
    e.addBlockLight(Blocks.GLOWSTONE, new ResolvedPointLight(0x60C0FF, 12));
    e.addBlockLight(Blocks.CAMPFIRE, state -> state.getValue(CampfireBlock.LIT)
            ? new ResolvedPointLight(0xFF8030, 14) : null);
});

Lights from code take a fixed ResolvedPointLight(color, radius) or a function that returns one. Block functions run once per blockstate. Entity, item and particle functions run every tick, so keep them cheap. If a block entity's light data changes without a block update, call VoxelVolumeApi.markDirty(pos).

Clone this wiki locally