OOCQueue: the "replaced setting for nil" debug spam is gone. The internal dedup key was being built from (opType, seqName) where seqName was silently nil for three call sites that queued global settings changes rather than per-sequence ones. The queue collapsed every subsequent generic queue into the same nil bucket and logged a replacement notice each time. Fix is two-part: (1) the three offending callers in Engine.lua and TempoAdvisor.lua now pass stable seqName strings ("macroResetModifiers", "msClickRate", "UseKeyHeldSpellErrorPollTime"); (2) OOCQueue:Add rejects a nil seqName for any non-OOC_OP_GENERIC op so the bug cannot re-emerge from a future caller forgetting the key.
GRIP-EMS v1.9.9
Released April 19, 2026. 13 entries in the author's notes.
Every entry
The author's own words, complete. Long sections are sorted into areas by LazyGrip.
Fixed
3TempoAdvisor: GRIP_EMS_CHAR.tempoOffGCD is now patch-stamped. When the saved-variables shape from an earlier patch loads on a different build, Initialize migrates each spec entry to the {_patch=..., spells={...}} shape and wipes the classification cache for any entry whose _patch does not match the current GetBuildInfo() string. Prevents the stale-off-GCD-classification issues that accumulate across patches and previously required /gems holdreset. A new /gems fs reset subcommand wipes _runtimeOverrides, GRIP_EMS_CHAR.tempoOffGCD, and the internal spell-class cache for users who want to force a fresh scan.
SequenceEditor: SetPropagateKeyboardInput(true) is now re-applied on both PLAYER_REGEN_ENABLED and panel OnShow. Prior builds only reset on combat-exit, so re-opening the editor after a /reload in a previously-tainted state left the editor in a key-swallowing mode until the next combat cycle. The dual reset path covers both the reload-then-open case and the reload-then-combat case.
Added
2Interleave discoverability bundle (4-part). Interleave was previously a hidden feature that only surfaced if you selected a top-level Action node. The whole surface is now consistent:
- Every nested Action child row in the detail pane renders an inline
[checkbox] [interval editbox] stepswidget. Toggling the checkbox flipsnode.intervalbetweenACTION_INTERLEAVE_DEFAULTand nil; the editbox clamps to[ACTION_INTERLEAVE_MIN, ACTION_INTERLEAVE_MAX]and updates dirty state on enter. - The existing interleave checkbox in the detail settings bar now shows a tooltip (
GEMS_INTERLEAVE_TOOLTIP_TITLE/GEMS_INTERLEAVE_TOOLTIP_DESC) explaining what interleave does and when to use it. - The add-step menu picks up a distinct "Action (Interleave)" entry after "Step" in both outline and detail-pane modes. The new node ships with
node.interval = ACTION_INTERLEAVE_DEFAULTso the inline widget renders in its enabled state on first paint. Defaults.NodeSummarygrows anACTION_TYPE_ACTIONbranch that emits the first macro line truncated to 40 chars with..suffix when longer, and appends[IL:N]when interval is set. Top-level action badges in the outline now show the macro text and interval at a glance.
GRIP1 export checksum. GE.Export and GE.ExportCollection both compute S.ComputeTableChecksum over the sequence payload (or sequences map for collections) and stash the result in payload.checksum. The three import paths (LI._PreviewGRIP1COLLECTION + single, and GE.ImportNative used by TestSuite) recompute on decode and warn via GEMS_IMPORT_CHECKSUM_MISMATCHwhen the values diverge. Validation is non-blocking. The import still completes, and the only user-facing effect is a warning line in the import preview when a payload has been corrupted or tampered with in transit.
Changed
6Removed UI/ActionRenderers.lua and the matching TOC line. The file was introduced during the S14 hierarchical-actions work but was superseded by StepListView renderers and never called from any remaining code path.
Removed three dead diagnostic blocks from Core.lua that referenced the deleted AR namespace (/gems perf AR frame-pool dump, an AR.RenderActionTree tracer hook, and a hooksecurefunc(AR, "Render") instrumentation block).
Removed the 60-line dead ACTION branch in StepListView:_renderDetailSettings. The branch was unreachable because detail settings for ACTION nodes have always routed through the interleave block. Its presence made the function harder to read.
SpellValidator.NodeHasInvalidSpells exposes a collectAll flag so badge calculations short-circuit on the first UNKNOWN while tooltip callers enumerate the full invalid list. The tooltip now shows every invalid spell inside a Loop/If/Embed subtree instead of just the first one.
The "new spell" tooltip built from the Spell Picker clamps to the screen edge via SetClampedToScreen(true) and flips anchor (ANCHOR_RIGHT -> ANCHOR_LEFT) when the owner sits in the right half of the viewport. Prevents overflow off the right edge on wide-tooltip content at high UI scale.
TempoAdvisor: flyout children (Call Pet 1-5, Hunter's Mark on [nopet], Warlock summon demon variants, Mage Teleport/Portal children) no longer get reclassified as OFF_GCD during combat. The previous guard referenced a non-existent SpellCachetable and silently passed every flyout child through to ReclassifyOffGCD, inflating complexity to INTENSE on any sequence that referenced one. Fix adds a spellID-keyed index to SpellCache and routes both the ScanPendingDurationZero and UNIT_SPELLCAST_SUCCEEDED guards through it. A one-shot scrub on the first SPELL_CACHE_REFRESHED after login drops poisoned entries from _runtimeOverrides and GRIP_EMS_CHAR.tempoOffGCDwithout requiring /gems holdreset. A write-side guard on ReclassifyOffGCD catches any future call-site before it can re-poison the tables.
Internal
2Data/SpellCache.lua: new self.byID map, spellID -> entry. Built in Scan() after the byName pass. Zero extra cost on lookup-heavy TempoAdvisor paths that previously had no way to resolve spellID to entry metadata.
Four new locale keys across all eleven locale files: GEMS_INTERLEAVE_TOOLTIP_TITLE, GEMS_INTERLEAVE_TOOLTIP_DESC, GEMS_ADD_ACTION_INTERLEAVE, GEMS_IMPORT_CHECKSUM_MISMATCH. Non- English files carry the English text with a -- MT marker.
Grab it
Release notes written by Sataana and reproduced here with his permission.