Changes since last PTB (Mudlet-4.22.0-ptb-2026-08-10-f1582ad8)
Fixed:
- underscores and descenders no longer clipped at certain font sizes #9743
- an empty XDG config directory hiding every profile #9712
Infrastructure:
- fix two tests still opting in with an empty XDG config dir #9810
- keep QTest's output visible when ctest runs on Windows #9751
- a media player no longer announces its own destruction #9746
- fix Windows CI losing the per-user luarocks tree #9752
- widget state getters for titles, stylesheets, tooltips and scroll bars #9645
- getWindowGeometry(), windowVisible() and getLabelText() functions #9528
- help links for packages, wired to the Module Help button #9453
- full-window background image/gradient support #9394
- starter interface with health bars, map and chat for new players #9454
- Federation 2 Community Edition #9500
- remainingNamedTimer() to check time left on a named timer #9411
- keyboard shortcuts to switch between game tabs #9460
- option to undo the game's own line wrapping #9455
- warn when two keyboard shortcuts clash #9449
- Show tutorial invitation on first launch #9169
- sign in to supported games using your browser (e.g. Google, Discord, or the game's own account) #9378
- feature callouts #9390
- UI tour to complement the Mudlet tutorial #9385
- the starter UI's chat capture is now a trigger tree players can read and copy #9736
- OSC 8 hyperlink handling, and a setting to turn it off #9731
- credit seven more contributors in the About Mudlet dialog #9675
- make filler widget size in toolbars user settable #9332
- ship every default package as an mpackage #9626
- make the New profile button show what it did #9607
- do not copy leading spaces in multi-line select #9560
- split the games list into My games and All games tabs #9452
- honor XDG_CONFIG_HOME for Mudlet's config directory #9552
- show a simpler trigger editor by default #9450
- embed leak suppressions file in Mudlet binary #9465
- scripts can now match map menus with their map events #9443
- make keyboard shortcut settings work with screen readers #9322
- faster colour tag processing in cecho, decho and hecho #9426
- underscores and descenders no longer clipped at certain font sizes #9743
- an empty XDG config directory hiding every profile #9712
- MXP frames overlapping UI packages that reserve screen space #9737
- don't offer updates that don't yet have a sha256 sum #9735
- new profiles process game text about twice as fast #9705
- a profile named "." or ".." deletes every profile when removed #9722
- game text no longer loses a character to a stray escape code #9723
- triggers being deleted when a script creates a lot of them at once #9724
- macOS builds sometimes failing their tests for no reason #9733
- unbreak development - cloneExportDocument was renamed to takeExportDocument #9732
- getWindowGeometry() and windowVisible() answer for the main window #9714
- three full-window background bugs - vanishing console, lost border colour, huge cover scaling #9711
- two ways a profile save could lose or resurrect your data #9704
- three crashes in the game selection screen #9702
- four security holes in the new browser sign-in #9713
- pausing a track and then playing a different one left you with silence #9710
- mapper scripts stopped being told the map had opened #9709
- trigger editor and deleted item subtrees leaking memory #9700
- stop the test-only waitForEvent() wedging Mudlet on macOS #9691
- profile close during a map operation, Discord presence truncation, and interrupting ttsSpeak() #9686
- user key bindings on Ctrl+1 to Ctrl+9 and Ctrl+Tab #9703
- a trigger that re-creates itself freezes Mudlet #9697
- stop treating long-time Mudlet users as brand new players #9695
- module save reaching into the profile after it is destroyed #9690
- package lifecycle - queued save outliving the profile, unremovable archives, module priority #9684
- six command line and console bugs #9683
- temporary trigger/alias/key/timer cleanup evicting same-named items #9682
- eight Geyser layout and container bugs #9680
- four Lua API corrections - colours, room name offsets, map window state and printTable #9678
- stop the telnet reader writing a NUL past the data it was given #9677
- Mudlet freezing when a window is set to wrap too narrowly #9623
- Discord getters no longer treat presence text as a format string #9660
- don't replay a sign-in token the game already rejected #9676
- stop map saves polluting userData with fallback keys #9469
- Sounds going silent when a file fails to load #9612
- stop table.union modifying a table it was given #9613
- table.n_collect drops values that match an index #9615
- profiles with parentheses in their name can be opened again #9610
- removing a game's profile no longer hides it from the All Games list #9608
- compare() no longer rejects tables that hold false #9614
- event handlers no longer wipe the caller's Lua stack #9621
- killTrigger and killAlias report failure when the item is already dead #9620
- crash when opening settings on macOS #9625
- crash when closing Mudlet while an update is available #9604
- script error messages are readable in dark mode again #9606
- help banners no longer show up in the wrong editor section #9609
- Windows auto-update failing on a release binary with no checksum #9617
- strand no heap objects across the remaining lua_error() raises #9605
- tempTimer negative time, compile() error slot, killTimer idempotency #9597
- ttsSetVoiceByName return garbage and stale ttsSpeechStarted text #9595
- media start events fired too early when replaying a just-stopped sound #9611
- Geyser.Window:echo() keeps the stored message
- gauge three value CSS shorthand and non-positive maximums
- lay out new2 boxes, and apply the layout end_update deferred
- Geyser.Button:setState refuses 'down' before writing it
- Adjustable.Container resetTitle error and delete leaks
- setTextFormat leak, createLabel return convention, windowType scrollbox
- looping sounds playing only once #9569
- garbled error messages in networking and media functions #9551
- permGroup reports failure properly and listRemove removes consecutive duplicates #9550
- cap the length of inserted text like echoed text #9497
- ttsGetQueue out-of-bounds read and ttsClearQueue message #9471
- prevent a rare crash while saving a profile that uses modules #9559
- crash when a button uninstalls its own package #9558
- stop crashes while saving and profiles losing their triggers #9557
- replacing a temp item's script no longer keeps running the old function callback #9496
- clearing the screen no longer loses the last line from the log #9486
- variables added while playing are no longer lost when saving #9492
- highlight triggers no longer stop later color triggers from matching #9425
- getNamedTriggers no longer drops names when trigger types are mixed #9549
- replacing the game GUI download dialog no longer cancels the new download #9519
- scaleMovie collateral disconnect, isAnsi*Color returns, scrolling messages #9474
- colon-form underline styles now match other terminals #9498
- memory leak when perm* functions receive invalid Lua code #9556
- caret-mode Shift+Arrow selection off-by-one and Ctrl+C copy #9393
- bold text no longer brings back a colour the game already reset #9515
- exporting a package no longer destroys an existing file when you decline to overwrite #9495
- restarting to apply an update no longer leaves a second Mudlet running #9487
- harden the TLS-upgrade question against reconnects and profile closure #9518
- log no longer duplicates a line when logging is restarted #9490
- mapper API error reporting for getMapEvents and addRoom #9473
- color triggers now work inside 'only pass matches' trigger groups #9442
- triggers created by other triggers react to the current line again #9458
- flag invalid aliases and block loops while typing them #9499
- tempAnsiColorTrigger can match background colour only #9494
- MXP text now shows correctly on non-English games #9491
- non-English game text no longer garbles after a stray "&" #9489
- script output no longer breaks the game's colour and control codes #9485
- character-at-a-time warning misfires on password prompts #9391
- apply Discord API permission gating consistently #9472
- searchRoom returns nil+message for a missing roomID #9467
- tempButton and tempButtonToolbar return the created ID #9470
- remove duplicate cechoLink/dechoLink/hechoLink in GeyserMiniConsole #9477
- profile reset no longer forgets which variables to save #9484
- notepad arrows now visible in dark mode #9488
- align getTimestamp, getModulePriority, getModulePath failure returns #9480
- guard sendMSDP against disconnected/unnegotiated state #9478
- stop a malicious game from writing files outside the media folder #9504
- show connection details when picking a game on a fresh install #9451
- game information sent via MXP is no longer all-lowercase #9447
- 200 byte leak when loading a map #9464
- cap telnet subnegotiation length to bound memory use #9440
- recover from corrupt MCCP compression and stop losing data #9441
- stray ESC sequence no longer corrupts later text #9436
- script editor's info banner no longer glares in dark mode #9414
- script editor's search box no longer jumps around #9444
- keep non-ASCII characters in MXP custom entities #9439
- enforce the per-echo character limit #9438
- colon-form italic styling no longer corrupts underline #9437
- cap over-long escape sequences to bound memory use #9435
- hidden terminal control sequences no longer show up as text #9433
- certificate warnings now open settings for the right profile #9432
- package description images now work for packages with spaces in their name #9431
- tempAnsiColorTrigger now runs function callbacks #9427
- pasting several copied items now works for every item type #9423
- Variables view handles decimal numbers and true/false keys properly #9422
- editor copy/paste works after scripts create triggers or aliases #9421
- debug console shows its black background again #9419
- certificate warnings are now readable in dark mode #9418
- Copy button no longer oversized on the connection screen #9417
- main display no longer leaves a blank strip when the top border shrinks #9413
- word wrap changed by scripts now shows correctly in Preferences #9410
- clicking into the main window no longer steals copy from the command line #9305
- no more crash when viewing Variables after resetting a profile #9430
- deleting lines in triggers no longer corrupts the log file #9429
- save new modules to the location you choose #9424
- alias patterns no longer break after editing them #9420
- trigger editor's extra-options arrow is now visible in dark mode #9412
- Windows crash reports now show the actual cause #9370
- line-initial underscores no longer clipped at certain font sizes (regression of #7866) #9288
- updater not running on close, showing empty changelog #9388
- prevent crash from a trigger that endlessly feeds itself #9368
- variable editor keeps new variables nested in their parent table #9285
- trigger multi-line attribute resets when adding a sibling trigger #9284
- crash when a package uninstalls itself from its own alias/key/tr… #9383
- don't load a map if trying to create a mapper & map is already loaded #9415
- apply map label edits immediately in label preview #9387
- shrink preferences dialog to fit on 1377x768 screen #9407
- keep saved profile passwords working on Windows after qtkeychain library update #9395
- clickable links could show the wrong colours and styling after heavy output #9406
- add missing dictionary name #9400
- resize command line box for appendCmdLine/printCmdLine/clearCmdLine #9301
- console text not redrawing after resizing the window #9369
- editor keeps its maximized/full-screen state when toggled back to #9303
- fix two tests still opting in with an empty XDG config dir #9810
- keep QTest's output visible when ctest runs on Windows #9751
- a media player no longer announces its own destruction #9746
- fix Windows CI losing the per-user luarocks tree #9752
- keep the profile-removal file list from going stale #9739
- Bump lukka/get-cmake from 4.4.0 to 4.4.2 #9729
- tidy up how CI installs Lua #9734
- Update autocompletion data in Mudlet #9720
- Bump 3rdparty/sentry-native from - Bump 3rdparty/edbee-lib from - Bump github/codeql-action from 4.37.3 to 4.37.6 #9730
- reject a release tag that does not match APP_VERSION #9701
- move module documents into their write jobs instead of copying #9699
- leak checking now gates the functional tests #9694
- Update text for translation in Crowdin #9718
- trim the comments left behind by two merged QA fixes #9708
- trim the comments around the experienced-player gate #9707
- assign milestones with the built-in token, not a PAT #9696
- fix milestone assignment, unbreak the key sequence tests #9679
- take re-entrancy depth counts off with scope guards #9687
- MMCP effect specs against a scripted chat peer #9629
- busted specs for the Geyser widget classes with no spec home #9665
- package and module lifecycle specs with a committed fixture kit #9632
- Discord effect specs against a fake Discord IPC server #9631
- cover the untested lua-lib surface #9630
- check mpackage archives match their sources #9624
- cut PR CI matrix in half and fix build flakes #9618
- make windows safe to destroy while a field has the text cursor #9596
- stop suppressing QString leaks in LSan enforcement #9602
- ignore multiple build targets #9562
- real-firing timer and script family Lua API tests #9572
- deepen the Geyser specs after test-coverage review
- address review of the Geyser specs
- Geyser geometry and visibility tests
- keep the HTTP fixtures byte-exact, harden the Windows step
- run the HTTP fixture server on Windows CI
- fix Windows media path assert, spare the media cache
- download, HTTP, media and TTS effect tests
- move media and TTS specs into Media_spec.lua
- drop attempt cap in setFont round-trip test
- window and label geometry/visibility Lua API tests
- document the LSan tracer-crash CI flake #9592
- decouple the mapper engine from UI dialogs #9513
- decouple profile management (Host) from UI dialogs #9514
- bump github/codeql-action from 4 to 4.37.3 #9565
- bump 3rdparty/sentry-native from - Update text for translation in Crowdin #9563
- document un-suppressible CI leak flakes #9561
- networking, MMCP, media and Discord API contract tests #9535
- replace test mocks with real API assertions; config, stopwatch and utils tests #9534
- database and datetime Lua API tests #9531
- add waitForEvent test helper for async Lua API tests #9527
- mock TTS engine and local HTTP server for tests #9529
- extensive mapper Lua API tests #9530
- ignore speech-dispatcher's one-time startup leak in leak detection #9521
- release resources in test fixture destructors #9522
- resolve CodeQL warnings in the telnet code #9523
- guard functional-test lookups with QVERIFY #9524
- clear 5 CodeQL warning-level alerts in src/ #9525
- re-enable Sentry crash reporting on PTB builds #9553
- survive xorg.freedesktop.org certificate expiry in CI #9554
- clean vestigial widget includes from the Lua engine files #9526
- trigger, alias, key and named-timer Lua API tests #9532
- UI text output and readback Lua API tests #9533
- decouple profile export and media playback from UI widgets #9512
- add performance baseline benchmark for the text and trigger pipeline #9509
- add Discord IPC server stub for end-to-end tests #9475
- harden the Widgets audit script and refresh its baseline #9516
- slim down the AI assistant instructions #9511
- harden the build for the minimum supported Qt version #9510
- add Qt Widgets dependency audit for the core library #9508
- decouple telnet engine from UI dialogs #9507
- use std::chrono literals for time durations #9493
- remove unregistered setMiniConsoleFontSize implementation #9479
- add profile and map save/load round-trip tests #9468
- Bump 3rdparty/sentry-native from - Update sanitizers.cmake to latest upstream #9503
- Update text for translation in Crowdin #9502
- document how to record before & after demo videos #9482
- test suites no longer clash when run at the same time #9483
- stop known ASan leak noise failing the password migration test #9461
- memory leaks found during CI tests now fail the build #9481
- fix else-after-return in codebase #9096
- Bump actions/setup-node from 6 to 7 #9457
- Bump lukka/get-cmake from 4.3.4 to 4.4.0 #9456
- Update text for translation in Crowdin #9360
- PTBs shipping without all platforms' installers #9389
- add Mudlet lua files to those shown by Qt Creator #9409
- Bump 3rdparty/qtkeychain from - Bump 3rdparty/sentry-native from - merge release-4.22 back into development #9386
Full changelog since last release (Mudlet-4.22.0)
Added:
Improved:
Fixed:
Infrastructure:
a99d64e to a185ce8 #9727
a3ae51b to 62ca709 #9728
a182754 to a99d64e #9564
0f7802f to a182754 #9505
7718d0a to 875f77d #9399
fea16b8 to 0f7802f #9398