35e8d3a7fe
Plugin.cs:937 only pushed RegularFont when Config.FontsEnabled was true.
FontsAndColours.cs:50 forces FontsEnabled=false whenever UseHellionFont is
enabled (to hide the chooser UI), so the bundled-font path was silently
dead and the FFXIV Axis game-font took over. Exo 2 looked "almost right"
because it overlaps Axis on basic Latin, so the regression went unnoticed
for the entire v1.5.x series.
The fix routes RegularFont through draw whenever either FontsEnabled or
UseHellionFont is on. First-frame HITCH dropped from ~74 ms to ~20 ms
median (5-reload Linux/Wine sample 17.9-23.6 ms) as a side effect — the
v1.5.1 "too optimistic" defer-pattern hypothesis was actually a symptom
of this bug, not bad math.
Font-stack overhaul on top:
- Inter Light (Static 18pt-Light, 343 KB, SIL OFL 1.1) replaces Exo 2 as
the bundled font. Inter ships full Latin Extended-A/B, Greek polytonic
and Cyrillic Supplement coverage.
- NotoSansCjkRegular added as a third merge layer for Hangul,
Simplified-Chinese-specific Han glyphs, and CJK fallbacks the FFXIV
Japanese font does not ship.
- Two new ExtraGlyphRanges flags (LatinExtended, Greek) implemented via
AddChar pair lists in SetUpRanges.
- Settings.Apply auto-activates the matching ExtraGlyphRanges flag on
language change. Plugin.LoadAsync runs a one-shot migration that ORs
in the required flag for an already-selected language.
- ExtraGlyphRanges CollapsingHeader reachable regardless of
UseHellionFont (was hidden in the early-return branch).
- New WarningText below the language combo: FFXIV's chat engine only
fully supports EN/DE/FR/JA. Other scripts render in the HellionChat
UI but may garble in in-game chat input/send.
Localisation wave (originally a FR-only cycle):
- 24 selectable UI languages. LanguageOverride enum gains 10 new locales
plus 3 previously commented-out (Italian, Korean, Norwegian with ISO
code `nb` instead of `no`). All new values append to keep existing
user-config integer serialisation stable.
- Resource bundle split: HellionStrings.resx (24 locales, 328 keys) for
fork-added strings, Language.resx (24 locales, 456 keys) for the
ChatTwo-Crowdin-heritage. 4 post-sync Crowdin keys backfilled into
13 legacy locales with per-key AI-assisted comment marker.
- Em-dash sweep on EN source plus 18 translations. Russian and Ukrainian
keep their typographic norm.
Old HellionFont.ttf + HellionFont-OFL.txt removed; Inter-Light.ttf +
Inter-OFL.txt take their place. Configuration field UseHellionFont keeps
its name for backwards-compat. Migration v17 stays.
864 lines
50 KiB
Markdown
864 lines
50 KiB
Markdown
# Changelog — Hellion Chat
|
||
|
||
All user-facing changes to Hellion Chat. Format follows
|
||
[Keep a Changelog](https://keepachangelog.com/en/1.0.0/), version numbers follow
|
||
[Semantic Versioning](https://semver.org/).
|
||
|
||
Detailed release notes per version are available directly on the
|
||
[Gitea Release page](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases) and
|
||
in the plugin changelog block (`HellionChat/HellionChat.yaml` → `changelog:`). This file summarises
|
||
releases as an overview and links to the release pages for details.
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.5.3 — Localisation Wave + Bundled-Font Overhaul (2026-05-19)
|
||
|
||
Multi-language pass plus a long-standing first-frame HITCH lands as a side effect of a font-stack
|
||
rewrite. The bundled UI font swaps from Exo 2 to Inter Light. HellionChat now ships strings and
|
||
renderable glyph coverage for 24 languages.
|
||
|
||
### User-visible
|
||
|
||
- Twenty-four selectable UI languages: Catalan, Czech, Danish, Dutch, English, Finnish, French,
|
||
German, Greek, Hungarian, Italian, Japanese, Korean, Norsk bokmål, Polish, Portuguese (Brazil),
|
||
Portuguese (Portugal), Romanian, Russian, Spanish, Swedish, Turkish, Ukrainian, Simplified
|
||
Chinese, Traditional Chinese. The dropdown sorts alphabetically by endonym, "None" pinned first.
|
||
Non-native translations are AI-assisted and flagged for community native-speaker review via the
|
||
Hellion Forge Discord.
|
||
- Bundled **Inter Light** replaces Exo 2 as the in-plugin font. Wider European coverage (Latin
|
||
Extended-A/B, Greek polytonic, Cyrillic Supplement) so Czech, Polish, Romanian, Turkish,
|
||
Hungarian, Greek and Ukrainian render without manual font configuration. SIL OFL 1.1, 343 KB.
|
||
- **NotoSansCjkRegular fallback** layer added as a merge-on-top so Hangul, Simplified-Chinese
|
||
characters specific to the post-1956 reform, and other CJK glyphs the FFXIV Japanese game font
|
||
does not ship now render correctly inside the HellionChat UI.
|
||
- First-frame **HITCH dropped from ~74 ms** (the v1.5.2 baseline that has held since v1.4.x) to a
|
||
**median of ~20 ms** (5-reload sample: 23.6 / 20.4 / 17.9 / 20.1 / 19.2 ms, Linux/Wine; Windows
|
||
baseline pending Jin's verification per the cross-platform-pflicht). The bundled-font path
|
||
silently fell back to the FFXIV Axis game font for the entire v1.5.x series because of an
|
||
early-return in the draw loop. The fix that routes `RegularFont` through draw also lands the
|
||
defer-pattern win the v1.5.1 cycle was reaching for.
|
||
- **ExtraGlyphRanges activates automatically** when the user picks a language that needs a non-Latin
|
||
script. Selecting Korean enables the Korean glyph range and rebuilds the atlas without a manual
|
||
toggle in Fonts & Colours.
|
||
- New **WarningText under the language dropdown** notes that FFXIV's own chat input only fully
|
||
supports EN, DE, FR and JA character sets. Other languages render inside HellionChat but may
|
||
garble when typed into in-game chat or sent as messages.
|
||
|
||
### Under the hood
|
||
|
||
- Three-layer font stack in `FontManager.BuildRegularFontHandle` and `BuildItalicFontHandle`:
|
||
Inter Light (or the user-selected global font) as primary, FFXIV JapaneseFont as merge 1 for
|
||
native FFXIV kana/kanji style, NotoSansCjkRegular as merge 2 for everything else CJK.
|
||
- Two new `ExtraGlyphRanges` flags: `LatinExtended` (U+0100-U+024F) and `Greek` (U+0370-U+03FF +
|
||
U+1F00-U+1FFF). Implemented as `builder.AddChar` pair lists in `SetUpRanges` (no managed-pointer
|
||
pinning needed).
|
||
- `LanguageOverride` enum gains ten locales (Catalan, Czech, Danish, Finnish, Hungarian,
|
||
Norwegian, Polish, Portuguese (Portugal), Turkish, Ukrainian) plus three previously
|
||
commented-out entries (Italian, Korean, Norwegian re-enabled with code `nb` instead of `no`).
|
||
New values are appended to the enum to keep existing user-config integer serialisation stable.
|
||
- **Crowdin gap closed:** four ChatTwo keys added after the last community sync
|
||
(`Options_ColorSelectedInputChannelButton_Name` / `_Description`,
|
||
`Options_HideInNewGamePlusMenu_Name` / `_Description`) are now backfilled into the thirteen
|
||
legacy Crowdin locales with per-key AI-translated markers.
|
||
- Plugin init runs a one-shot migration that ORs in the matching `ExtraGlyphRanges` flag based on
|
||
the user's current `LanguageOverride`. An update from v1.5.2 picks up the new coverage without
|
||
the user having to toggle the language twice.
|
||
- `Plugin.cs:937` draw-path fixed: `RegularFont` is now pushed whenever **either** `FontsEnabled`
|
||
**or** `UseHellionFont` is on. The previous `Config.FontsEnabled`-only check meant the bundled
|
||
font path was silently dead whenever `FontsAndColours.cs:50` force-set `FontsEnabled = false` on
|
||
the UseHellionFont-toggle. Source of the HITCH win.
|
||
- `ExtraGlyphRanges` settings panel is now reachable in **all** UseHellionFont / FontsEnabled
|
||
combinations. The bundled-font branch used to short-circuit past it.
|
||
- **Resource bundle split:** fork-added strings live in `HellionStrings.resx` (24 locales, 328
|
||
keys each) alongside the ChatTwo-Crowdin-heritage `Language.resx` (24 locales, 456 keys each).
|
||
The `Language` siblings for the ten brand-new locales and Greek carry a Hellion Forge maintainer
|
||
header that points reviewers at the Discord rather than the standalone-hosted Gitea.
|
||
- **Em-dash sweep** across the EN source and 18 translations: in-prose em-dashes replaced with
|
||
period or colon per the house style guide. Russian and Ukrainian keep their typographic norm
|
||
where the em-dash is orthographically required (subject-predicate separator).
|
||
- **Bundled font asset rotation:** `HellionFont.ttf` (Exo 2) plus its OFL notice removed from
|
||
`Resources/`. `Inter-Light.ttf` plus `Inter-OFL.txt` take their place. `FontManager`
|
||
references rename to `BundledFontBytes` / `TryGetBundledFontBytes()` for clarity (config field
|
||
`UseHellionFont` keeps its name so existing user configs deserialize cleanly).
|
||
|
||
### Migration
|
||
|
||
- Migration v17 stays (no schema bump).
|
||
- Existing `UseHellionFont = true` users transition transparently from Exo 2 to Inter Light on
|
||
first reload.
|
||
- Existing users with `LanguageOverride != None` get their matching `ExtraGlyphRanges` flag set
|
||
on the first plugin init after the v1.5.3 update (Plugin.cs LoadAsync migration step).
|
||
|
||
### Reserved for follow-up cycles
|
||
|
||
- Native-speaker review pass for AI-assisted translations in the 13 legacy Crowdin locales (ca,
|
||
es, fr, it, ja, ko, nl, pt-BR, ro, ru, sv, zh-Hans, zh-Hant) — corrections via the Hellion
|
||
Forge Discord.
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.5.2 — First-Run Wizard Rework (2026-05-18)
|
||
|
||
UX patch. The single-page first-run wizard becomes a four-step staged-commit flow, the privacy
|
||
profile catalogue gains a fourth entry "Roleplay", and a new power-settings stage surfaces six
|
||
previously-hidden Configuration defaults. Existing v1.5.1 users see the new wizard once on first
|
||
v1.5.2 boot via a new `WizardLastShownVersion` config marker.
|
||
|
||
User-visible:
|
||
|
||
- Wizard layout: Welcome → Privacy profile → Power settings → Done. Forge-Bronze pagination dots,
|
||
per-step Back / Decide later / Next footer. Decide-later and X-close both leave the existing
|
||
config untouched; only the Finish ✓ click commits pending choices.
|
||
- Fourth privacy profile "Roleplay": Privacy-First whitelist plus `Say` and both emote types, with a
|
||
30-day retention window for `Say` and 90 days for the two emote channels. `Shout`, `Yell` and
|
||
`NoviceNetwork` stay out — public-distance noise from strangers is not story content.
|
||
- Privacy picker becomes a 2×2 grid. Casual stays the recommended option with a ★ marker.
|
||
- Power-settings stage surfaces six existing `Configuration` fields in one place: Load Previous
|
||
Session, Filter Include Previous Sessions, Auto-Tell-Tabs History Preload, Compact Density,
|
||
Prettier Timestamps, plus a built-in theme picker. No new settings are introduced — the stage just
|
||
collects what was previously buried in Settings → Privacy / Chat / Data Management / Appearance.
|
||
- Inline test hint on the done stage: `type /tell <Player Name> into chat` surfaces the auto-tell-tab
|
||
spawn mechanism for new users.
|
||
- Wizard window starts at 720×480 (was 900×560) and can shrink to 600×400. Step 1 wraps the fox
|
||
banner in a collapsible TreeNode, folded by default — onboarding copy stays primary.
|
||
- Existing v1.5.1 users get the new wizard surfaced once on first v1.5.2 boot. A new
|
||
`WizardLastShownVersion` config field tracks the most recent version whose wizard was shown;
|
||
Plugin.LoadAsync resets `FirstRunCompleted` once when the constant `1.5.2` doesn't match.
|
||
|
||
Under the hood:
|
||
|
||
- `WizardStateSmokeStep` registered with `/xlperf`. Variant 1 walks the four steps with empty
|
||
pending state to pin the no-op CommitPending path. Variant 2 picks Roleplay on Step 2, skips
|
||
Step 3, commits, and asserts `LoadPreviousSession` / `FilterIncludePreviousSessions` stayed on
|
||
their pre-test value — pinning the null-semantics contract. The step snapshots six privacy /
|
||
retention fields before Variant 2 and `CleanUp()` restores them, so back-to-back runs don't drift
|
||
the active profile.
|
||
- Twelve pure-helper xUnit Facts in the Build Suite (`Privacy/PrivacyDefaultsTests.cs`) cover all
|
||
four profile whitelists plus the new Roleplay retention overrides.
|
||
- `Configuration` grows one optional string field `WizardLastShownVersion` (default empty). No
|
||
schema bump — migration v17 still applies.
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
[Full release notes on the Gitea release page.](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.5.2)
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.5.1 — FontAtlas Refactor and Hellion Forge Signature (2026-05-17)
|
||
|
||
Hybrid FontManager refactor plus an embedded Hellion Forge provenance mark.
|
||
|
||
- FontManager handle creation moves into the ctor inside a single `atlas.SuppressAutoRebuild()`
|
||
block — the font atlas now builds once per plugin load instead of four to five times.
|
||
- Hybrid property model: `Axis`, `AxisItalic` and `FontAwesome` become init-only handles;
|
||
`RegularFont` and `ItalicFont` stay mutable because the eight font settings still need to replace
|
||
them at runtime via the renamed `RebuildDelegateFonts()` path, without a plugin reload.
|
||
- `FontAwesome` reuses Dalamud's `UiBuilder.IconFontFixedWidthHandle` instead of building its own
|
||
atlas slot.
|
||
- `BuildFontsAsync` and `BuildFonts` are removed; the live mutation path is `RebuildDelegateFonts()`
|
||
now.
|
||
- Two new self-test steps register with `/xlperf`: FontManager ctor smoke (every handle non-null, no
|
||
atlas load-exception) and push smoke (`Push()` returns without throwing).
|
||
- Hellion Forge signature embedded in the plugin DLL: a fox-head ASCII silhouette is prepended to
|
||
the `/xllog` bootstrap banner on every plugin load, and a full fox banner with "Hellion Forge" set
|
||
inside the body is available as a folded `TreeNode` in the First-Run Wizard and Settings →
|
||
Information tab. Drawn by Julia Moon.
|
||
- Honorific full-gradient port (originally scheduled for this cycle) was dropped: Honorific 3.2
|
||
exposes no IPC for the rendered gradient frame, and an in-plugin port of the colour palette was
|
||
declined. The integration stays at the v1.4.7 glow-only shape.
|
||
|
||
The 10× HITCH cut targeted from the v1.5.0 cross-plugin baseline did not land — HITCH stays around
|
||
80 ms because the cost lives in the UiBuilder first-frame render path, not in the atlas build (which
|
||
this cycle did reduce from 4-5 builds per load to 1). A first-frame render investigation is reserved
|
||
for a later cycle. No settings changes, no migration. v17 stays.
|
||
|
||
[Full release notes on the Gitea release page.](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.5.1)
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.5.0 — DI Foundation and Service Refactor (2026-05-17)
|
||
|
||
Major architecture cycle. The plugin bootstrap moves to a generic-host DI container
|
||
(`Microsoft.Extensions.Hosting` + `IServiceCollection`) modelled on Lightless Sync. Service logging
|
||
migrates from a static `Plugin.LogProxy` locator to typed `Microsoft.Extensions.Logging.ILogger<T>`
|
||
via constructor injection, bridged over Dalamud's `IPluginLog` by a custom `DalamudLogger` trio.
|
||
|
||
### Under the hood
|
||
|
||
- 18 instance-class services migrate to `ILogger<T>` via constructor injection across four slices:
|
||
data layer (`MessageStore`, `MessageManager`, `AutoTellTabsService`), IPC and integrations
|
||
(`HonorificService`, `IpcManager`, `TypingIpc`, `ExtraChat`, three `GameFunctions` classes), UI
|
||
window layer (`ChatLogWindow`, `DbViewer`, `Popout`, three settings tabs), and root (`Commands`,
|
||
`ThemeRegistry`, `PayloadHandler`).
|
||
- `Plugin.LogProxy` stays in place for the eight buckets ctor injection cannot reach: static helpers
|
||
(`EmoteCache`, `AutoTranslate`, `MemoryUtil`, `WrapperUtil`), Dalamud-reflected types
|
||
(`Configuration`), the `Message` data class, and instance classes that only log from static
|
||
methods (`FontManager`, one `GameFunctions` site).
|
||
- Plugin.cs finishes at 1012 lines — virtually identical to the pre-cycle 1013. The new Phase-1 host
|
||
build and `Plugin.X` bridge wiring trade out exactly the service and window allocations that
|
||
previously lived in `LoadAsync`.
|
||
- Cross-plugin baseline confirms no performance penalty against Chat 2: HellionChat first-frame
|
||
HITCH 77 ms median, Chat 2 74 ms median. Lightless and XIVInstantMessenger sit around 7 ms by
|
||
deferring their font-atlas build past `Finished loading` — that pattern is the v1.5.1 follow-up
|
||
item.
|
||
|
||
### User-visible
|
||
|
||
- Slash-command insert fix: pasting a slash command into the chat input (Friend List "/tell" action,
|
||
plugin-driven inserts from Artisan, AllaganTools etc.) now replaces the existing input instead of
|
||
concatenating onto whatever the user was typing. Cherry-picked from ChatTwo upstream `ee7768ac`
|
||
with namespace adaptation.
|
||
|
||
Migration v17 stays (no schema bump).
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.10 — Symbol-Picker and Tell-History Fix (2026-05-16)
|
||
|
||
Eleventh and final sub-patch of the v1.4.x Polish-Sweep series. Symbol picker for the chat input, a
|
||
tell-history reload fix for users with many active partners, and a closing cleanup sweep before
|
||
v1.5.0 picks up the DI-container adoption.
|
||
|
||
- Symbol picker for the chat input: smile-icon button left of the channel indicator opens a popup
|
||
with two tabs — 161 FFXIV PUA glyphs (Dalamud's SeIconChar enum) and 97 server-verified BMP
|
||
symbols round-tripped through `/echo` and `/say` in a four-round probe. Cursor-aware splice,
|
||
multi-insert keeps the popup open, recent-used strip floats the last sixteen picks across both
|
||
tabs. Toggle in Settings → Chat → Message behaviour, default on.
|
||
- Pinned auto-tell tabs reload their full history again. PreloadHistory had a hidden 500-row scan
|
||
cap that overrode the user-configurable `AutoTellTabsHistoryPreload` setting whenever you chatted
|
||
with many partners; less-frequent pinned partners lost their backlog. The cap is removed.
|
||
- Slash-command teardown cleanup: `/hellion`, `/hellionView`, `/hellionDebugger` (and
|
||
`#if DEBUG /hellionSeString`) wrappers are now cached as private fields so plugin teardown
|
||
detaches the live registration instead of re-Register'ing with identical args (latent maintenance
|
||
hazard from v1.4.9).
|
||
- v1.4.x Polish-Sweep wraps up here. The ImGuiListClipper render refactor that was on the v1.4.10
|
||
reserve list got dropped after cross-platform smoke showed the scroll rubber-band is a Wine/Linux
|
||
render-pipeline quirk, not universal — Windows users never saw it. It will get its own
|
||
platform-targeted spike in a later patch. Next major cycle is v1.5.0 with the DI-container
|
||
adoption (Microsoft.Extensions.Hosting + ILogger<T>) modelled on Lightless.
|
||
- Migration v17 stays (no schema bump).
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.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
|
||
down to ~76 ms median — comfortably under Dalamud's 100 ms HITCH warning threshold. The remaining
|
||
~13 ms gap to ChatTwo upstream (~63 ms median) is the cost of HellionChat-only features (sidebar tab
|
||
view, custom status bar, Honorific integration).
|
||
|
||
- First-frame defer: six non-essential rendering sections inside `ChatLogWindow` skip their first
|
||
Draw and run one frame later. Covered sections are the bottom status bar, channel-name SeString
|
||
chunks, window bounds check, v0.6.1 hint banner, autocomplete and input-preview calculation. At 60
|
||
fps the user sees those sections ~17 ms after plugin reload — invisible inside the ~2.5 s
|
||
font-atlas build window every reload runs through anyway. Frame 1 stays well under 100 ms too (~40
|
||
ms), so no secondary HITCH warning appears.
|
||
- Slash-command centralisation: `/hellion`, `/hellionView`, `/hellionSeString` and
|
||
`/hellionDebugger` are now registered during `LoadAsync` instead of inside the corresponding
|
||
window constructors. The commands work before their target window is opened the first time, and
|
||
Dalamud's plugin-manager configuration / open buttons (`UiBuilder.OpenConfigUi` / `OpenMainUi`)
|
||
hang on the same path.
|
||
- Plugin-load profiling logs stay on: `MessageStore.Connect`, `MessageStore.Migrate`,
|
||
`FilterAllTabs` and the auto-translate warm-up timing log are now Information level rather than
|
||
Debug. They serve as a tripwire so a future regression past 100 ms shows up directly in `/xllog`
|
||
without re-enabling Debug.
|
||
- ChatTwo IPC compatibility layer: HellionChat now mirrors ChatTwo's full IPC surface
|
||
(`GetChatInputState`, `ChatInputStateChanged`, `Register`, `Unregister`, `Available`, `Invoke`)
|
||
under the `ChatTwo.*` namespace in addition to our existing `HellionChat.*` provider gates.
|
||
Third-party integrations that historically only subscribe to ChatTwo's IPC — for example Artisan's
|
||
and AllaganTools' context-menu hooks — keep working without requiring a code change on their side.
|
||
Conflict detection prevents ChatTwo from loading in parallel with HellionChat, so there is no
|
||
slot-collision risk at runtime.
|
||
- Migration v17 stays (no schema bump).
|
||
- Internal: hypothesis-triage during the R2 cycle falsified three of the four candidate root causes
|
||
(font-atlas sync, theme-apply ABGR-cache init, multiple-window render). Actual cause is `DrawList`
|
||
setup cost distributed across ~10 ImGui sections inside ChatLogWindow (5-20 ms each). The six
|
||
selective defers above are the pragmatic fix — a clean structural rewrite would belong in the
|
||
v1.5.x DI-container cycle.
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.8 — Hook-Layer and Polish Quick-Wins (2026-05-14)
|
||
|
||
Ninth sub-patch of the v1.4.x polish-sweep series. Hook-layer cluster (FTS5 full-text search,
|
||
ad-block foundation investigation) plus three polish quick-wins.
|
||
|
||
- DbViewer full-text search: optional FTS5 index across the full chat history. Built asynchronously
|
||
on first run after the update with a progress toast (UI stays responsive, the toggle is disabled
|
||
until the build completes). The local page-filter remains the default mode. Multi-word queries
|
||
match as exact phrases; power users can opt into raw FTS5 `MATCH` syntax by wrapping their own
|
||
double-quotes around the term.
|
||
- Custom theme files now auto-reload when edited while the theme is active. Save the JSON in your
|
||
editor and the live render picks up the change within a second — no need to re-click the theme in
|
||
the picker. Disk-stat is throttled to 1 Hz so per-frame cost stays free.
|
||
- Retention sweep no longer blocks the framework thread. `Framework.Run(...).Wait()` is replaced by
|
||
`Framework.RunOnTick(...)`, which removes the ~194 ms hitch the sweep used to add per run.
|
||
- Status bar height is derived from `GetTextLineHeightWithSpacing()` plus a DPI-aware spacer so the
|
||
bar renders correctly at Windows display scaling above 100 %. Linux/Wayland default of 100 % is
|
||
unaffected.
|
||
- Receive-suppressed-tells routing was investigated this cycle and **postponed to v1.5.x**. When
|
||
other plugins suppress tells via `CheckMessageHandled`, FFXIV's chat pipeline skips the
|
||
`RaptureLogModule.AddMsgSourceEntry` path, which means HellionChat's `ContentIdResolverHook` does
|
||
not fire and tell-partner identification breaks for AutoTellTab routing. The proper fix sits next
|
||
to the planned ad-block hook layer (`RaptureLogModule.ShowMiniTalkPlayer` and friends) where the
|
||
same patch surface comes up anyway.
|
||
- Internal: storage form of `messages.Id` clarified (declared BLOB but Microsoft.Data.Sqlite stores
|
||
Guid parameters as TEXT). FTS bulk insert and `LoadByGuids` join now match the TEXT storage form
|
||
on both sides. Migration v17 stays (no schema bump).
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.7 — Backlog Cleanup and Mid-Features (2026-05-13)
|
||
|
||
Eighth 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, a configurable sidebar, plus a
|
||
Settings-Save channel-preservation fix surfaced during smoke testing.
|
||
|
||
- TempTell Pin: right-click a TempTell tab in the sidebar and choose "Pin Tab" / "Tab anpinnen".
|
||
Pinned tabs survive plugin reload and character logout, keep their conversation history (loaded on
|
||
demand from the message store on rehydrate), 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. The
|
||
sidebar groups pinned tabs into their own section with a divider header
|
||
- Honorific glow outlines now render via an 8-direction DrawList pre-pass when the title carries a
|
||
Glow colour. Opt-in via **Settings → Integrations → Render glow outlines (Honorific)** (default
|
||
off). Honorific's gradient surface (`Color3`, `GradientColourSet`, `GradientAnimationStyle`) is
|
||
parsed and stashed for a later cycle but renders as the primary colour until then — the v1.4.7 DTO
|
||
already mirrors all four extra fields so the JSON roundtrip doesn't silent-drop them
|
||
- Sidebar width configurable in **Theme & Layout** (44–160 px, default 44 stays icon-only). The icon
|
||
button stretches with the configured width so a widened sidebar looks intentional, not a 36 px
|
||
icon floating in empty space
|
||
- `Configuration.UpdateFrom` now preserves the runtime `CurrentChannel` across the persistent-tab
|
||
merge alongside `Messages` and `LastSendUnread`. `TabSwitched` deep-clones the seeded channel from
|
||
the previous tab instead of sharing the same `UsedChannel` instance. Together these fix a
|
||
regression where Settings-Save on a Party or Linkshell tab popped the chat input back to
|
||
`/tell <pinned-partner>` on the next interaction
|
||
- `Util/ImGuiUtil.cs` `DrawArrows` IconButton id uses `(id + 1).ToString()` with explicit
|
||
parentheses instead of the operator-precedence quirk `id + 1.ToString()` (which resolved to
|
||
`id.ToString() + "1"`). Single live caller is `Ui/DbViewer.cs:227` page-navigation
|
||
- 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. Production wrapper `DalamudPluginLogProxy`
|
||
and Build-Suite `FakePluginLogProxy` mirror the full `IPluginLog` surface
|
||
(`Verbose`/`Debug`/`Information`/`Info`/`Warning`/`Error`/`Fatal`) with single-string,
|
||
`Exception+string`, and `params object[]` overloads
|
||
- Internal: TempTab counter switched from an `Interlocked` cached field to a derived
|
||
`Tabs.Count(predicate)`. Pin-state transitions (TryPin / Unpin / Promote) are cold-path and don't
|
||
need lock-free reads; counter mutation surface dropped from 5 to 0 sites. Build-Suite floor 688 →
|
||
710 (+22)
|
||
- Schema bump v16 → v17 is additive: new `Tab.IsPinned` bool, default false. Existing v16 configs
|
||
load cleanly and get their `Version` stamp bumped after the gate check
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.6 — Code Hygiene and Refactor (2026-05-12)
|
||
|
||
Maintenance patch. No user-visible behaviour changes; tightens the development feedback loop, fixes
|
||
two upstream-inherited bugs from ChatTwo `f35b7d3`, and prepares the code for the v1.4.7 backlog
|
||
cleanup.
|
||
|
||
- `scripts/preflight.sh` gains Block E (`dotnet csharpier check`) and Block F (`markdownlint-cli2`)
|
||
so reflow drift and markdown violations are caught at the pre-push gate. `.markdownlint.json` adds
|
||
`MD024 siblings_only` and disables `MD036` so the bilingual forge-post bold-emphasis headings pass
|
||
linting; the `.claude/` directory is excluded from the scan
|
||
- `FontManager.AddFontWithFallback` catch-filter now covers `InvalidOperationException` and
|
||
`ArgumentException` on top of the existing IO triad. The warning log carries the exception type
|
||
name, so the diagnostic path knows which class of atlas-toolkit throw triggered the
|
||
NotoSansCjkRegular fallback
|
||
- `BrandingLinks` (5 URLs) and `Integrations/IntegrationLinks` (2 URLs) validate themselves on first
|
||
module load via `[ModuleInitializer]` + a shared `UrlValidation.ValidateAll` helper. A malformed
|
||
URL now throws `InvalidOperationException` at plugin load with the source class and the broken URL
|
||
in the message
|
||
- Cherry-picked from ChatTwo upstream `f35b7d3`: `Chat.SetChannel` no longer leaks the native
|
||
`Utf8String` when the linkshell check rejects the channel. The validity check is now wrapped
|
||
around the `ChangeChatChannel` call instead of short-circuiting before `Dtor`. `ValidAnyLinkshell`
|
||
is renamed to `IsChannelOrExistingLinkshell` and the `ChatLogWindow` call-site follows the rename
|
||
- Cherry-picked from ChatTwo upstream `f35b7d3`: `Tab.Clone` now deep-clones `UsedChannel` and
|
||
`TellTarget`. The old `CurrentChannel = CurrentChannel` was a reference copy, so PopOut and Temp
|
||
tabs mutated each other's channel state (incl. tell target). `TellTarget.From(t)` static factory
|
||
is replaced with an instance `Clone()`; `UsedChannel.Clone()` is new and runs deep-clone on both
|
||
TellTarget references
|
||
- `ChatLogWindow` active-tab underline pill now scales with `ImGuiHelpers.GlobalScale` and rounds
|
||
its DrawList coordinates to physical pixels via `MathF.Round`, so the 2 px line stays crisp on 125
|
||
% and 150 % DPI setups instead of bleeding into a sub-pixel blur
|
||
- `ImGuiUtil.IconButton` width parameter no longer subtracts HUD-scaled `CellPadding.X * 2` from the
|
||
raw `int` width. `ImGui.Button` handles its own frame padding internally, so the measured
|
||
`buttonWidth` now passes through verbatim (inspired-by upstream `f35b7d3`, but our two call-sites
|
||
need the parameter, so the param itself stays)
|
||
- Internal: `HellionStyle` ChildBgAlpha threshold logic extracted to
|
||
`HellionStyleHelpers.ResolveChildBgAlpha` with a build-suite mirror test that pins the 0.999f
|
||
cutoff. `Plugin.SaveConfig` clones only the temp-tab subset in the pre-serialization snapshot
|
||
instead of the full tab list. `SettingsOverview` caches `ImGui.GetWindowDrawList()` once per frame
|
||
and passes the pointer down to `DrawCard`
|
||
- Internal: `Dalamud.Utility.Util` static surface (`IsWine`, `OpenLink`) routed through a new
|
||
`IPlatformUtil` indirection. `MessageStore`'s `IsWine` probe is now reachable from the xUnit
|
||
AppDomain via a `FakePlatformUtil` fixture (full isolated MessageStore construction still pending
|
||
— `Plugin.Log.Information` in `Migrate0` is a separate Dalamud-static surface, slated for v1.4.7)
|
||
- Built-in themes: Crystal Nocturne (royal sapphire and electric magenta over obsidian, by
|
||
CRYSTALLITE) replaces Moonlit Bloom in the built-in roster. Users who had Moonlit Bloom selected
|
||
fall back to the default Hellion Arctic on the first plugin load; an existing custom JSON copy of
|
||
Moonlit Bloom under `pluginConfigs/HellionChat/themes/` keeps working unchanged
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.5 — UX and Robustness (2026-05-12)
|
||
|
||
Sixth sub-patch of the v1.4.x polish-sweep series. User-visible robustness fixes plus two doc/test
|
||
polish items from the audit backlog. No schema bump, no migration.
|
||
|
||
- `ChatLogWindow.Draw` now surfaces a one-shot warning notification when the draw path throws. The
|
||
stack trace still goes to `/xllog` via `Plugin.Log.Error`; the notification is suppressed for the
|
||
rest of the plugin session so a recurring failure can't spam the notification stack
|
||
frame-by-frame. Pattern-match to the existing `Plugin.cs:505-516` migration-blocker notification
|
||
- `FirstRunWizard` splits accept from close. `OnClose` no longer silently sets `FirstRunCompleted`,
|
||
so closing the X leaves the wizard pending and it reopens on the next plugin load. A new footer
|
||
"Later — keep defaults" button is the explicit path to dismiss without picking a profile.
|
||
Bilingual strings (EN + DE) plus a tooltip
|
||
- `InputHistoryService.Reset` is wired into `Plugin.DisposeAsync` alongside the existing pure-memory
|
||
cleanups. Static state used to survive a plugin reload — the next load now starts with an empty
|
||
history
|
||
- `FontManager.GetHellionFontBytes` becomes `TryGetHellionFontBytes` with a nullable return. On miss
|
||
(broken csproj, hand-rolled dev build) the caller falls back to the system-font path that
|
||
`UseHellionFont=false` already uses, plus a `Plugin.Log.Warning`. The whole UiBuilder no longer
|
||
throws if the embedded font resource is absent
|
||
- `Plugin.cs:167-168` gets a 4-line reasoning comment around the session-only
|
||
`RemoveAll(IsTempTab)`: tells are usually privacy-filtered, resurrecting an empty crashed-session
|
||
tab would trigger DB reconstruction on the next load. `TempTabCounter.InitFromList` mirrors the
|
||
post-strip semantic in the Build-Suite with a pinning test
|
||
- `StatusBar.cs` drops the version slot when the chat window's content width minus the version text
|
||
is below 200 px. The right-aligned version used to clip into the four left-side slots in narrow
|
||
windows
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.4 — Threading and IPC Safety Polish (2026-05-12)
|
||
|
||
Fifth sub-patch of the v1.4.x polish-sweep series. Threading assumptions are documented per-method,
|
||
a hot-path lock falls away in `AutoTellTabsService`, IPC-cleanup failures become visible, and the
|
||
privacy filter now speaks up when an unknown ChatType shows up.
|
||
|
||
- `AutoTellTabsService.ActiveTempTabCount` switches from a lock-protected LINQ `Count` to an
|
||
`Interlocked` counter kept in sync with `Config.Tabs` from inside the existing mutation paths.
|
||
`Initialize()` seeds the counter from the persisted Tabs list, and `SaveConfig`'s snapshot-restore
|
||
path calls a new `ResyncTempTabCounter()` so the mid-step `RemoveAll` doesn't leave the counter
|
||
drifting. Pure-helper test mirror lives in the Build-Suite repo
|
||
- `HonorificService` per-method threading banners replace the block comment at the bottom of the
|
||
file. Each IPC callback (`TryInitialPull`, `OnTitleChanged`, `OnReady`, `OnDisposing`,
|
||
`TryUnsubscribe`) and the `CurrentTitle` field carry a one-line `// Thread:` annotation so the
|
||
framework-thread invariant is visible at the call site
|
||
- `TryUnsubscribe` log-level upgraded from `Debug` to `Warning`. A silent unsubscribe failure leaks
|
||
a live subscription across plugin reloads, which is exactly the kind of issue that should not be
|
||
at Debug
|
||
- `AutoTranslate.PreloadCache` thread now has `IsBackground = true` and a thread name. Without
|
||
`IsBackground` the warmup blocks plugin unload (typically 100-300 ms). Pattern-match to
|
||
`MessageManager` (F6.1) and `Plugin.RetentionSweep` (F9.3), both since v1.4.0
|
||
- `Configuration.IsAllowedForStorage` adds a one-line `Plugin.Log.Warning` for the first occurrence
|
||
of any ChatType that isn't in `PrivacyPersistChannels`. Dedup via a `NonSerialized`
|
||
`HashSet<ChatType>`, so the warning fires once per runtime — not once per frame, not once per
|
||
install. Failsafe routing through `PrivacyPersistUnknownChannels` is unchanged
|
||
- `PrivacyPersistUnknownChannels` field default flipped from `false` to `true` for new installs via
|
||
a constant in `PrivacyDefaults`. Existing configs keep their explicit choice — the deserializer
|
||
overrides the initializer. No schema bump, no migration, no first-run banner
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.3 — Plugin-Load Async-Init + Repo-Cutover (2026-05-08)
|
||
|
||
Plugin lifecycle migrated to Dalamud's `IAsyncDalamudPlugin` API. The constructor now does only the
|
||
bootstrap-essentials (config load, language init, conflict detection); migrations, service
|
||
allocations, window construction and hook subscription move to `LoadAsync`. Dalamud can keep its UI
|
||
responsive while the heavy work runs.
|
||
|
||
- `IAsyncDalamudPlugin` two-phase load with per-line `CaptureFailure` in `DisposeAsync` (mirrors
|
||
LightlessSync's pattern); idempotency guard protects against reload races
|
||
- Schema-gate replaces the v9 → v16 migration chain. Configs on schema v16+ load directly; older
|
||
configs trigger an "install v1.4.2 first" error so the historic migration path stays intact
|
||
- `AutoTranslate.PreloadCache` moved off the load path. First use may have a sub-second hitch
|
||
instead of every-load; the upstream chose differently, we accept first-use latency
|
||
- `FontManager.BuildFonts` is called sync at the start of `LoadAsync`; Dalamud rebuilds the font
|
||
atlas on its own pipeline so the custom Hellion-Exo2 font appears with a brief font-pop after load
|
||
(matches ChatTwo's behaviour)
|
||
- Custom-repo URL moved to `gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat`. GitHub repo
|
||
stays as a frozen v1.4.2 snapshot; new releases ship from Gitea. Existing testers need to update
|
||
the custom-repo URL once
|
||
- Plugin-load time in this release sits at ~3.7 s median (5 reloads), comparable to v1.4.2. Async
|
||
migration is foundational for v1.4.4 Lazy-Init optimisations rather than an immediate
|
||
user-perceived win
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.2 — ChatLog Frame-Hot-Path
|
||
|
||
Third sub-patch of the v1.4.x Polish Sweep series. Per-frame allocations from the chat-log render
|
||
path eliminated.
|
||
|
||
- `DrawMessages` card-mode hoists `theme`/`drawList`/`winLeft`/`winRight`/`borderColorAbgr` out of
|
||
the per-message loop. About 500 redundant calls per frame at 100 visible messages, multiplied by
|
||
every pop-out window
|
||
- Auto-tell tab tint and icon use a per-tab cache. Hash computation and string allocation only
|
||
happen when the tell target name or world drifts. `AutoTellTabTint` stays a pure hash helper;
|
||
cache lives in a thin `TabTintCache` wrapper
|
||
- Status bar gates its tab aggregation behind the same one-second cache it already used for the
|
||
format strings. LINQ `Sum` and `Count` replaced with a single `foreach` pass that runs on roughly
|
||
1 % of frames
|
||
|
||
Realistic frame-time recovery: 2-5 % in typical scenes, more on pop-out-heavy setups because the
|
||
card-border hoist scales per window.
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.1 — Theme Engine Performance
|
||
|
||
Second sub-patch of the v1.4.x Polish Sweep series. Heap pressure from the theme engine's per-frame
|
||
render path removed, plus a tenth built-in theme and hardening for the custom-theme hot-reload.
|
||
|
||
- Theme records carry a pre-computed ABGR-packed cache for every color slot; cache is filled when
|
||
the theme is registered and refreshed defensively on every `Switch()`
|
||
- `HellionStyle.PushGlobal` reads ABGR values from the cache instead of calling
|
||
`ColourUtil.RgbaToAbgr` per slot per frame; ~13 % render-time recovery measured in typical scenes
|
||
(plan estimate was 2–6 %, real ~10–15 %)
|
||
- `ThemeRegistry` custom-theme reload distinguishes a recoverable file lock (editor mid-save) from a
|
||
permanent IO failure; locked themes keep their last-known-good snapshot and retry on the next
|
||
lookup instead of dropping out of the picker
|
||
- New built-in: **Synthwave Sunset** — Hot Magenta + Cyan on midnight violet, 80s neon-grid vibes;
|
||
tenth theme in the picker
|
||
- Author credits refreshed: brand themes are credited as "Hellion Forge"; **Mint Grove** and **Forge
|
||
Merchantman** now credited to **Carla Beleandis** as a community thanks
|
||
|
||
No schema bump, no user-visible behaviour change other than smoother frames on GC-sensitive setups
|
||
and one additional colour option.
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.4.0 — Critical Lifecycle Fixes
|
||
|
||
First sub-patch of the v1.4.x Polish Sweep series. Seven known lifecycle and race bugs eliminated
|
||
before any performance refactor sits on top.
|
||
|
||
- MessageStore disposal no longer triggers GC.Collect globally; Pooling=false on the SQLite
|
||
connection means there's nothing left to clean up by hand
|
||
- PendingMessage and RetentionSweep worker threads are explicitly marked IsBackground=true so the
|
||
plugin domain can unload during XIVLauncher reload without waiting for them
|
||
- EmoteCache image and gif loaders moved from async-void to async Task with a shared task tracker,
|
||
draining on Dispose so an in-flight load can no longer write to a disposed EmoteImages entry
|
||
- DisposeAsync 10s timeout now warns loudly instead of silently leaving the worker behind
|
||
- Plugin.Dispose flushes any pending DeferredSaveFrames before tearing services down, so settings
|
||
changes made in the last few frames before disable are no longer lost
|
||
- The v13→v14 config migration now reads the pre-v13 backup and carries HellionThemeWindowOpacity
|
||
into the new WindowOpacity field instead of falling back to the default 0.85
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## Hellion Chat 1.3.0 — Plugin Integrations: Honorific
|
||
|
||
First step on the plugin-integration roadmap. HellionChat now listens to Honorific and shows your
|
||
custom title in the chat header. The slot auto-hides when Honorific is not installed, when no custom
|
||
title is active, or when you are using the original FFXIV title.
|
||
|
||
- New "Integrations" settings tab
|
||
- Honorific integration with auto-detection and live updates
|
||
- "Coming soon" preview of the next five planned integrations: context menu actions, smart
|
||
notifications, RP status block, ExtraChat channels, and quick DM compose
|
||
- Maintainer attribution buttons for Honorific repo and Caraxi
|
||
- New service-class pattern under HellionChat/Integrations/
|
||
|
||
Modding & support: join Hellion Forge — <https://discord.gg/X9V7Kcv5gR>
|
||
|
||
Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).
|
||
|
||
---
|
||
|
||
## v1.2.3 — Theme Expansion (2026-05-06)
|
||
|
||
### Added
|
||
|
||
- Four new built-in themes:
|
||
- **Night Blue** — Royal Blue on deep marine, cool tech-dashboard mood
|
||
- **Indigo Violet** — Royal Violet on deep indigo with a turquoise-mint counter (aurora glitter
|
||
feel)
|
||
- **Forge Merchantman** — Patina bronze on workshop slate with warm amber counter (Hellion Forge
|
||
identity)
|
||
- **Hellion Spectrum** — Deuteran/Protan-safe channel colours using Wong/Okabe-Ito palette tones;
|
||
channel identity (Tell pink, Yell yellow, Shout orange, Party blue, FC green) preserved while
|
||
keeping every channel separable under red-green colour vision deficiency
|
||
- Built-in theme catalogue grown from five to nine
|
||
|
||
### Notes
|
||
|
||
- No engine changes, no settings touched, no migration
|
||
- Default theme unchanged (Hellion Arctic). Existing custom themes keep working.
|
||
- Hellion Spectrum covers the ~99 % of CVD cases that are red-green; a Tritan-safe variant could
|
||
follow in a later cycle if there is demand.
|
||
|
||
---
|
||
|
||
## v1.2.1 — Settings Cleanup (2026-05-06)
|
||
|
||
### Changed
|
||
|
||
- Settings cards re-sorted thematically: 9 cards remain, each card has one clear job and a one-line
|
||
subtitle.
|
||
- **Theme & Layout** (new) collects the theme picker, window frame style (title bar, sidebar, hide
|
||
button, pop-out title bar) and the timestamp style options.
|
||
- **Fonts & Colours** (new) houses font choice, font size and per-channel chat colours.
|
||
- **Data Management** (new) collects retention windows, cleanup, export, the database viewer and the
|
||
shift-click advanced tools.
|
||
- **Privacy** is now focused on the privacy filter alone.
|
||
- **Chat** absorbs the Auto-Tell-Tabs history-preload slider that used to live under Privacy.
|
||
- **General** groups the keybind mode under Input.
|
||
|
||
### Removed
|
||
|
||
- Legacy "Style override" option and the unused style-name field — both obsolete since the v1.1.0
|
||
themes engine.
|
||
- Legacy `WindowAlpha` slider — if you had it set, the value is auto-migrated to Theme & Layout →
|
||
Window Style → Window Transparency.
|
||
- Unused `ShowThemeQuickPicker` schema field.
|
||
|
||
### Migration
|
||
|
||
- v15 → v16 with backup at `pluginConfigs/HellionChat.json.pre-v16-backup`.
|
||
- All other settings preserved unchanged.
|
||
- One-time toast on first start if Style override was previously active.
|
||
|
||
---
|
||
|
||
## v1.2.0 — Layout Refresh (2026-05-05)
|
||
|
||
### Added
|
||
|
||
- Sidebar tab modernization: icon-only at fixed 44 px, tooltip on hover, vertical accent pill for
|
||
active tab
|
||
- Top tabs: accent underline pill replaces background fill on active tab
|
||
- Per-tab custom icons in Settings → Tabs (15-glyph FontAwesome picker)
|
||
- Bottom status bar (22 px): channel indicator, privacy badge, counters, tells, version — updates
|
||
1×/sec
|
||
- Card rows as default message render: sender header in channel color, subtle border between cards
|
||
- Compact-Density toggle in Appearance: switches back to single-line `[HH:mm] Sender: Text` layout
|
||
- Auto-Tell tabs: per-partner hashed icon (7-glyph pool:
|
||
envelope/star/heart/bell/bookmark/flag/fire) plus hashed color (12-color palette) — 84 distinct
|
||
icon+color combinations
|
||
- Unread indicator: pulsing red dot in the top-right corner of any sidebar tab icon with unread
|
||
messages, 2-second sine-wave pulse, respects `Configuration.ReduceMotion`
|
||
|
||
### Changed
|
||
|
||
- Migration v14 → v15: deprecated Configuration fields `HellionThemeEnabled` and
|
||
`HellionThemeWindowOpacity` removed
|
||
- Appearance settings cleaned: legacy theme-engine bindings replaced by Themes tab (introduced in
|
||
v1.1.0)
|
||
|
||
### Fixed
|
||
|
||
- Settings save no longer wipes chat history by default — the heavy
|
||
`ClearAllTabs + FilterAllTabsAsync` cycle now only runs when a filter-relevant setting actually
|
||
changed (Privacy filter, persisted channels, per-tab channel selection). Cosmetic changes keep the
|
||
in-session chat intact
|
||
- Identifier-based `MessageList` restore in `Configuration.UpdateFrom` plus TempTab skip in
|
||
`ClearAllTabs`/`FilterAllTabs` ensure persistent tabs and Auto-Tell tabs both survive the save
|
||
- Sidebar buttons now align vertically with the first message row (top padding mirrors the chat
|
||
header toolbar height)
|
||
- Sidebar child window no longer paints the top padding area with its frame background
|
||
- Status bar version slot (`vX.Y.Z · Hellion`) no longer clips its rightmost character
|
||
|
||
### Notes
|
||
|
||
- Polish phase (animations, theme crossfade, header quick-picker) follows in v1.3.0
|
||
- Top-Tab icon prefixes were considered but dropped: Dalamud's default font atlas does not include
|
||
FontAwesome codepoints, so mixed-font in a single TabItem label renders as tofu. Underline pill
|
||
alone is the v1.2.0 visual treatment for top tabs. Resolution would require Font-Atlas merge at
|
||
FontManager level — out of scope.
|
||
|
||
---
|
||
|
||
## [1.1.0] — 2026-05-05 — Theme Foundation
|
||
|
||
First major UI cycle after v1.0.0. Theme engine, five built-in themes, custom themes via JSON,
|
||
settings card grid.
|
||
|
||
### Added
|
||
|
||
- **Theme engine** with five built-in themes: Hellion Arctic (default), Chat 2 Classic, Event
|
||
Horizon, Moonlit Bloom, Mint Grove.
|
||
- **Settings → Themes** with mini mockup preview per theme. Clicking a card instantly switches the
|
||
entire plugin (chat, settings, pop-outs).
|
||
- **Custom themes via JSON** in `pluginConfigs/HellionChat/themes/`. On first start,
|
||
`example-theme.json` is placed there as a template.
|
||
- **Optional theme chat channel colours**: themes can ship their own channel colours. On switch, a
|
||
banner appears with _Apply / Keep current_ — never applied automatically.
|
||
- **Settings card grid**: new overview on open, clicking a card navigates into the section's detail
|
||
view. Breadcrumb + ESC navigate back.
|
||
- **`docs/THEME-AUTHORING.md`** as a guide for writing custom themes, with Hellion Forge branding.
|
||
|
||
### Changed
|
||
|
||
- **Plugin icon** updated to Hellion Forge hammer (previously a ChatTwo derivative).
|
||
- **Settings detail view** uses the full width — the second tab list on the left is gone because the
|
||
card overview handles navigation.
|
||
- **`HellionStyle.PushGlobal`** is now theme-driven (`PushGlobal(theme, opacity)`) instead of
|
||
const-palette-driven.
|
||
- **Configuration v13 → v14**: all users land on `hellion-arctic`. Those who prefer the upstream
|
||
look can select `chat2-classic` in Settings → Themes.
|
||
|
||
### Deprecated
|
||
|
||
- `Configuration.HellionThemeEnabled` and `HellionThemeWindowOpacity` remain readable for one
|
||
release as a safety net but are no longer evaluated. Removal planned for v1.2.0.
|
||
|
||
### Security
|
||
|
||
- Custom theme JSON loader validates `schemaVersion`, required fields and hex format. Invalid themes
|
||
are skipped with a warning; the plugin continues loading with built-ins.
|
||
|
||
### Internal
|
||
|
||
- 51 local unit tests (theme records, registry, JSON round-trip, sanity per built-in theme). Tests
|
||
are gitignored.
|
||
|
||
---
|
||
|
||
## [1.0.3] — 2026-05-04 — Polish Patch
|
||
|
||
Four small polish items from the backlog bundled together:
|
||
|
||
- **Hide on New Game+ menu**: optional global toggle that hides Hellion Chat (and all other plugin
|
||
windows such as Settings, DB Viewer, pop-outs) while the NG+ menu is open. Settings → Window →
|
||
Frame, default off. Skips the entire `WindowSystem.Draw()` path analogous to the existing
|
||
LoadingScreens pattern.
|
||
- **Channel selector colouring**: optional tinting of the channel-select button (comment icon) next
|
||
to the input field in the current channel colour. Settings → Appearance → Chat Colours, default
|
||
on. Consistent with the existing input text colouring; ExtraChat override is carried over.
|
||
- **(De)buff icon aspect-ratio fix**: `PayloadHandler.InlineIcon` was squashing all hover icons to
|
||
32×32. Status icons with non-square dimensions (debuffs with an arrow indicator) are now shrunk
|
||
aspect-preserving. Standalone float-math implementation with zero-size guard instead of a
|
||
cherry-pick from the open ChatTwo PR #157 (which had an int-division trap).
|
||
- **HideState logging sweep**: all HideState transitions (Battle/Cutscene/User/Override plus pop-out
|
||
mirroring) log at verbose level. Off by default; enable via `/xllog set HellionChat verbose` for
|
||
bug-report diagnostics.
|
||
|
||
[Release Notes 1.0.3](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.0.3)
|
||
|
||
---
|
||
|
||
## [1.0.1] — 2026-05-04 — Window Position Recovery
|
||
|
||
Fixes an off-screen-window scenario the user could end up in after a monitor disconnect or display
|
||
layout change between sessions. An automatic one-shot bounds check on the first draw after plugin
|
||
load snaps the window back into the visible viewport, and a new "Reset Window Position" button in
|
||
Settings → Window → Frame serves as the manual escape hatch for edge cases.
|
||
|
||
Bundled housekeeping since v1.0.0: documentation restructured into `docs/`, stale ChatTwo/\* paths
|
||
in repo configs cleaned up, Pidgin parser library bumped from 3.3.0 to 3.5.1, GitHub Actions bumps
|
||
for `actions/setup-dotnet` (4 → 5) and `github/codeql-action` (3 → 4).
|
||
|
||
[Release Notes 1.0.1](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.0.1)
|
||
|
||
---
|
||
|
||
## [1.0.0] — 2026-05-03 — Standalone Major Release
|
||
|
||
First fully independent release. Code namespace, IPC channels and source tree structure consolidated
|
||
under `HellionChat.*`. Plugin refuses to start alongside an active upstream Chat 2 (bilingual
|
||
conflict message). SQLite native pinned to 3.50.3 (CVE-2025-6965, CVE-2025-7709). Tab layout default
|
||
for new installs and users on config version 12 or older restructured (5 thematic tabs instead of 6+
|
||
kitchen-sink). Sweep of critical and major findings from the codebase audit incorporated.
|
||
|
||
[Release Notes 1.0.0](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.0.0)
|
||
|
||
---
|
||
|
||
## [0.6.1] — 2026-05-03 — Pop-Out Discoverability & /tell Auto-Pop-Out
|
||
|
||
Pop-out button visible in the chat header, one-time hint banner for the pop-out feature. New setting
|
||
"Open new /tell tabs directly as pop-out". Pop-out input is now active by default. Bug fixes: ghost
|
||
windows on LRU-drop / logout, dead zone below the input bar when the hint banner is active.
|
||
|
||
[Release Notes 0.6.1](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v0.6.1)
|
||
|
||
---
|
||
|
||
## [0.6.0] — 2026-05-03 — UX Polish: Pop-Out Input + Colour Presets
|
||
|
||
Two opt-in UX features. Pop-out windows optionally get a compact input bar with a channel-coloured
|
||
icon button and an independent text buffer per pop-out. Seven built-in colour presets (Classic, High
|
||
Contrast, Pastel, Dark Mode Tuned, Hellion, Night Blue, Indigo Violet) for one-click apply.
|
||
Configuration migration v10 → v11.
|
||
|
||
[Release Notes 0.6.0](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v0.6.0)
|
||
|
||
---
|
||
|
||
## [0.5.4] — 2026-05-02 — WrapText Hardening
|
||
|
||
`ImGuiUtil.WrapText` rewritten from pointer arithmetic to Span- and index-based control flow.
|
||
Permanently closes the recurring CodeQL critical alert "unvalidated local pointer arithmetic". No
|
||
user-visible behaviour change — word-wrap output is byte-identical to 0.5.3.
|
||
|
||
[Release Notes 0.5.4](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v0.5.4)
|
||
|
||
---
|
||
|
||
## [0.5.3] — 2026-05-02 — Pointer Arithmetic Hardening
|
||
|
||
First attempt at closing the CodeQL critical alert in `ImGuiUtil.WrapText`. Encoded byte buffer
|
||
length is validated via `GetByteCount` before pointer arithmetic.
|
||
|
||
[Release Notes 0.5.3](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v0.5.3)
|
||
|
||
---
|
||
|
||
## Earlier Versions
|
||
|
||
Releases before 0.5.3 (bootstrap phase 0.1.0 to 0.5.2) are available directly on the Gitea release
|
||
stream:
|
||
|
||
[All Releases](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases)
|
||
|
||
---
|
||
|
||
## Maintenance Note
|
||
|
||
The source of truth for the user-facing changelog is the `changelog:` block in
|
||
`HellionChat/HellionChat.yaml`. `repo.json` and the GitHub release body are fed from there. This
|
||
file (`docs/CHANGELOG.md`) is a curated summary with links to the release pages and is updated
|
||
manually on each version bump.
|