Skip to content

Add: Experiments section in profile preferences - #11946

Open
vadi2 wants to merge 6 commits into
developmentfrom
claude/experiments-settings-ui
Open

vadi2 wants to merge 6 commits into
developmentfrom
claude/experiments-settings-ui

Conversation

@vadi2

@vadi2 vadi2 commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Brief overview of PR changes/additions

Adds an Experiments (unsupported) card to the Advanced page of profile preferences. It has one checkbox for each experiment in the profile's whitelist (Host::mValidExperiments), so scripts no longer have to call setConfig("experiment....", true) to try one.

  • List source: the card is built from the Host's whitelist, now returned sorted by Host::getValidExperiments(). Each known experiment gets a translatable label and description (with //: translator comments). An experiment without a label still shows up under its raw key. Every checkbox's tooltip shows the key scripts use.
  • Group rules: the dialog uses the same grouping as Host. That grouping is now one static helper, Host::experimentGroup(), which setExperimentEnabled() also uses.
    • Ticking experiment.rendering.originalish unticks experiment.rendering.more-transparent and vice versa. The description says so ("Turning this on turns off: ...").
    • experiment.3dmap.modernmapper and experiment.3d-player-icon are in different groups, so both can be on.
  • Applying changes: toggles go through the dialog's existing instant-apply path into Host::setExperimentEnabled(). The 3D view swap that setConfig() used to do for the modern mapper now lives in Host::setExperimentEnabled(). It runs the same way whether the change comes from Lua, from the dialog, or from a profile/package import. The swap is a no-op unless a 3D view is open on the other renderer.
  • Sync with Lua: the dialog re-reads the experiments when it is re-activated, like the other live-synced settings. A setConfig() from a script while the dialog is open shows up when you return to the dialog.
  • Builds without the 3D mapper: every current experiment only affects the 3D map. Builds without INCLUDE_3DMAPPER (e.g. the linux-lowspec preset) hide the card, and search skips it.

Motivation for adding to Mudlet

Experiments could only be switched on from a script. That made it hard for players to find them and try them out, and we want people to test the new 3D mapper.

Screenshots

The new card on Preferences → Advanced, with every experiment off:

Experiments card with every box unticked

"Modern 3D mapper" and "Original level shading" ticked. Each description in the rendering group names the experiment it turns off:

Experiments card with Modern 3D mapper and Original level shading ticked

The 3D map on the modern renderer right after ticking "Modern 3D mapper" in the dialog (taken headless on Xvfb, cropped to the 3D scene):

Modern 3D map after ticking the box in the dialog

Other info (issues closed, discussion etc)

Persistence: no new mechanism was added. Experiments are already saved with the profile: XMLexport writes <experiment key="..." enabled="yes"/> and XMLimport reads them back through setExperimentEnabled(). Storing them anywhere else (e.g. the global Mudlet.ini) would have created a second source of truth, out of step with the profile-scoped Lua API. The new test test_aTickedExperimentIsSavedWithTheProfileAndReadBack ticks an experiment in the dialog, saves the profile, and checks the saved XML. It then clears the experiment and loads the XML back to confirm the experiment returns.

Tests:

  • New ctest case: SettingsExperimentsTest, added to the existing functional_settings_tests group (no new binary). It covers:
    • one labelled checkbox per whitelisted experiment on the Advanced page
    • a script toggle shows in the dialog
    • a tick switches the experiment on the Host
    • group exclusivity
    • two experiments from different groups both stay on
    • the save/load round trip
    • ticking the modern mapper swaps an open (hidden) 3D view to the modern renderer, and unticking swaps it back
    • Result: 9/9 on offscreen. Before the dialog change, 6 of the original 8 cases fail. A mutation of the group-exclusivity handler is caught. The renderer-swap case fails when the recreate3DView() call is removed. It keeps the map dock hidden so no GL context is created, which the leak-detection job requires.
  • Lua specs in Other_spec.lua:
    • The sorted experiment list from getConfig() (fails on development).
    • A guard that the modern mapper and the player icon can both be on.
    • Result: 6217/0.
  • Full ctest: passes, apart from CommandLineSpellCheckTest, which fails on this machine only because no en_US dictionary is available in the build dir.
  • Manual check, headless on Xvfb with a demo map:
    • With the legacy 3D view open, ticking "Modern 3D mapper" in the dialog switched to the modern renderer.
    • setConfig("experiment.3dmap.modernmapper", false) switched it back.
    • Installing a host package with the experiment on, while the 3D view was open, swapped renderers without a crash.

The DCO sign-off from the human maintainer is still pending: they will add Signed-off-by after building and testing the change themselves.

Test case: open a profile, then Preferences → Advanced → "Experiments (unsupported)". Open the 3D map and tick "Modern 3D mapper": the 3D view switches renderer. Run lua setConfig("experiment.3dmap.modernmapper", false) and return to the dialog: the box is unticked. Tick "Original level shading" and then "Darken other levels": the first one unticks. Save and reopen the profile: the ticked experiments are still on.

Assisted-by: Claude:Opus 5.5

🤖 Generated with Claude Code

https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ


Generated by Claude Code

The Advanced settings page gets an "Experiments (unsupported)" card with one
checkbox per experiment the Host accepts, built from Host's whitelist so a
newly whitelisted experiment shows up with no UI work. Each has a translated
label and description, falling back to its key, and a tooltip naming the key
scripts pass to setConfig().

The dialog uses Host::experimentGroup(), the same rule setExperimentEnabled()
applies, so ticking one member of a group unticks the others, while the
modern mapper and the 3D player marker (different groups) can both be on.
Toggles go through Host::setExperimentEnabled(), and the 3D view swap for
the modern mapper moves from setConfig() into Host so both routes get it.
The card refreshes from the Host whenever the dialog is activated, so an
experiment switched by a script shows up there.

Experiments already persist per profile through the profile XML; the new
functional test proves the round trip for one ticked in the dialog.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
Every experiment so far only changes the modern 3D map, so a build made
without it would offer five checkboxes that do nothing.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
Also say what the experiments spec actually covers: Host, not the dialog.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
@vadi2
vadi2 requested a review from a team as a code owner October 11, 2026 16:11
@add-deployment-links

add-deployment-links Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Hey there! Thanks for helping Mudlet improve. 🌟

Test versions

You can directly test the changes here:

No need to install anything - just unzip and run.
Let us know if it works well, and if it doesn't, please give details.

@greptile-apps

greptile-apps Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Retrigger

[Medium impact] Adds experiments UI to profile preferences with mutual exclusion logic.

The PR appears safe to merge, with a non-blocking gap in tests for renderer switching.

Reviews (1) · Last reviewed commit: "Use range-based loops over the experimen..." · Reviewed by Greptile

Comment thread test/functional_tests/SettingsExperimentsTest.cpp
vadi2 pushed a commit that referenced this pull request Oct 11, 2026
Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ

vadi2 commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

Before/after demo, recorded headless (Xvfb) with a demo map open in the 3D view (30 s):

  • Before (development): Preferences > Advanced has no way to switch experiments on.
  • After (this PR):
    1. The Advanced page shows the "Experiments (unsupported)" card.
    2. Ticking "Modern 3D mapper" swaps the open 3D map to the new renderer, and unticking it brings back the original one.
    3. A script's setConfig('experiment.3dmap.modernmapper', true) also shows up as a tick when you reopen the dialog.

Video: pr11946-experiments-settings.mp4 (raw)


Generated by Claude Code

Opens the legacy 3D view, ticks and unticks "Modern 3D mapper" in the
dialog, and checks the view's renderer class after each change. It fails
with the recreate3DView() call in Host::setExperimentEnabled() stubbed
out. Telling the classes apart needs no GL context, so it runs under
ctest's offscreen platform.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
@github-actions github-actions Bot added this to the 5.1.0 next release milestone Oct 11, 2026
Shown, each QOpenGLWidget tries to make a GL context, and on the leak
job's offscreen platform the contexts from those failed attempts are
reported by LeakSanitizer - the case asan-suppressions.txt asks tests to
avoid. The view now lives in a hidden map dock: the swap still happens
and is still checked, and no context is ever constructed (0 against 8
before, counted with a breakpoint on QOpenGLContext's constructor).

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ

vadi2 commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

The macos (arm64) / c++, lua tests failure on dbcae84 (job 114531609346) is not from this PR. The only failing case is MainWindowSizeReportTest::test_aUserWindowDockedBesideAnotherGetsAShareOfTheArea ("the second user window is 0 high beside the first's 740"), at 294/295 ctest cases.

I'm re-running the failed job once.


Generated by Claude Code

Resolve the setConfig() conflict: development added an
update3DViewAvailability() call next to the recreate3DView() call that
this branch moved into Host::setExperimentEnabled(). It moves there too,
so a map window's 3D button follows the renderer whether the change
comes from Lua, the preferences dialog or a profile import. Drop the
TMapViewsFrontend.h include from TLuaInterpreter.cpp, which only that
block used.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
vadi2 pushed a commit that referenced this pull request Oct 12, 2026
The Experiments card on the Advanced page with every box unticked, the
same card with "Modern 3D mapper" and "Original level shading" ticked,
and the 3D map on the modern renderer right after ticking the box.

Assisted-by: Claude:Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NL8qdhrqWbWpL59XwmN6pJ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants