#### Brief overview of PR changes/additions
- Stop importing settings from the pre-4.19 NativeFormat store (macOS
plists / Windows registry) into a freshly created Mudlet.ini
- On those platforms the old store ignores HOME/XDG overrides, so any
machine that ever ran Mudlet <= 4.18 made every fresh install inherit
stale keys and classify as an experienced player - skipping the starter
UI, tour and hints, and failing two functional tests
- Add tripwire asserts so any future write into a fresh Mudlet.ini
before init() fails with a self-explaining message
#### Motivation for adding to Mudlet
A fresh install must be recognised as a new player; anyone who ran 4.19+
was already migrated, and a direct <= 4.18 upgrade only loses UI
preferences (window geometry, appearance, storePasswordsSecurely,
deletedDefaultMuds), never profiles.
#### Other info (issues closed, discussion etc)
Fixes#9741
**Test case:** ExperiencedPlayerGateTest (18/18) and DefaultPackagesTest
(28/28) pass; on a Mac that ran Mudlet <= 4.18 (check with `defaults
read com.mudlet.Mudlet pos`), both suites now pass and a fresh profile
gets the starter UI.
Assisted-by: Claude:claude-opus-5
#### Brief overview of PR changes/additions
- Comment-only follow-up to #9695 "fix: stop treating long-time Mudlet
users as brand new players" - no code line changes at all.
- Removes every passage describing what the gate used to do; git history
and the #9695 body carry that, and in source it goes stale the moment
someone touches the line.
- Cuts what remains to the constraints a reader cannot derive from the
code: the `init()` ordering requirement, why no filesystem timestamp can
substitute for the recorded date, and why the fallback deliberately errs
towards 'experienced'.
#### Motivation for adding to Mudlet
Applies the house comment standard to code that landed a few hours
earlier: 112 comment lines out, 33 shorter ones in.
#### Other info (issues closed, discussion etc)
Test names carry the intent in `ExperiencedPlayerGateTest`, so
per-assertion narration went; the `QVERIFY2` failure messages already
say what each case is asserting. What was kept there: the permissions
restore-before-assert ordering, the `$XDG_CONFIG_HOME/mudlet` opt-in
marker, and the note that the live-singleton case must run last because
`experiencedMudletPlayer()` memoises.
**Test case:** `ctest --output-on-failure` - 79/79, unchanged.
Assisted-by: Claude:claude-opus-5
#### Brief overview of PR changes/additions
- `experiencedMudletPlayer()` decided veteran status from profile
**directory** mtimes. The per-profile data writes (url, port, password,
`profile.ini`, command history) all land straight in that directory and
bump its mtime every session, so only a profile *abandoned* for six
months ever looked old - the more you use Mudlet, the more certainly it
called you new. All 13 profiles on the maintainer's machine classified
as "brand new player".
- Mudlet renewed those timestamps itself: the connection dialog rewrites
`url`/`port`/`description` for the selected profile at startup, so
merely launching Mudlet reset the value the gate read.
- Replaced with a `firstLaunchDate` key recorded in QSettings on a
genuinely fresh install (written in `init()`, before anything can create
a profile or save a setting). An installation with any trace of earlier
use - a profile, or any other setting already on file - has no
recoverable start date and is treated as experienced; timestamps cannot
recover one, since a copied or restored profile keeps its modification
times only if the tool used happened to preserve them, and loses its
birth time regardless.
#### Motivation for adding to Mudlet
In 4.22.0 this gate only suppressed three one-line hints, but 5.0 hung
the full-window "Welcome to Mudlet! New here?" tour (#9385, 69d7d4169
"Add: UI tour to complement the Mudlet tutorial") and the starter UI
package (#9454, 69cd06b1c "add: starter interface with health bars, map
and chat for new players") off it, so essentially every active 4.22.0
user upgrading to 5.0 would get a beginner tour dropped on top of their
session.
#### Other info (issues closed, discussion etc)
The heuristic dates back to ae0564e6e "Improve: revise splitscreen
tutorial (try 2)" (#7341); the two 5.0 consumers above are what turned
it into a release blocker. New `ExperiencedPlayerGateTest` (18 cases)
covers fresh install, upgrader with freshly-written profiles, settings
restored without profiles, the six-month boundary, a profile restored
from backup, future-dated, unparseable and unwritable records, and two
live-singleton cases that pin the `init()` call site and the memoised
read. Both directions were mutation-tested: dropping the `init()` call
and restoring the old mtime heuristic each fail the suite. When in doubt
the gate errs towards *experienced* - a veteran shown a new-user tour is
a much worse outcome than a newcomer who misses it.
**Test case:** Seed a HOME that looks like an existing user (one
profile, `Mudlet.ini` without `uiTourShown`), launch Mudlet and connect
- before, the 6-step "Welcome to Mudlet!" tour appears; after, it does
not. A HOME whose `Mudlet.ini` has a recent `firstLaunchDate` still gets
the tour, and a genuinely empty HOME records one.
Assisted-by: Claude:claude-opus-5
#### Brief overview of PR changes/additions
- Every package Mudlet preinstalls now lives in `src/packages/<name>/`,
holding its `config.lua`, `.xml` and the `.mpackage` built from them -
previously they were scattered across `src/` and `src/mudlet-lua/lua/`,
and four had no metadata at all.
- The game loaders (Carrion Fields, Icesus, MorgenGrauen, Medievia) and
the two `mudlet.org` dev packages shipped as bare xml, so the Package
Manager showed them with no version, author or description. They are
packaged now, keeping their existing package names so nothing renames on
upgrade.
- New `DefaultPackagesTest` walks the preinstall table for seven games,
checks every queued path is really compiled in, and installs all 15
archives.
#### Motivation for adding to Mudlet
An mpackage carries Mudlet's metadata and a bare xml cannot. Keeping
each package's sources next to its archive also makes the Lua reviewable
in diffs, which a committed zip on its own is not.
#### Other info
Stacked on #9624, whose check now covers all 15 packages. The IRE mapper
stays an xml because upstream publishes it that way and
`update-3rdparty.yml` overwrites it weekly. Package repository PR
Mudlet/mudlet-package-repository#746 updates the sync paths and must
merge right after this.
#### Test case
`ctest` 66/67 locally (`TKeySequenceEditTest` is the known headless
flake - passes under openbox); `DefaultPackagesTest` 28/28; `python3
CI/check-mpackage-sync.py --base-ref origin/development` clean.
Assisted-by: Claude:claude-opus-5
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>