Testing

Back to Lambent

Lambent’s tests run inside a real game client, because what they check is what ends up on screen. Every jar includes the self-test, but it does nothing unless the game is started with -Dlambent.selftest=true.

Running it

gradlew :1.20.1:forge:runClient    -Plambent.selftest
gradlew :1.21.1:neoforge:runClient -Plambent.selftest
gradlew :26.3:neoforge:runClient   -Plambent.selftest -Plambent.only=26.3

The client starts, creates a flat test world at night, runs every case, writes a report and closes itself. A full run takes a few minutes.

What it checks

The test world is a flat floor with a stone pillar in front of the camera. Each case lights the scene, waits for the frame to settle, reads back the screen, and compares the brightness of chosen spots against the same spots with no lights.

Cases What passes
baseline Lights are not broken, and the frame time with nothing lit.
pair, point, glow, lens Each kind of light brightens the pixels it should.
spot-shadow, point-shadow The floor in the light comes up. The floor behind the pillar stays dark.
limits-* Each kind takes exactly its room per frame (Lights.MAX_*) and refuses the next one.
fade frame.fade eases a light in without ever dimming it.
failing-source A source that throws is switched off, and the other sources keep lighting.
clear-cache After the resource reload path (LightRenderer.clearCache), shadows build again.
fabulous-* The baseline and both shadow cases again under Fabulous graphics.
fancy-again Back to Fancy, nothing left broken by the switch.
perf Frame time with one of every kind lit at once.
after-lights AfterLights runs every frame, always with a camera.

Every case is followed by a -healthy check: the light pass is still on, and none of the test’s own sources has thrown.

The thresholds are relative to the unlit frame, so they hold on any GPU and at any window size. The shadow cases need the floor behind the pillar to stay below a fraction of what the lit floor gets.

Last results

Run on an RTX 2060 at 854×480. The times are whole frames (the time from one frame to the next, in the small test world), so the difference between the two columns is roughly what the lights cost.

Version Result Frame, nothing lit Frame, every kind lit
1.20.1 Forge 43/43 0.49 ms 0.66 ms
1.21.1 NeoForge 43/43 0.51 ms 0.67 ms
26.1.2 NeoForge 43/43 0.66 ms 0.92 ms
26.2 NeoForge 43/43 0.78 ms 1.45 ms
26.3 NeoForge 43/43 0.55 ms 0.84 ms

Timings vary by a few tenths of a millisecond from run to run.

When a case fails