Skip to content
3 Death Saves
Wiki updated as of 1.3.1 (Sep 2026)

Module API

The API is available from init at game.modules.get('tokenlightcondition').api and at the TLC.api global.

if (game.modules.get('tokenlightcondition')?.active) TLC.api.refreshAllTokenLighting();
MethodSignatureReturns
determineLightLevel(token, position?)Promise<'bright' | 'dim' | 'dark'>
getEffectiveLightLevel(token)'bright' | 'dim' | 'dark' | null
getLightLevel(token)'bright' | 'dim' | 'dark' | null
recalculate(token, position?)Promise<void>
refreshAllTokenLighting()Promise<'refreshed' | 'coalesced'>

Every method that takes a token accepts a Token placeable or a TokenDocument. A position is a canvas center point { x, y, elevation }.

Calculates a token’s light level without applying effects or storing anything. Pass position to test another spot. It ignores HP, so a token at 0 HP still gets a level. The promise rejects if the calculation fails.

Returns the stored level adjusted for vision. When the stored level is dark and the token’s vision mode sees unlit ground, such as darkvision, with a sight range above 0, it returns dim. Otherwise it returns the stored level.

Returns the level stored on the token, or null when the token has not been calculated or its level was cleared.

Recalculates one token and applies the result. A token at 0 HP has its stored level and effect cleared. With position, the token is queued only when the level there differs from its stored level, and the committed level still comes from where the token stands. It does nothing on a client that is not the primary GM, or for an actor that is not a character or NPC.

Recalculates every eligible token on the viewed scene and resolves 'refreshed' once effects and levels are committed. A call made while a refresh is running resolves 'coalesced' immediately, and the running refresh repeats when it finishes. When the viewed scene is not the active scene, nothing is recalculated, a warning is shown once for that scene, and the promise still resolves 'refreshed'. Only the primary GM’s client calculates.

Fires on every client for each token whose stored level changes.

Hooks.on('tokenlightcondition.lightLevelChanged', (tokenDocument, newLevel, oldLevel) => {
console.log(tokenDocument.name, oldLevel, '->', newLevel);
});
ArgumentTypeMeaning
tokenDocumentTokenDocumentThe token whose level changed
newLevel'bright' | 'dim' | 'dark' | nullThe committed level; null when the token was cleared
oldLevel'bright' | 'dim' | 'dark' | nullThe level stored before the change

Fires each time the module collects the scene’s light sources, before tokens are scored. Push objects onto sources to add light the scene does not have.

Hooks.on('tokenlightcondition.gatherLightSources', (sources, scene) => {
sources.push({ x: 1000, y: 1000, elevation: 0, dim: 40, bright: 20, priority: 0 });
});
PropertyMeaning
x, yCanvas coordinates
elevationElevation in scene distance units; defaults to 0
dim, brightRadii in scene distance units; default to 0
priorityResolution order against other sources; defaults to 0
darknesstrue to lower the level instead of raising it

A contributed source reaches a token inside its radius, measured as a cylinder around its elevation. It ignores walls and emission angles, but light-restricting tiles still block it.