From c6a37807532739d217df7f1f765a951e5be145e5 Mon Sep 17 00:00:00 2001 From: Jon Kazama Date: Fri, 15 May 2026 11:51:25 +0200 Subject: [PATCH] docs: add v1.4.9 changelog and forge announcement post MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Synchronises the v1.4.9 changelog across the manifest sources that the Dalamud plugin installer, the gitea repo.json feed and the Forge auto- announce workflow read at release-tag time. Files touched: - HellionChat/HellionChat.yaml: v1.4.9 block inserted at the top of the changelog: literal. v1.4.5 dropped to keep the slim-rule at 4 subblocks (preflight Block C enforces YAML_VERSIONS <= 4). Current set is v1.4.9/v1.4.8/v1.4.7/v1.4.6. - repo.json: Changelog field kept synchronous with the yaml — v1.4.9 block prepended, v1.4.5 substring removed, JSON-escaped newlines. - .github/forge-posts/v1.4.9.md: new file with frontmatter (subtitle "Plugin-Load Render Polish", versionsnatur "Performance-Patch") and a German-only body. The English half of the eventual Discord embed is pulled automatically from the yaml changelog at tag-push time by .gitea/workflows/forge-announce.yml — same workflow as v1.4.4 onwards, the post file does not carry an English block. Char-cap pre-check passes (title 46 + description ~2700 + footer 33 = ~2800 chars, well under the 5500-char Discord embed total cap). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/forge-posts/v1.4.9.md | 28 ++++++++++++++++++++ HellionChat/HellionChat.yaml | 50 +++++++++++++++++++---------------- repo.json | 2 +- 3 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 .github/forge-posts/v1.4.9.md diff --git a/.github/forge-posts/v1.4.9.md b/.github/forge-posts/v1.4.9.md new file mode 100644 index 0000000..41928d0 --- /dev/null +++ b/.github/forge-posts/v1.4.9.md @@ -0,0 +1,28 @@ +--- +subtitle: Plugin-Load Render Polish +versionsnatur: Performance-Patch +--- + +- First-Frame-HITCH unter 100 ms: der erste Render-Frame des Plugins liegt + jetzt bei ~76 ms Median (vorher ~127 ms), die Dalamud-Warnung + „UiBuilder(Hellion Chat) > 100ms" beim Plugin-Start ist damit weg. + Erreicht durch das Verlagern von sechs nicht-essentiellen Render- + Sektionen (Statusleiste, Kanalname-Chunks, Fenster-Bounds-Check, + Hinweis-Banner, Autocomplete, Input-Preview) auf den zweiten Frame. + Bei 60 fps sieht man die deferred-Sektionen ~17 ms später, was im + Atlas-Build-Fenster nach einem Reload unsichtbar bleibt. +- Slash-Commands zentral registriert: /hellion, /hellionView, + /hellionSeString und /hellionDebugger werden jetzt im Plugin-Load zentral + registriert statt erst beim ersten Öffnen ihres Ziel-Fensters. Heißt: die + Befehle funktionieren ab dem ersten Tick, auch wenn das jeweilige Fenster + nie geöffnet wurde. Der „Einstellungen"-Button im Plugin-Manager hängt am + selben Pfad. +- Plugin-Load-Diagnose-Logs als Tripwire: die Profiling-Logs für + MessageStore.Connect, MessageStore.Migrate, FilterAllTabs und den + Auto-Translate-Warmup bleiben auf Information-Level eingeschaltet. Falls + eine zukünftige Änderung die Lade-Zeit wieder über 100 ms drückt, taucht + der Mehrverbrauch direkt im /xllog auf, ohne dass jemand erst den + Debug-Filter einschalten muss. +- Migration v17 unverändert: kein Schema-Bump, kein Config-Migrations- + Aufwand. Nach dem Update läuft das Plugin gegen die bestehende + v17-Datenbank weiter. diff --git a/HellionChat/HellionChat.yaml b/HellionChat/HellionChat.yaml index a81bbd2..01b78f8 100755 --- a/HellionChat/HellionChat.yaml +++ b/HellionChat/HellionChat.yaml @@ -35,6 +35,33 @@ tags: - Replacement - Privacy changelog: |- + **v1.4.9 — Plugin-Load Render Polish (2026-05-15)** + + Tenth sub-patch of the v1.4.x polish-sweep series. First-frame + render cost drops from ~127 ms median to ~76 ms median, + comfortably under Dalamud's 100 ms HITCH warning threshold. + + - First-frame defer: six non-essential rendering sections inside + ChatLogWindow skip their first Draw and run one frame later + (bottom status bar, channel-name SeString chunks, window bounds + check, v0.6.1 hint banner, autocomplete, input-preview + calculation). User-visible delay is ~17 ms at 60 fps, hidden + inside the post-reload font-atlas build window. + - Slash-command centralisation: /hellion, /hellionView, + /hellionSeString and /hellionDebugger are registered in + LoadAsync instead of inside the corresponding window + constructors. The plugin-manager Open and configuration buttons + hang on the same path. + - Plugin-load profiling logs stay on at Information level + (MessageStore connect/migrate, FilterAllTabs, auto-translate + warmup) as a regression tripwire — a future load past 100 ms + will show up in /xllog without a Debug filter. + - Migration v17 stays (no schema bump). + + Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2). + + --- + **v1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)** Ninth sub-patch of the v1.4.x polish-sweep series. Hook-layer @@ -151,27 +178,4 @@ changelog: |- --- - **v1.4.5 — UX and Robustness (2026-05-12)** - - Sixth sub-patch of the v1.4.x polish-sweep series. Chat-log draw - failures surface as a notification, the first-run wizard has an - explicit "Later" option, the input history clears on plugin reload, - and the status bar version slot stops clipping in narrow windows. - - - Chat window draw errors now show a one-shot notification instead - of failing silently — stack trace stays in /xllog - - First-run wizard: explicit "Later — keep defaults" button. - Closing the X no longer silently accepts the defaults; the wizard - reopens on the next plugin load if nothing was picked - - InputHistoryService clears on plugin dispose so the previous - session's typed commands don't bleed into the next load - - Status bar hides the version slot when the chat window is too - narrow to fit all five slots without overlap - - Internal: explicit session-only Auto-Tell-Tab invariant in - Plugin.cs plus a pinning test in the Build-Suite - - Internal: FontManager falls back to the system font if the - embedded Hellion font resource is missing — logs a Warning - - --- - Full history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases diff --git a/repo.json b/repo.json index c25b6fe..0ddc1ae 100644 --- a/repo.json +++ b/repo.json @@ -14,7 +14,7 @@ "CanUnloadAsync": false, "LoadPriority": 0, "Punchline": "A Hellion Forge plugin. Privacy-first chat for FFXIV, built to stay out of your way.", - "Changelog": "**v1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)**\n\nNinth sub-patch of the v1.4.x polish-sweep series. Hook-layer cluster (DbViewer FTS5 full-text search, ad-block foundation investigation) plus three polish quick-wins.\n\n- DbViewer full-text search: optional FTS5 index across the full chat history. Built asynchronously on first load after the update with a progress toast. The local page-filter remains available as the default mode. Queries match as exact phrases -- multi-word terms must appear together in order; advanced users can opt into raw FTS5 MATCH syntax by wrapping their own double-quotes.\n- Custom theme files now auto-reload when edited while the theme is active -- no need to re-click the theme in the picker.\n- Retention sweep no longer blocks the framework thread, removing the ~194ms mini-hitch per sweep.\n- Status bar renders correctly at Windows display scaling > 100%.\n- Receive-suppressed-tells routing investigated this cycle and postponed to v1.5.x: when other plugins suppress tells via CheckMessageHandled, the FFXIV chat pipeline skips the RaptureLogModule.AddMsgSourceEntry path so HellionChat's ContentIdResolverHook does not fire and tell-partner identification breaks. The fix belongs next to the planned ad-block hook layer where the same patch surface comes up.\n- Internal: messages.Id is declared BLOB but stored as TEXT (Microsoft.Data.Sqlite Guid binding). FTS bulk insert and LoadByGuids match the TEXT storage form on both sides. Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.7 — Backlog Cleanup and Mid-Features (2026-05-13)**\n\nEighth sub-patch of the v1.4.x polish-sweep series. First user-visible feature bundle since v1.4.5 — pinned tell tabs that survive relog, opt-in Honorific glow rendering, and a configurable sidebar.\n\n- TempTell Pin: right-click a TempTell tab in the sidebar to pin it. Pinned tabs survive relog, keep their conversation history (loaded on demand from the message store), and stay bound to the same /tell partner. Hard cap of 5 pinned tabs in a pool separate from the 15-tab auto-tell pool — total ceiling is 20 tabs. New 'Angepinnt' / 'Pinned' section in the sidebar with its own divider header\n- Honorific Glow outline now renders when the title carries a Glow colour. Opt-in via Settings → Integrations → 'Render glow outlines (Honorific)' (default off, dodges the per-frame DrawList overhead on low-end hardware). Gradient (Color3 / GradientColourSet / Wave / Pulse) is parsed but rendered statically — a later cycle will port the full animation\n- Sidebar width is now configurable in Theme & Layout (range 44–160 px). Default stays icon-only; widen to fit section headers like 'Aktive Tells (3)' without truncation\n- Settings Save no longer pops the chat input back to /tell with a pinned partner — Configuration.UpdateFrom now preserves the runtime CurrentChannel across the persistent-tab merge, and TabSwitched deep-clones the seeded channel instead of sharing the previous tab's UsedChannel\n- Util/ImGuiUtil.cs DrawArrows IconButton id now uses (id + 1).ToString() instead of the operator-precedence quirk id + 1.ToString() — generated IDs stay numerically stable\n- Internal: IPluginLogProxy indirection over Dalamud's IPluginLog routes all ~91 Plugin.Log call sites through a testable proxy. MessageStore.Migrate0 can now run in xUnit without loading Dalamud.dll, closing the gap F12.1 left in v1.4.6\n- Internal: TempTab counter switched from an Interlocked cached field to a derived Tabs.Count(predicate) — pin-state transitions are cold-path and don't need lock-free reads\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.6 — Code Hygiene and Refactor (2026-05-12)**\n\nMaintenance patch. No user-visible behaviour changes; tightens the development feedback loop, fixes two upstream-inherited bugs, and prepares the code for the v1.4.7 backlog cleanup.\n\n- preflight.sh gains a csharpier reflow check and a markdownlint pass so style drift and markdown violations are caught at the pre-push gate\n- FontManager fallback catches the full set of atlas-toolkit throws (IO, InvalidOperation, ArgumentException) — a corrupt font config no longer takes down the whole atlas build\n- BrandingLinks and IntegrationLinks URLs validated on plugin load — a typo in a future URL rotation now throws at startup\n- Cherry-picked from ChatTwo upstream f35b7d3: Chat.SetChannel no longer leaks the native Utf8String when the linkshell check rejects the channel\n- Cherry-picked from ChatTwo upstream f35b7d3: Tab.Clone now deep-clones UsedChannel and TellTarget — PopOut and Temp tabs no longer mutate each other's channel state\n- Active-tab underline scales with DPI and rounds to physical pixels for crisp rendering above 100% scaling\n- IconButton width parameter no longer subtracts HUD-scaled padding from a raw int (measured width passes through verbatim)\n- Internal: HellionStyle ChildBgAlpha extracted to a testable helper; Plugin.SaveConfig clones only the temp tabs; SettingsOverview caches the draw-list per frame; Dalamud.Utility.Util surface routed through an IPlatformUtil indirection (MessageStore IsWine probe is now testable in isolation)\n- Built-in themes: Crystal Nocturne (sapphire and electric magenta over obsidian, by CRYSTALLITE) replaces Moonlit Bloom. Users with Moonlit Bloom selected fall back to Hellion Arctic on first load\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.5 — UX and Robustness (2026-05-12)**\n\nSixth sub-patch of the v1.4.x polish-sweep series. Chat-log draw failures surface as a notification, the first-run wizard has an explicit Later option, the input history clears on plugin reload, and the status bar version slot stops clipping in narrow windows.\n\n- Chat window draw errors now show a one-shot notification instead of failing silently — stack trace stays in /xllog\n- First-run wizard: explicit \"Later — keep defaults\" button. Closing the X no longer silently accepts the defaults; the wizard reopens on the next plugin load if nothing was picked\n- InputHistoryService clears on plugin dispose so the previous session's typed commands don't bleed into the next load\n- Status bar hides the version slot when the chat window is too narrow to fit all five slots without overlap\n- Internal: explicit session-only Auto-Tell-Tab invariant in Plugin.cs plus a pinning test in the Build-Suite\n- Internal: FontManager falls back to the system font if the embedded Hellion font resource is missing — logs a Warning\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases", + "Changelog": "**v1.4.9 — Plugin-Load Render Polish (2026-05-15)**\n\nTenth sub-patch of the v1.4.x polish-sweep series. First-frame render cost drops from ~127 ms median to ~76 ms median, comfortably under Dalamud's 100 ms HITCH warning threshold.\n\n- First-frame defer: six non-essential rendering sections inside ChatLogWindow skip their first Draw and run one frame later (bottom status bar, channel-name SeString chunks, window bounds check, v0.6.1 hint banner, autocomplete, input-preview calculation). User-visible delay is ~17 ms at 60 fps, hidden inside the post-reload font-atlas build window.\n- Slash-command centralisation: /hellion, /hellionView, /hellionSeString and /hellionDebugger are registered in LoadAsync instead of inside the corresponding window constructors. The plugin-manager Open and configuration buttons hang on the same path.\n- Plugin-load profiling logs stay on at Information level (MessageStore connect/migrate, FilterAllTabs, auto-translate warmup) as a regression tripwire — a future load past 100 ms will show up in /xllog without a Debug filter.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)**\n\nNinth sub-patch of the v1.4.x polish-sweep series. Hook-layer cluster (DbViewer FTS5 full-text search, ad-block foundation investigation) plus three polish quick-wins.\n\n- DbViewer full-text search: optional FTS5 index across the full chat history. Built asynchronously on first load after the update with a progress toast. The local page-filter remains available as the default mode. Queries match as exact phrases -- multi-word terms must appear together in order; advanced users can opt into raw FTS5 MATCH syntax by wrapping their own double-quotes.\n- Custom theme files now auto-reload when edited while the theme is active -- no need to re-click the theme in the picker.\n- Retention sweep no longer blocks the framework thread, removing the ~194ms mini-hitch per sweep.\n- Status bar renders correctly at Windows display scaling > 100%.\n- Receive-suppressed-tells routing investigated this cycle and postponed to v1.5.x: when other plugins suppress tells via CheckMessageHandled, the FFXIV chat pipeline skips the RaptureLogModule.AddMsgSourceEntry path so HellionChat's ContentIdResolverHook does not fire and tell-partner identification breaks. The fix belongs next to the planned ad-block hook layer where the same patch surface comes up.\n- Internal: messages.Id is declared BLOB but stored as TEXT (Microsoft.Data.Sqlite Guid binding). FTS bulk insert and LoadByGuids match the TEXT storage form on both sides. Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.7 — Backlog Cleanup and Mid-Features (2026-05-13)**\n\nEighth sub-patch of the v1.4.x polish-sweep series. First user-visible feature bundle since v1.4.5 — pinned tell tabs that survive relog, opt-in Honorific glow rendering, and a configurable sidebar.\n\n- TempTell Pin: right-click a TempTell tab in the sidebar to pin it. Pinned tabs survive relog, keep their conversation history (loaded on demand from the message store), and stay bound to the same /tell partner. Hard cap of 5 pinned tabs in a pool separate from the 15-tab auto-tell pool — total ceiling is 20 tabs. New 'Angepinnt' / 'Pinned' section in the sidebar with its own divider header\n- Honorific Glow outline now renders when the title carries a Glow colour. Opt-in via Settings → Integrations → 'Render glow outlines (Honorific)' (default off, dodges the per-frame DrawList overhead on low-end hardware). Gradient (Color3 / GradientColourSet / Wave / Pulse) is parsed but rendered statically — a later cycle will port the full animation\n- Sidebar width is now configurable in Theme & Layout (range 44–160 px). Default stays icon-only; widen to fit section headers like 'Aktive Tells (3)' without truncation\n- Settings Save no longer pops the chat input back to /tell with a pinned partner — Configuration.UpdateFrom now preserves the runtime CurrentChannel across the persistent-tab merge, and TabSwitched deep-clones the seeded channel instead of sharing the previous tab's UsedChannel\n- Util/ImGuiUtil.cs DrawArrows IconButton id now uses (id + 1).ToString() instead of the operator-precedence quirk id + 1.ToString() — generated IDs stay numerically stable\n- Internal: IPluginLogProxy indirection over Dalamud's IPluginLog routes all ~91 Plugin.Log call sites through a testable proxy. MessageStore.Migrate0 can now run in xUnit without loading Dalamud.dll, closing the gap F12.1 left in v1.4.6\n- Internal: TempTab counter switched from an Interlocked cached field to a derived Tabs.Count(predicate) — pin-state transitions are cold-path and don't need lock-free reads\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.6 — Code Hygiene and Refactor (2026-05-12)**\n\nMaintenance patch. No user-visible behaviour changes; tightens the development feedback loop, fixes two upstream-inherited bugs, and prepares the code for the v1.4.7 backlog cleanup.\n\n- preflight.sh gains a csharpier reflow check and a markdownlint pass so style drift and markdown violations are caught at the pre-push gate\n- FontManager fallback catches the full set of atlas-toolkit throws (IO, InvalidOperation, ArgumentException) — a corrupt font config no longer takes down the whole atlas build\n- BrandingLinks and IntegrationLinks URLs validated on plugin load — a typo in a future URL rotation now throws at startup\n- Cherry-picked from ChatTwo upstream f35b7d3: Chat.SetChannel no longer leaks the native Utf8String when the linkshell check rejects the channel\n- Cherry-picked from ChatTwo upstream f35b7d3: Tab.Clone now deep-clones UsedChannel and TellTarget — PopOut and Temp tabs no longer mutate each other's channel state\n- Active-tab underline scales with DPI and rounds to physical pixels for crisp rendering above 100% scaling\n- IconButton width parameter no longer subtracts HUD-scaled padding from a raw int (measured width passes through verbatim)\n- Internal: HellionStyle ChildBgAlpha extracted to a testable helper; Plugin.SaveConfig clones only the temp tabs; SettingsOverview caches the draw-list per frame; Dalamud.Utility.Util surface routed through an IPlatformUtil indirection (MessageStore IsWine probe is now testable in isolation)\n- Built-in themes: Crystal Nocturne (sapphire and electric magenta over obsidian, by CRYSTALLITE) replaces Moonlit Bloom. Users with Moonlit Bloom selected fall back to Hellion Arctic on first load\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases", "AcceptsFeedback": true, "DownloadLinkInstall": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.9/latest.zip", "DownloadLinkUpdate": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.4.9/latest.zip",