github Mudlet/Mudlet Mudlet-4.22.0-ptb-2026-08-17-b9e597b3
Public Test Build

pre-release6 hours ago

Changes since last PTB (Mudlet-4.22.0-ptb-2026-08-16-44d23ebf)

Improved:

- undoing the game's own wrapping is marked experimental, and no longer advertised #9873

- text throughput by not rewrapping lines that already fit #9928

Fixed:

- profile saves no longer leak Lua stack slots #9895

- A damaged trigger no longer crashes Mudlet while the profile loads #9884

- the starter UI's chat window no longer makes captured lines expensive #9962

- Undoing the game's word wrapping no longer merges separate sentences #9872

- Crash when an update download is requested twice in quick succession #9948

- Rare crash if a profile closes while an MXP tag is stalled #9946

- Crash on macOS 12 shortly after startup #9945

- keep the selected room when right-clicking elsewhere on the map #9932

- a game that cannot be reached now says so, instead of nothing at all #9914

- three first-screen defects in the connection dialog #9894

- triggers no longer act on the wrong line after another trigger feeds text #9898

- hidden control codes no longer leave stray characters in the game's text #9901

- New variables no longer occasionally vanish from the variable editor and profile saves #9944

- Windows CI builds again after an msys2 update broke Lua module installs #9963

- games offering several character sets no longer knock a profile out of UTF-8 #9861

Infrastructure:

- spec the multiline trigger behaviour that does not need a functional test #9943

- Auto-setup build environment for Claude Code web sessions #9931

Full changelog since last release (Mudlet-4.22.0)
Added:

- drag the starter UI's map and chat anywhere too #9863

- drag the starter UI's health bars anywhere you like #9840

- PhoenixMUD #9874

- adjustable containers can be dragged out of their parent #9850

- 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

Improved:

- undoing the game's own wrapping is marked experimental, and no longer advertised #9873

- text throughput by not rewrapping lines that already fit #9928

- text and trigger throughput, and a CSI sequence that read freed memory #9916

- moving or resizing a Geyser layout no longer lays it out several times over #9919

- the ISO 8859-1 decoder no longer allocates a string for every character #9856

- base UI captures your gossips in its chat window #9838

- "Copy as image" now works without selecting text first #9738

- 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

Fixed:

- profile saves no longer leak Lua stack slots #9895

- A damaged trigger no longer crashes Mudlet while the profile loads #9884

- the starter UI's chat window no longer makes captured lines expensive #9962

- Undoing the game's word wrapping no longer merges separate sentences #9872

- Crash when an update download is requested twice in quick succession #9948

- Rare crash if a profile closes while an MXP tag is stalled #9946

- Crash on macOS 12 shortly after startup #9945

- keep the selected room when right-clicking elsewhere on the map #9932

- a game that cannot be reached now says so, instead of nothing at all #9914

- three first-screen defects in the connection dialog #9894

- triggers no longer act on the wrong line after another trigger feeds text #9898

- hidden control codes no longer leave stray characters in the game's text #9901

- New variables no longer occasionally vanish from the variable editor and profile saves #9944

- Windows CI builds again after an msys2 update broke Lua module installs #9963

- games offering several character sets no longer knock a profile out of UTF-8 #9861

- Mudlet no longer crashes when a multiline trigger's script feeds text back #9897

- Quitting a testing build no longer ends in a LeakSanitizer error #9930

- Music stopped with a fade-away right after it starts no longer plays on #9907

- a script connecting while the profile is still connecting no longer leaves it connected to nothing #9896

- replaceAll() replaces the wrong characters when a line has accents #9906

- the Carrion Fields loader no longer fails silently or re-downloads on every reconnect #9921

- the Variables editor no longer creates a junk copy of a variable it cannot name exactly #9908

- a profile save no longer blanks, drops or inflates saved variables #9892

- update notes no longer skip releases your platform never got #9891

- a killed alias, key binding or timer can come back to life and fire again #9888

- Geyser elements asked to start hidden no longer appear on screen #9883

- copying text no longer grabs an extra character or re-wraps the line per character #9855

- sharing an area from the generic mapper now carries its room hashes #9364

- a trigger with a blank pattern before a real one silently never matches #9851

- building a map from a script no longer slows to a crawl as it grows #9763

- the last line of a paragraph no longer goes missing when undoing game wrapping #9859

- reconnecting a profile to a different game no longer carries the last game's protocols over #9773

- pasted text goes in at the cursor, not at the start of the line #9871

- saved variables holding functions come back empty again instead of half-filled #9860

- game text no longer breaks into one character per line with GA forced off #9858

- Mudlet no longer copies the whole screen an extra time on every repaint #9854

- exact-match triggers no longer copy every line they check #9853

- trigger matching no longer allocates memory for every pattern on every line #9852

- a queued quit no longer runs from inside a profile save #9813

- Mudlet no longer crashes when adding an event handler after switching scripts #9839

- undoing the game's line wrapping no longer merges list entries #9836

- delete old maps/modules doing nothing when there is no backup folder #9849

- profile saves silently dropping saved variables that a second global references #9762

- preloading a sound no longer plays it, and IRC settings stop losing your password #9817

- three Lua API bugs the core specs found - command history, phantom profiles, package names #9816

- seven Lua library and mapper bugs found while speccing them #9815

- db:create crashing on a single column name as _index #9799

- gauges no longer make every line of game text expensive #9766

- a stray escape code no longer silences your game for the rest of the session #9765

- brand-new installs get the new-player experience again #9745

- deleting a big Geyser layout no longer freezes Mudlet #9760

- notepad, IRC client and toolbars outliving their profile #9706

- 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

Infrastructure:

- spec the multiline trigger behaviour that does not need a functional test #9943

- Auto-setup build environment for Claude Code web sessions #9931

- link the Linux CI builds with mold #9927

- Guide AI assistants to prefer Lua specs over C++ functional tests #9925

- test the guard that keeps a cleared shortcut from swallowing every key #9886

- MXP frame placement test no longer depends on the startup window size #9876

- stop the development ccache from going stale #9905

- Bump 3rdparty/sentry-native from a185ce8 to 724479b #9899

- Bump 3rdparty/edbee-lib from a3ae51b to 9a91551 #9900

- give the undo-server-wrap tests a known starting buffer #9866

- document the xdotool no-op drag-step trap in the video workflow #9870

- retry the LeakSanitizer tracer crash instead of failing the leak job #9812

- Update text for translation in Crowdin #9875

- stop the telnet test stub losing data sent before a client connects #9862

- Add CMake presets for every platform, and one home for AI assistant skills #9742

- fix the main window restore baseline the map dock invalidates #9828

- fix a test running against the real config dir, and guard the recipe #9811

- Add tests for the core and misc Lua functions that had none #9802

- Add functional tests for the profile lifecycle Lua API #9776

- busted specs for the last uncovered UI functions #9775

- busted specs for the last uncovered lua-lib functions #9774

- test coverage for the IRC configuration and media playback APIs #9772

- rename the six tests Windows refuses to launch without elevation #9753

- drop comments that restate the code beside them #9681

- 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 a99d64e to a185ce8 #9727

- Bump 3rdparty/edbee-lib from a3ae51b to 62ca709 #9728

- 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 a182754 to a99d64e #9564

- 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 0f7802f to a182754 #9505

- 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 7718d0a to 875f77d #9399

- Bump 3rdparty/sentry-native from fea16b8 to 0f7802f #9398

- merge release-4.22 back into development #9386

Don't miss a new Mudlet release

NewReleases is sending notifications on new releases.