EQL Source / Tools / Gap engine
Gap engine.
Every other tracker here tells you what you have. This one reads your combat log and tells you what to change — as a difference against what you are already doing, never a score to hit. And it says out loud what it will not answer.
Reads your logYour log never leaves this machineNot yet live
This page is a preview and every number on it is invented. The engine runs, on real logs, in its own repository — it is not yet wired into this site, so there is no file input here rather than one that does nothing. A control that invites you to drop in a log and then does nothing would be the page lying to you, and this is a tool whose whole claim is that it refuses to overstate.
What would make it live: the engine ships as a bundle. When it does, this page reads your log in your browser and sends nothing — there is no server to send it to, and this site holds no logs at all, so it could not compute your figures even if it wanted to.
SYNTHETIC. Generated by running gapengine.py over an invented log, so the SHAPE is always exactly what the engine emits and cannot drift from it. The numbers carry no measurement and cannot be wrong.
Measured, and modelled, are shown as two different things
A page that mixes them invites you to trust the weaker one.
Measured comes out of the log, computed in your browser. A DPS figure always carries the window it was measured over: four shipped meters use four denominators, and the spread is more than double.
Counted, but not turned into a rate
A count with no denominator is not a rate, and the engine says so in the data rather than leaving a page to work it out.
-
Example Nuke IIIno denominator
Resisted 2 times, landed 0 — no rate is claimed.
Why: no landings of this spell appear as direct-damage lines (a damage-over-time effect reports differently), so the denominator is unknown and NO RATE IS CLAIMED
What it found, and what it refused
These two columns carry equal weight on purpose. A tool that shows only what it found reads as “nothing else to improve”.
Deltas 3
Every one is a difference against your own measured baseline. The output has no field for a modelled absolute, so a page cannot print one by accident.
-
stanceestimate
Offensive stance instead of Balanced
+86.582% of your measured 105.2 DPS (engaged)
material
cost: none - one keypress · class_any: the 9 martial classes
What would show this wrong: A following log at the same gear whose non-crit melee endpoint does not approximately double.
-
lane.bashfloor
fire bash at its cooldown rather than the observed 0.08/s while in melee
+8.88% of your measured 105.2 DPS (engaged)
modest - a few percent of this character's output
cost: none - rotation only
What would show this wrong: A following log at a measured bash rate above 0.43/s in melee showing no lane gain.
-
lane.kickfloor
fire kick at its cooldown rather than the observed 0.09/s while in melee
+7.27% of your measured 105.2 DPS (engaged)
modest - a few percent of this character's output
cost: none - rotation only
What would show this wrong: A following log at a measured kick rate above 0.43/s in melee showing no lane gain.
Refusals 3
What it declined, with the reason and what would settle it. A tool that silently omits what it cannot do fails open: a short list reads as good news.
-
item.selectionsomeone else does this better
Which obtainable item meets a stat floor is a catalogue question.
What would settle it: eqlegendstools.com holds this and does it well. Link, do not clone.
-
worn.statsa log cannot see it
A log does not show worn stats. AC, resists and worn ATK were not seen.
What would settle it: The 50 Upgrades gear input, or a character-panel reading.
-
engaged_time.comparisonrefused, with no override
Comparing how long two named characters were engaged is refused in all cases.
What would settle it: Nothing. Hard refusal, ruled 30 August 2026.
What it saw, and what it assumed
Observed: crit rate, engaged time, resist counts, stance.
Assumed, and therefore a source of error:
haste at cap, target mitigation, buff uptime.
