Burnsies HideoutDocsBurnsie.Common

Notifications & Text — Notifier, Palette, Captions

Three surfaces for talking to the player, each with a distinct job:

SurfaceWhereUse for
Notifier toaststop-right feedEvents: dispatches, arrivals, status changes
Notifier live statustop-left HUD lineA persistent, update-in-place incident status
Captionsbottom-centre subtitleSpoken dialogue and narration

Notifier — rate-limited toasts + live status

Why it exists

Two failure modes are engineered out:

  • Feed flooding. A wave dispatch plus five arrivals in two seconds unreadably floods the notification feed. Queued toasts drain on a fiber with a minimum gap (default 1200 ms, tune via MinGapMs).
  • Flickering status. Feed toasts auto-fade; updating one means remove + re-add, which flashes. The live-status line is instead drawn every frame via Game.FrameRender, so it updates in place without flicker.

Usage

var notifier = new Notifier(log);
notifier.Start(fibers, flag);        // starts the queue drain fiber; once per duty session

// Queued (rate-limited) toasts:
notifier.Show(Palette.Dispatch("unit en route to " + Palette.Key(areaName)));
notifier.ShowBranded("~b~MyPlugin", "~s~subtitle", "body text");

// Immediate variants — for moments that must not wait (must be called from a GameFiber):
notifier.ShowNow("text");
notifier.ShowBrandedNow("~b~MyPlugin", "~s~subtitle", "body");

// Persistent live status (top-left; call as often as you like, it never flashes):
notifier.SetLiveStatus("~b~PANIC ACTIVE", "", "3 units responding");
notifier.ClearLiveStatus();

// Teardown — once per session:
notifier.Clear();   // drop anything still queued
notifier.Stop();    // clears status AND detaches the frame-render hook

Behavior notes

  • Enabled = false is a master switch: all toasts drop silently (logging stays).
  • The queue is bounded (16 entries) so a stuck drain fiber can't grow it unbounded.
  • Branded toasts use the web_lossantospolicedept texture by default; override with TextureDictionary / TextureName.
  • Color/style markup (~b~, ~r~, …) is stripped from the live-status line — it is drawn text, not a game notification, so tokens would render literally.
  • The live-status overlay disables itself for the session if drawing ever throws (a throwing render handler would fire every frame), and the failure is logged once.
  • Call Stop() at session teardown. The frame-render hook must not outlive the notifier across duty toggles.

Palette — the community color standard

Implements the lcpdfr.com "standardisation of API plugin colors" convention. Color the key words, not whole sentences; always reset with ~s~.

Constant / helperTokenMeaning
Palette.Red, Danger(text)~r~Danger, suspects, critical alerts
Palette.Blue, Police(text)~b~Police, dispatch, plugin branding
Palette.Yellow, Key(text)~y~Keybinds, objectives, routes
Palette.Orange, Warn(text)~o~Warnings, cooldowns
Palette.Green, Success(text)~g~Success, Code 4
Palette.White~w~White
Palette.Reset~s~Reset to default style
Palette.NewLine~n~Line break inside a notification
Dispatch(text)~b~Dispatch:~s~ text — a dispatch-voiced line
notifier.Show(Palette.Dispatch("respond " + Palette.Danger("Code 3") +
    " to " + Palette.Key("Mission Row")));

Captions — movie-style dialogue subtitles

Rendered on GTA's own subtitle line (bottom-centre) with a colored speaker label — the right surface for speech, where help text and notifications read as UI.

// Duration derived from text length (reading pace, clamped 1.8–7 s), returned in ms
// so you can pace the next line:
int ms = Captions.Speak("Auditor", "You can't stop me filming.");
GameFiber.Sleep(ms + 300);
Captions.Speak("Officer", "Sir, step back behind the tape.");

// Plain narration (no speaker label):
Captions.Narrate("The crowd is getting restless.");

// Explicit duration:
Captions.Show("Dispatch", "Units be advised...", 4000);

Pacing constants: 45 ms per character, minimum 1800 ms, maximum 7000 ms. Captions are cosmetic — failures are swallowed, never disturbing the scene.