Files
HellionChat/docs/ROADMAP.md
T
JonKazama-Hellion d9f6704316 chore: bump version to 1.4.9, sync manifest
Manifest version bump for the v1.4.9 release cut. Schema-required v16
stays unchanged (R1/R2/R3 are all config-neutral refactors).

Files touched:
- HellionChat/HellionChat.csproj: <Version> 1.4.8 -> 1.4.9
- HellionChat/Plugin.cs: schema-migration error string self-reference
  (v1.4.8 -> v1.4.9, required schema v16 stays)
- repo.json: AssemblyVersion, TestingAssemblyVersion, 3x DownloadLink*
  URLs all bumped to 1.4.9 / v1.4.9. Changelog field is still on v1.4.8;
  the v1.4.9 block plus v1.4.5 slim-drop land in the next commit.
- README.md: shield badge, version header in lead paragraph, project-
  status block rewritten for v1.4.9 (Plugin-Load Render Polish).
- docs/CHANGELOG.md: v1.4.9 block inserted above v1.4.8.
- docs/ROADMAP.md: v1.4.9 moved into the released-versions list,
  "Next Cycle" header now targets v1.4.10 (Render Clipper + Symbol
  Picker reserves carried over from the v1.4.9 plan).

yaml changelog block and repo.json Changelog field follow in the
docs commit so the slim-drop of v1.4.5 stays atomic with the v1.4.9
block insert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:31:35 +02:00

279 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hellion Chat — Roadmap
Planned work after the v1.0.0 standalone cut. This list is intentionally high-level: concrete specs, size estimates and
repro steps live in the internal backlog. External tracking runs via
[Gitea Issues](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/issues) with the `roadmap` label once an
item is scheduled for a cycle.
Order reflects priority, not a guarantee. Items may shift or be dropped entirely if they turn out to be a poor fit for
the plugin's privacy-first scope during brainstorming.
---
## Next Cycle (v1.4.10)
**Render Clipper, Symbol-Picker and Final-Cleanup.** Reserve items inherited from the v1.4.9 plan that did not need to
land in the HITCH-cut: an `ImGuiListClipper` for variable-height messages in `DrawMessages` (the OtterGui `ImGuiClip.cs`
wrapper is the idiom anchor), a Symbol Picker popup for the chat input (`imgui_demo.cpp` Popups & Modal Windows section
is the pattern reference), plus the carry-over from v1.4.9: structural First-Frame-Layout rewrite if the v1.4.9 selective
defers turn out to be too narrow once user-side regressions surface. Lazy-Window-Init naive is **not** in scope — the
v1.4.9 Stage-2 diagnose falsified that path (`WindowSystem.windows` is non-thread-safe, Game-Freeze under reload stress,
no measurable HITCH delta). A clean DI-container adoption (Lightless `PluginHostFactory` pattern) belongs in v1.5.x and
will revisit the question with the right threading model.
---
## v1.4.9 — Plugin-Load Render Polish (released 2026-05-15)
Tenth sub-patch of the v1.4.x Polish Sweep series. First-frame HITCH drops from ~127 ms median to ~76 ms median (4-reload
sample), comfortably under Dalamud's 100 ms warning threshold. Mechanism: a single `_firstFrameDone` flag inside
`ChatLogWindow` defers six non-essential rendering sections (bottom status bar, channel-name SeString chunks, window
bounds check, v0.6.1 hint banner, autocomplete, input-preview calculation) from frame 0 to frame 1. User sees those
sections ~17 ms (60 fps) later, invisible inside the ~2.5 s font-atlas build window after every reload. Slash-command
registration moved from individual window constructors to a central `SetupCommands` / `TearDownCommands` pair in
`Plugin.cs``/hellion`, `/hellionView`, `/hellionSeString` and `/hellionDebugger` work before their target windows are
opened the first time, and Dalamud's plugin-manager `OpenConfigUi` / `OpenMainUi` buttons hang on the same path.
Plugin-load profiling logs (auto-translate warmup, `MessageStore.Connect`, `MessageStore.Migrate`, `FilterAllTabs`) stay
on at Information level as a regression tripwire. Migration v17 stays (no schema bump). Hypothesis-triage falsified
three of four candidate root causes (font-atlas sync fallback, theme-apply ABGR-cache init, multiple-window render via
lazy-init) — actual cost distributes evenly across ~10 ImGui sections inside ChatLogWindow, so structural rewrite is
deferred to v1.5.x DI-container cycle.
## v1.4.8 — Hook-Layer and Polish Quick-Wins (released 2026-05-14)
Ninth sub-patch of the v1.4.x Polish Sweep series. Database Viewer gains an optional FTS5 full-text search across the
full chat history, built asynchronously on first run after the update with a progress toast; the local page-filter
remains the default mode. Custom theme files auto-reload when edited while the theme is active (1 Hz disk-stat throttle,
so per-frame cost is free). Retention sweep no longer blocks the framework thread — `Framework.Run(...).Wait()` is
replaced by `Framework.RunOnTick(...)`, removing the ~194 ms hitch per sweep. Status-bar height is now derived from
`GetTextLineHeightWithSpacing()` plus a DPI-aware spacer so the bar renders correctly at Windows display scaling above
100 %. Receive-suppressed-tells routing was investigated and **postponed to v1.5.x**: when other plugins suppress tells
via `CheckMessageHandled`, FFXIV's chat-pipeline skips the `RaptureLogModule.AddMsgSourceEntry` path, which means the
`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 anyway. Migration v17 stays (no schema bump). H3 leaves a foundation
note in the Vault (`Projekte/FFXIV/Hellion Chat/v1.5.x Ad-Block Foundation.md`) covering the NoSoliciting filter +
bubble-layer hook pattern as a ready-made template for the v1.5.x cycle.
---
## v1.4.7 — Backlog Cleanup and Mid-Features (released 2026-05-13)
Eighth sub-patch of the v1.4.x Polish Sweep series. First user-visible feature bundle since v1.4.5. TempTell tabs can
now be pinned via right-click; 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. A hard cap of 5
pinned tabs lives in a pool separate from the 15-tab auto-tell pool, total ceiling 20. The sidebar groups pinned tabs
into their own section with a divider header, and the sidebar width itself is now configurable in **Theme & Layout**
between 44 and 160 px. Honorific glow outlines render when the title carries a Glow colour, opt-in via **Settings →
Integrations → Render glow outlines (Honorific)** (default off). Honorific's gradient (Color3 / GradientColourSet / Wave
/ Pulse) is parsed but rendered statically — a later cycle will port the full animation algorithm or land an upstream
IPC PR for the resolved frame colour. `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` — together they fix a Settings-Save regression where the chat input could pop back to
`/tell <pinned-partner>` after touching settings on a Party or Linkshell tab. Internal items: `IPluginLogProxy`
indirection over Dalamud's `IPluginLog` routes all ~91 `Plugin.Log` call sites through a testable proxy, closing the
F12.1 test-isolation gap (`MessageStore.Migrate0` runs in xUnit now). TempTab counter switched from `Interlocked` cached
field to derived `Tabs.Count(predicate)`. Migration v16 → v17 is additive (new `Tab.IsPinned` flag). Build-Suite floor
688 → 710 (+22 tests across Pin-lifecycle predicates, pool limits, Tab.Clone roundtrip, MessageStore Migrate0
construction, and Honorific TitleData JSON roundtrip).
## v1.4.6 — Code Hygiene and Refactor (released 2026-05-12)
Seventh sub-patch of the v1.4.x Polish Sweep series. Maintenance patch — no user-visible behaviour changes; tightens the
development feedback loop and pulls in two ChatTwo upstream bugfixes. `scripts/preflight.sh` gains a csharpier reflow
check (Block E) and a markdownlint pass (Block F), so style drift and markdown violations are blocked at the pre-push
gate. `FontManager.AddFontWithFallback` catch-filter now spans `InvalidOperationException` and `ArgumentException` on
top of the existing IO triad, with the exception type name in the warning log so the diagnostic path can see which
atlas-toolkit throw triggered the fallback. `BrandingLinks` and `IntegrationLinks` run a `[ModuleInitializer]` URL
validation pass on plugin load; a typo in a future URL rotation now throws at startup instead of failing silently when a
user clicks the broken button. Cherry-picked from ChatTwo upstream `f35b7d3`: `Chat.SetChannel` no longer leaks the
native `Utf8String` when the linkshell check rejects the channel (rename to `IsChannelOrExistingLinkshell` plus
wrap-not-return), and `Tab.Clone` now deep-clones `UsedChannel` and `TellTarget` (the previous reference copy let PopOut
and Temp tabs mutate each other's channel state). The `ChatLogWindow` active-tab underline pill scales with
`ImGuiHelpers.GlobalScale` and rounds to physical pixels for crisp rendering above 100 % DPI. Internal items:
`HellionStyle` ChildBgAlpha extracted to a testable helper, `Plugin.SaveConfig` clones only the temp-tab subset in the
snapshot path, `SettingsOverview` caches the draw-list per frame, `Dalamud.Utility.Util` static surface routed through
an `IPlatformUtil` indirection (`MessageStore`'s `IsWine` probe is now testable in isolation). No schema bump, no
migration.
## v1.4.5 — UX and Robustness (released 2026-05-12)
Sixth sub-patch of the v1.4.x Polish Sweep series. User-visible robustness polish plus two doc/test polish items from
the audit backlog. Chat-log draw failures now surface as a one-shot notification instead of failing silently. The
first-run wizard splits accept from close: `OnClose` no longer silently sets `FirstRunCompleted`, and a new footer
"Later — keep defaults" button is the explicit path to dismiss without picking a profile. `InputHistoryService` clears
on plugin dispose so the previous session's typed commands don't bleed into the next load. `FontManager` falls back to
the system font path if the embedded Hellion font resource is missing (broken-csproj / dev-build only). The status bar
hides the version slot when the chat window is too narrow to fit all five slots without overlap. Plus
`Plugin.cs:167-168` gains an explicit session-only Auto-Tell-Tab invariant comment with a `TempTabCounter.InitFromList`
pin in the Build-Suite. No schema bump, no migration.
## v1.4.4 — Threading and IPC Safety Polish (released 2026-05-12)
Fifth sub-patch of the v1.4.x Polish Sweep series. `AutoTellTabsService.ActiveTempTabCount` switches from a
lock-protected LINQ `Count` to an `Interlocked` counter kept in sync from inside the existing mutation paths;
`Initialize()` seeds from the persisted Tabs list and `SaveConfig`'s snapshot-restore path calls a new
`ResyncTempTabCounter()` after the mid-step `RemoveAll`. `HonorificService` carries per-method threading banners and
`TryUnsubscribe`'s log level moves from Debug to Warning. `AutoTranslate.PreloadCache` is marked `IsBackground = true`
so plugin unload no longer waits for it. `Configuration.IsAllowedForStorage` logs once per unknown ChatType via a
`NonSerialized` `HashSet`, and `PrivacyPersistUnknownChannels` default flips to `true` for new installs. No schema bump,
no migration.
## v1.4.3 — Plugin-Load Async-Init + Repo-Cutover (released 2026-05-08)
Fourth and largest sub-patch of the v1.4.x Polish Sweep series. Plugin migrated to Dalamud's `IAsyncDalamudPlugin` API:
the constructor handles only bootstrap essentials (config load, language init, conflict detection); migrations, service
allocations, window construction and hook subscription move to `LoadAsync`. Schema gate replaces the v9 → v16 migration
chain; configs on schema v16+ load directly, older configs trigger an "install v1.4.2 first" error.
`AutoTranslate.PreloadCache` moved off the load path. `FontManager.BuildFonts` runs sync at the start of `LoadAsync`;
Dalamud rebuilds the font atlas on its own pipeline. Custom-repo URL cut over to `gitea.hellion-forge.cloud`; the GitHub
repo remains as a frozen v1.4.2 snapshot. Plugin load time sits at ~3.7 s median (5 reloads), comparable to v1.4.2 — the
async migration is a foundation for v1.4.4 lazy-init optimisations rather than an immediate user-perceived win.
## v1.4.2 — ChatLog Frame-Hot-Path (released 2026-05-08)
Third sub-patch of the v1.4.x Polish Sweep series. Per-frame allocations eliminated from the ChatLogWindow render path
and the settings status bar. Card-mode border loop in `DrawMessages` hoists five invariants into a pre-loop hoist;
`AutoTellTabTint` gets a per-tab cache via `TabTintCache` (separate validation keys per cache, no cross-invalidation);
status bar moves the cache-gate check before the aggregation and replaces LINQ `Sum`+`Count` with a single-pass foreach.
## v1.4.1 — Theme Engine Performance (released 2026-05-08)
Second sub-patch of the v1.4.x Polish Sweep series. ABGR cache pre-computed on theme records; `HellionStyle.PushGlobal`
reads from the cache instead of converting per slot per frame. **~13 % render-time recovery** in smoke tests (plan
estimate of 26 % was conservative; real result ~1015 %). Custom-theme hot-reload survives transient file locks via
last-known-good snapshot. Plus: Synthwave Sunset as the tenth built-in, author credits consolidated under Hellion Forge,
Mint Grove + Forge Merchantman credited to Carla Beleandis as a community thanks.
## v1.4.0 — Critical Lifecycle Fixes (released 2026-05-07)
First sub-patch of the v1.4.x Polish Sweep series. Seven P0 findings from audit passes 3 and 4 resolved: async-void
loads, missing `IsBackground` flags, `GC.Collect` in Dispose, deferred-save race and pre-v13 backup lookup for
`WindowOpacity`. No schema bumps, no user-facing behaviour changes other than reload and shutdown running noticeably
cleaner.
## v1.3.0 — Plugin Integrations: Honorific (released 2026-05-07)
First cycle of the plugin integrations roadmap. Honorific custom titles displayed in the chat header with auto-detect
and silent fallback. New Integrations settings tab. Pattern-setter for the five following cycles (Context Menu,
NotificationMaster, RP Status Block, ExtraChat, XIVIM).
Spec: [Plugin Integrations Overview](../Hellion%20Chat%20Plugin-Integrationen.md)
## v1.2.3 — Theme Expansion (released 2026-05-06)
Four new built-in themes: Night Blue, Indigo Violet, Forge Merchantman, Hellion Spectrum (Deuteran/Protan-safe). No
engine changes. See `docs/CHANGELOG.md`.
(v1.2.2 was burned because the `repo.json` manifest was not bumped in sync on the first push — re-released as v1.2.3
with full manifest synchronisation.)
## v1.2.1 — Settings Cleanup (released 2026-05-06)
Settings re-sorted thematically (9 cards), 4 dead settings removed, auto-migration v15 → v16 without data loss.
## v1.2.0 — Layout Refresh (released 2026-05-05)
Top tabs refresh, sidebar tab icons, bottom status bar, card rows as default message render, auto-tell tab hashing.
## v1.1.0 — Theme Foundation (released 2026-05-05)
Theme engine with five built-in themes, settings card grid, custom themes via JSON, theme authoring docs. Plugin icon
updated to Hellion Forge hammer. See `docs/CHANGELOG.md` for details.
Items from the original v1.1.0 plan (ad-block / spam filter, receive-suppressed-tells toggle) were deferred in favour of
the theme engine — both items live on in the mid-term block.
---
## Mid-Term (v1.4.x+)
- **Plugin Integrations Roadmap (Cycles 26)** — six plugin integrations planned; Honorific (Cycle 1) is live, followed
by Context Menu, NotificationMaster, RP Status Block, ExtraChat and XIVIM in their own cycles. Spec and cycle order in
[Plugin Integrations Overview](../Hellion%20Chat%20Plugin-Integrationen.md).
- **Ad-Block / Spam Filter** — hybrid concept combining a lightweight built-in filter with optional `NoSoliciting` IPC
integration. Addresses ad-spam in public channels and tells. Deferred from the v1.1.0 plan.
- **Receive-Suppressed-Tells Toggle** — auto-tell tabs trigger even when a third-party plugin (e.g. XIVMessenger)
globally suppresses /tell display. Same hook layer as ad-block, so they are bundled.
- **Database Viewer Inline Search** — full-text search in the DB viewer via SQLite FTS5. Currently only date and channel
filters are available.
- **TempTell Persistence** — pin toggle on TempTell tabs so selected tells survive a relog. Tester request from Jingliu.
- **FontManager Async Refactor** — move `LoadGameSymFontAsync` out of the blocking plugin constructor. Fix cold-start
hitching on first plugin load (low severity; plugin is functional).
- **Separate Opacity Active vs. Inactive** — second slider for inactive window opacity. Upstream declines this; we can
decide differently here.
- **Failed-Tell Notification** — visible message on /tell failure (offline, restricted instance, blacklisted,
world-mismatch) instead of silent failure.
- **Per-Tab Sound Notification** — sound toggle and optionally a custom .wav per tab, with mute-in-combat option.
---
## Long-Term (v1.x+)
### Storage Backends (three-stage confirmation)
- MySQL/MariaDB backend for multi-device setups
- PostgreSQL backend
- AES-256 encryption for sensitive channels with a local key
### Linux-Specific
- WireGuard network detection as an optional filter trigger
- libnotify integration for native Linux toasts
- XDG compliance (complex under Wine)
### UX and Tab Management
- **Regex Tab Routing** — route plugin output spam into dedicated tabs, auto-sort tells from specific people. Clearly
scoped against ad-block: routing sorts into views, blocking hides globally.
- **Auto-Detect Duties** — tab switch on duty start via condition flag.
- **UX Bundle** — vertical tab bar as a layout option, Shift+Mousewheel to scroll tab headers without activating them,
global hotkey to close the active tab.
- **Configure Tab Title** — configurable tab title format (name / name + abbreviated world / full name / custom),
overridable per tab.
- **Name Display Options** — analogous to FFXIV vanilla (full name, first name abbreviated, initials), per-channel
override possible.
- **Item & Flag Linking** — outgoing: Shift-click on an item/flag sends it to the focused plugin input. Incoming: item
links and map coordinates are clickable.
- **Color Currently Selected Input Channel** — tint the channel-selector button in the input bar with the current
channel colour.
- **Plugin-Disclosure Pre-Send Filter** — configurable word/regex list blocks sending with a pre-send confirmation.
Protects against accidentally mentioning plugins in public channels.
- **Chat Clear on Name Change** — on character name change, migrate or wipe local history; default is wipe for maximum
privacy.
- **Hide Plugin Window on NG+ Screen** — extend hide logic to cover additional addon names.
- **Kick from Novice Network** — mentor niche; context menu entry with confirmation.
- **Text-to-Speech for /tell** — incoming tells via TTS, optionally per sender, with channel filter and mute-in-combat.
Low priority.
### Distribution and Branding
- Hand-drawn Hellion logo (currently a placeholder from the Hellion Online Media brand repo)
- GitHub Action for automatic `repo.json` sync after tag push
- Submission to the Dalamud main plugin repository (in addition to the custom repo)
---
## Bug Verifications
Carried over from the upstream issue tracker; not yet reproduced or verified in Hellion Chat 1.0.0. Will be tested
against the current state when opportunity allows.
- **Right-Click Whisper Error** in Field Ops / Special Instances (Eureka, Bozja, Occult Crescent, DRS) — upstream
[#168](https://github.com/Infiziert90/ChatTwo/issues/168). Reply helper appears to swallow the `@World` suffix.
- **FPS Drops with Plugin Active** — upstream [#145](https://github.com/Infiziert90/ChatTwo/issues/145). 1020 % drop
since upstream v1.29.19.0. v1.0.0 includes several fixes on the suspected paths; repro test against the current state
is open.
- **Add Blacklist from Plugin Window** — upstream [#140](https://github.com/Infiziert90/ChatTwo/issues/140). Right-click
add-to-blacklist throws "Cannot locate character with that name"; works via vanilla chat.
- **DB Viewer Column Sort** — State column sorts lexicographically instead of numerically (10 before 2). XIVIM
[#82](https://github.com/NightmareXIV/XIVInstantMessenger/issues/82); repro in Hellion Chat open.
---
## Licence Boundary
Hellion Chat is licensed under EUPL-1.2. Concept imports from AGPL-3.0 plugins (e.g. XIV Instant Messenger) are
architectural inspiration only — no code was ported. Code imports from the upstream codebase are complete as of v1.4.x
because Chat 2 is undergoing a fundamental rework and selective patches are no longer cleanly portable. Status and
rationale in [`UPSTREAM_SYNC.md`](UPSTREAM_SYNC.md).