Changelog
What changed in AO Launcher and on the game server. Discuss it on our Discord.
AO Launcher
- v0.1.133
Launcher 0.1.133 updates the canonical public endpoints to muthur.us.in and luna.muthur.us.in, while automatically migrating saved profiles from the retired emeraldsolitaire.com host. This release includes the current x86 shim and is signed with the established updater key.\n\nVerification: verification-0.1.133.json passed locally for the NSIS installer, MSI, embedded shim, PE architectures, signatures, and updater manifest.
- v0.1.132
Other players now hear your gun click when it is empty, as in the original game (#845, #862).
- The original game clicked only for you. The launcher now tells the server, which plays the click at your position for everyone else in the mission.
- To turn it off, set
report_empty_clicks=0under[debug]inddraw_debug.ini.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.131
The Available Sectors list reads "Alpha Sector (Online)" in green, with the number of players online right now (#813, #814).
- The game no longer draws the selected sector in red. To restore the original red, set
green_selected_sector=0under[debug]inddraw_debug.ini. - The "(Online)" text and the more accurate player count come from the server and are already live for every launcher version.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- The game no longer draws the selected sector in red. To restore the original red, set
- v0.1.130
The mouse stays inside the game. In every display mode the pointer now stays on the game's screen, so it can't slip onto another monitor or the desktop mid-game.
- Press F10 in the game to free the pointer (for example to drag the window), and F10 again to capture it.
- Alt+Tab, minimizing and game dialogs free it automatically.
- To turn it off, untick Keep the mouse inside the game under the launcher's Advanced settings.
- The key can be changed with
release_cursor_keyinddraw_debug.ininext toaliens.exe.
Otherwise the same as v0.1.129 (the native client can pick up the server's Retrieval Core).
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.129
Retrieval missions: the game client can now pick up the server-spawned Retrieval Core. This is inactive until the matching server change ships; nothing else changes in play.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.128
Your password no longer travels to the game server. The original game sends its login without encryption. The launcher now signs in to ao-web over HTTPS and hands the game a short-lived key (one day; revoked by a password change) instead of your password.
Fewer startup connection errors. New launcher profiles turn on Advanced → Delay first sends to avoid connect errors by default, which prevents "WinSock error 10057" on slower connections. Existing profiles keep their saved choice.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.127
Fixes lifts and doors that played their sound but didn't move (#608, PR #609).
What changed
- Slow lifts and doors move again at any frame rate. The game moves each lift and door by a whole number of units per frame and drops the fraction. At 60 fps a slow one dropped all of it and never moved. That's the LV-426B lift into the vents from the front entrance, and two slow doors on another map. The launcher now carries the leftover fraction from frame to frame, so every lift and door moves at its designed speed.
- Missions run at 60 fps by default, and 60 is now the most. A higher
target_fpssetting is lowered to 60, because the same rounding affects other movement and timers at higher frame rates.target_fps=0still gives the original 50 fps. - The opt-in elevator diagnostic now logs your real height.
If a lift or door misbehaves: set
carry_trigger_steps=0inddraw_debug.ini(next toaliens.exe) to turn the fix off, and tell us on Discord.Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.126
Test release for the LV-426B elevator that plays its sound but doesn't move. It adds an opt-in diagnostic and changes nothing in the game unless you turn it on. Otherwise identical to v0.1.125.
How to help:
- In AO Launcher, open Advanced and tick Log elevator diagnostics (for bug reports).
- Play LV-426B as a Marine and go to the elevator you saw fail: from the front entrance, take a right into the first room (the lift up into the vents). Press it a few times.
- Close the game and send
ao_shim.logfrom the folder withaliens.exe. Also mention yourtarget_fpsfromddraw_debug.iniif you changed it. - Untick the box afterwards.
The log gets one
ElevatorDiag:line per elevator change, with its height, speed, the game's frame time and the movement per frame. ASTALLEDline marks an elevator that is "moving" without its height changing.Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.125
Fixes a crash when clicking an empty character slot, or any slot other than the last one used. The game saves its settings through a temporary file, which it tried to create in the root of the drive; Windows doesn't let ordinary programs create files there, so the game crashed. The shim now puts that file in the game folder (#597, #598). Otherwise identical to v0.1.124.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.124
New
- After a disconnect the game no longer shows the blocking "Lost TCP connection" popup (PR #587 by kejek). Its own disconnect handling, chat-log line, disconnect screen and ESC exit are unchanged. Other Host Messages still appear.
- Builds on v0.1.123, which stopped the stream of WinSock error dialogs after a disconnect.
verify_release.pyPASSED (signatures, embedded x86 shim, PE architectures, versions, MSI, latest.json).Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.123
New
- After a disconnect the game stops sending into the dead connection, so you no longer get a stream of WinSock error dialogs (#487, PR #562 by kejek, revised in review). One disconnect notice, then ESC exits.
- Hand grenades report their impact and splash radius again, so thrown-grenade kills are credited.
Also carries the unpublished drafts' changes
- v0.1.119: Windowed Fullscreen mouse no longer boxed into the top-left.
- v0.1.120: wedged AI Aliens moved to open floor.
- v0.1.122: Marines leave a finished match for the debrief by themselves (#488/#502).
verify_release.pyPASSED (signatures, embedded x86 shim, PE architectures, versions, MSI, latest.json). Native acceptance pending before publishing.Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.121
v0.1.118 plus #458: closed doors hide players again with full-resolution rays, and you can walk through dead Aliens and fallen Marines (passable_bodies=0 restores blocking). NSIS installer only this release (the MSI step failed on the build VM; the updater uses NSIS). Does not include the unpublished v0.1.119/v0.1.120 drafts.
Known limitations: https://ao.emeraldsolitaire.com/known-limitations
- v0.1.118
Chasing AI Aliens now step round barrels and other small objects instead of stalling behind them, and an Alien stuck in one spot for two seconds turns onto a new course (unstick_aliens, on by default; set it to 0 in ddraw_debug.ini for the original behaviour). Everything else is v0.1.117.
Draft: built and signed on Midgit's workstation; verify_release.py PASSED (verification-0.1.118.json). Native acceptance pending.
- v0.1.117
Shotgun, FlameThrower and SmartGun impact marks fade from walls again, as in the original game. Since v0.1.114 the kept-corpses feature mistook those projectiles for Aliens and left their marks forever; dead Aliens and Alien players still stay on the floor (keep_alien_corpses). Everything else is v0.1.116.
Draft: built and signed on Midgit's workstation; verify_release.py PASSED (verification-0.1.117.json). Native acceptance pending.
- v0.1.116
AO Launcher v0.1.116
This release includes Tim/Midgit's per-key
ddraw_debug.inihandling. Missing keys now use his requested settings (60 FPS, frame-rate logging, torso alignment, precise and full-resolution rays, filtered walls, and free mouse look), while explicit player values remain unchanged.The Windows NSIS and MSI installers were built from the committed source, signed with the existing updater key, and verified with
ao-launcher/tools/verify_release.py. Native gameplay acceptance remains a separate test track.
Game server
feat(luna): expose server-fed mission settlement details
fix(luna): validate authored enhanced movement rules (Luna 8.9)
Native empty gun click reaches other players
The original client plays an empty trigger pull's click locally and sends nothing. Shim InstallEmptyClickReport (report_empty_clicks, default 1) hooks HandleWeaponFireAction (0x459e90): a call that returns 0 and sets the refire timer to 300 ms is the empty pull, and the shim queues outbound opcode 0xEB with the weapon type through BuildAndQueueOutgoingGameAction. The entry bytes are checked first.
feat(web): password reset email, forgot-username email, opt-in 2FA
• /forgot-password and /forgot-username send mail through SMTP_URL (nodemailer); uniform answers, per-IP and per-recipient limits, reset tokens hashed, single-use, one hour, tied to session_version. • Opt-in TOTP two-factor authentication with QR setup and ten single-use recovery codes; replay guard and a per-account lockout after five wrong codes. Enabling it signs out other sessions and older game keys. • /auth/login asks for the code (401 twoFactorRequired); a game key on a 2FA account sti…
feat(server): catalogue published Luna maps
Validate operator map manifests, derive native floors, and install immutable custom-map revisions behind the Enhanced mission boundary. Keep proprietary packs outside the repository and document the activation contract.
fix(0.5): remove carried objective actors for observers
Empty gun click: Luna clicks locally, the mission hears it
Native HandleWeaponFireAction (0x459e90) plays the weapon's SPELL.BIN fail sound and waits 300 ms when the magazine cannot pay for a trigger pull; it sends nothing.
feat(server): #near lists the Aliens nearest an admin and whether they fit
An Alien reported as stuck or not attacking could not be matched to an actor: under native client AI only the shim's 0xEA report knows where it is. #near [n] (admin, read-only) lists the nearest live AI Aliens from that report, else the spawn record, with the storey at that spot and whether the species' native body height fits there.
fix(luna): admin broadcast lane (Luna 3.6)
fix(server): don't count the viewer in the sector player count
The Available Sectors list counted every connected player, including the one it was sent to. That player's world connection is registered before the 0x78 goes out, so someone alone on the server read "Alpha Sector (Online) 1 Player". Each recipient now gets the count of the other players, matched by account so their other stage connections are skipped as well. The refresh broadcast builds one list per lobby socket.
Sector list: "Alpha Sector (Online)" in green, accurate counts
ao-server: Alpha's 0x78 extra text is "Online" (it drew as "()"), and a game-stage authentication also refreshes open sector lists. A player moving to the hive closes the world socket first, so other lobby viewers were left with a count one too low.
fix(server): dispatch corpse strips on world connections
test(server): journal native Retrieval objective transitions
feat(shim): native state 5 for the reserved Retrieval Core 0x780; reserve its id
The client-side half of #783 (MODE-RET, #781), shipped ahead of the server spawn so launchers carry it before the server sends the Core. IsRetrievalCore promotes only species 6 / id 0x780 in mission type 3 to state 5 (native Get), mirroring IsDemolitionCharge; it is inert until the server spawns 0x780. next_npc_id now skips 0x780 so no ordinary Alien can receive that id and be promoted. The server Core spawn itself stays in #783.
fix(ai): snapshot target pos once so a mid-tick leave cannot crash the AI tick
_alien_ai_loop filtered Marine targets on a truthy pos under _CLIENTS_LOCK, then indexed c["pos"] again in the chase-target min(), tgt["pos"] and melee_tgt["pos"]. A client leaving at match close (or dying/redeploying) clears pos from another thread, so those reads raised TypeError and the restarting wrapper lost the tick (production 2026-10-07, capture-objective lane 2026-10-09). Read each target's pos once per actor, drop the ones that are gone, and carry that snapshot through chase and melee.
docs(server): correct bots.rank help text and the byte-17 research note
Byte 17 of the 0x03 announce is the rank index (peer field 0x4f2af6), which also scales the native Alien kill bonus in local slot 0x66, so the setting is not display-only. Annotate the old wKills reading in RESEARCH.md instead of rewriting history, and align the Setting call's indentation.
Fix Retrieval Missions
Allow AI Marine Ranks To Be Configureable
fix(luna): parse mixed capture flags through env settings
test(luna): move real peer through browser lane
fix(native-lab): keep guest SSH cleanup bounded (0.5)
fix(server,luna): each side's summary reports its own result; steady the timeout lane
• _enhanced_summary_packet reported the Marines' outcome (state['won']) to every recipient, so an Alien player's Hive Summary read Victory when the Marines won and Defeat when the Hive won. Report the recipient's own side, the rule _record_lifetime_results already applies. Test covers both sides in both outcomes; the old line fails it. • Lanes that encoded the bug (settlement, retrieval/demolition/stranded/ capture objective waits, admin-end) now expect each peer's own result. • test:timed-ti…
#endmission admin command to end a mission early
• feat(server): #endmission admin command to end a mission early
test(luna): tighten companion A/B evidence
test(luna): control mixed peer poses in mission scope
Changes to the code the game server runs. Not every change is live yet: the server is updated between play sessions.