Commit graph

3 commits

Author SHA1 Message Date
Vadim Peretokin
848dee43ea
improve: base UI captures your gossips in its chat window (#9838)
#### Brief overview of PR changes/additions
- The base UI's chat capture now recognises `You gossip, 'test!'`-style
lines and copies them into the Tells tab
- New `you gossip` shape under the tells gate (18 of 20 gate substrings
used), mirrored in `chatPatterns` so gossip lines stay out of the vitals
harvester
- Package version 1.3.0, `.mpackage` rebuilt; corpus lines added to
StarterUiTriggerCostTest and UI_spec

#### Motivation for adding to Mudlet
Gossip is a staple channel on Diku-style games, and the starter UI
missed these lines entirely.

#### Other info (issues closed, discussion etc)
Only your own gossips are captured for now - the incoming `Bob gossips,
'...'` counterpart can be added the same way if wanted.

**Test case:** `ctest -R StarterUiTriggerCost`, or gossip on any
Diku-style game with the base UI up and see the line land in the Tells
tab.

Assisted-by: Claude:claude-fable-5
2026-08-13 08:06:37 +02:00
Vadim Peretokin
7c03ced91a
improve: the starter UI's chat capture is now a trigger tree players can read and copy (#9736)
#### Brief overview of PR changes/additions
- Chat capture ships as a permanent trigger tree in the base UI package
instead of triggers created at runtime, so it is visible and copyable in
the editor: one root folder, three cheap substring gates (tells / speech
/ channel tags), each gating its Perl regex shapes as children.
- Lifecycle moves from `tempRegexTrigger`/`killTrigger` to
`enableTrigger`/`disableTrigger` on the three gates, with a
`BaseUI.chatTriggersArmed()` probe replacing the id bookkeeping.
- Vitals capture is unchanged and stays Lua-armed: its prefilter is
machine-built from the label tables, so an XML copy would drift from
what `parseVitalsLine` reads.

#### Motivation for adding to Mudlet
The gate pattern - a cheap substring parent chaining to regex children -
is the thing new scripters most need to learn, and shipping it as a
readable tree teaches it where invisible runtime triggers could not.

#### Other info (issues closed, discussion etc)
A non-matching line now costs ~17 substring scans and zero regex work.
Tightening the speech gate's literals fixed real leakage in the process:
the stems `say`/`ask`/`yell` had been letting "essay", "task", "asked"
and "yellow" through to the regex layer.

New tests: the tree's leaf shapes are asserted equal to
`BaseUI.chatShapeRegexes()`, gates are asserted substring-only, and
every gate literal must have a corpus line - the enforcer for the gate
contract, since a case-mismatched gate would otherwise drop lines
silently. Each was verified to fail by mutating the shipped package.

**Test case:** Start a new profile, connect to a game with tells and
channels, and confirm chat lines still sort into their tabs; open the
Triggers editor and confirm `mudlet-base-ui` -> `Mudlet base UI chat
capture` shows three gates with regex children. `ctest -R
StarterUiTriggerCost` covers both.

Assisted-by: Claude:claude-opus-5
2026-08-08 18:49:56 +02:00
Vadim Peretokin
9a9710b229
fix: new profiles process game text about twice as fast (#9705)
#### Brief overview of PR changes/additions

- The starter UI armed **77 always-active PCRE triggers** (12 chat + 65
vitals) at package load, so every line a game sent was matched against
all of them - and every line one matched was then re-walked in Lua with
all 77 patterns **recompiled from source**, because `rex.match` given a
pattern string compiles it afresh on every call. They are now fronted by
4 triggers (3 chat-routing groups + 1 vitals prefilter) and compiled
once. The 65 vitals shapes and 12 chat shapes are byte-identical and
still do all the reading.
- The plain-text vitals layer now retires itself once GMCP or MSDP holds
the source lock, since `applyVitals` discards its readings from that
point anyway, and re-arms on disconnect.
- `PipelineBenchmark` created its profile through the production
new-profile path, so the starter UI was **inside** the
`text_lines_per_sec` baseline backing the "no more than 10% throughput
loss" gate for #9011 - the guard built to catch this class of regression
could not see it. Pipeline metrics now come from a profile with default
packages suppressed; the shipped configuration is reported separately as
`defaults_*` and gated in its own right.

#### Motivation for adding to Mudlet

Every new 5.0 profile was paying roughly half its text throughput to a
default package, and the perf guard had the cost baked into its own
baseline so nothing flagged it.

#### Other info (issues closed, discussion etc)

Findings C17 and C18 of the 5.0 QA sweep. Bisected there to `69cd06b1c`
- "add: starter interface with health bars, map and chat for new
players" (#9454); the benchmark half is the interaction of that with
`7d67d4bfb` - "infrastructure: perf baseline" (#9509).

Measured on a quiet 16-core box, Release, no ASan, alternating paired
runs so drift is shared between arms:

| workload | before | after | |
| --- | --- | --- | --- |
| `TelnetBenchmark` `benchLargeData`, 1000 lines that match nothing |
22.25 ms `[22.1-22.6]` | 12.0 ms `[11.9-12.2]` | **1.85x** |
| `PipelineBenchmark`, 25k lines of realistic game output, new-user
profile | 9,998 lines/s `[9,856-10,072]` | 16,503 lines/s
`[16,257-16,632]` | **1.65x** |

Complete separation in both (21 and 9 pairs; within-arm spread ±1.7% and
±1.5%, so ~3% is the smallest effect distinguishable from noise - the
effect is 85% and 65%). The bare pipeline measures 116,000 lines/s, so
the starter UI's remaining cost on that corpus is 7.0x, down from 11.6x;
the residual is the capture layer doing its designed work on a corpus
where 1 line in 11 is a tell and another 1 in 11 a vitals prompt.

Two notes for reviewers:
- `config.lua` is bumped to 1.1.0, so mpkg offers the update - but
default packages are installed at profile creation, so **profiles
already created on a 5.0 PTB keep the old copy** until they update it.
- Touches `src/mudlet.cpp` / `src/mudlet.h` /
`test/functional_tests/CMakeLists.txt`, which #9695 also touches; the
CMakeLists hunk will likely conflict trivially (both append a test
file).

**Test case:** create a fresh profile against any game without GMCP,
confirm the health/mana gauges and chat tabs still appear from prompt
and chat lines, then `ctest -R StarterUiTriggerCostTest`.

Assisted-by: Claude:claude-opus-5
2026-08-08 09:04:14 +00:00