forked from mediaexplorer74/WPR
-
Notifications
You must be signed in to change notification settings - Fork 1
Update History
Bubbleshum edited this page Jul 19, 2026
·
17 revisions
Running changelog of WPR fixes / features / compatibility changes. Most recent entries are at the top.
- Compat: Bejeweled Live (PopCap) — the plain title, distinct from Bejeweled Live + — promoted from Untested → Playable; the menu is now portrait and in-game achievements list correctly. Boots and runs end-to-end.
- Fix: Bejeweled Live launched in a landscape window despite being a portrait
game. Root cause was WPR-wide: FNA never set
Window.CurrentOrientationon desktop (it stayedDefault), so the game's main-menuLockOrientation()took its landscape branch. Fix: report the backbuffer-implied orientation fromFNAWindow.EndScreenDeviceChange. Shim-only — no reinstall - Fix: Bejeweled Live's in-game achievements screen came up empty. Root cause
was WPR-wide: the shim ran the
BeginGetAchievementscompletion callback on a thread-pool thread, so the game's per-rowTexture2D.FromStreamran off the render thread and silently failed. Fix: marshal that callback onto the game thread viaWprGameThread. Shim-only — no reinstall - Feat: hardcoded achievement catalogue added for Bejeweled Live (PopCap) —
all 20 achievements (200 GamerScore total) now available in WPR. Keys
recovered from the game's
Achievements.ACHIEVEMENT_KEYS; icons sliced from the TrueAchievements sprite. - Compat: James Patterson's Women's Murder Club (Vivid Games) promoted from Untested → Playable — boots and runs end-to-end.
- Feat: hardcoded achievement catalogue added for James Patterson's Women's
Murder Club (Vivid Games) — all 13 achievements (200 GamerScore total) now
available in WPR. Keys recovered from the
triggerAchievementcall sites inWMC_wp7.dll; icons sliced from the TrueAchievements sprite.
- Compat: Beards & Beaks (Microsoft Studios) promoted from Untested → Playable — boots and runs end-to-end after the fixes below.
- Fix: Beards & Beaks splash-screened then crashed with
TypeLoadException: Could not load type 'System.Windows.Deployment'(andIsolatedStorageSettings). Root cause:ApplicationPatcher.PatchDllsilently failed to write the mainBeards and Beaks.dllat install — Mono.Cecil'sWritethrewAssemblyResolutionExceptionresolving an enum-typed field constant fromMicrosoft.Xna.Framework.Graphics, so the assembly stayed unpatched and its[System.Windows]typerefs were unresolved at runtime. Fix: gave the patcher aDefaultAssemblyResolverwith search paths for the install dir + WPR bin (FNA/shims). Install-time change — affected games need reinstalling - Fix: Beards & Beaks then threw a
MissingMethodExceptiononDependencyObject.get_Dispatcher()inPerformActionOnUIThread, which calls((DependencyObject)Deployment.Current).Dispatcher.BeginInvoke(...). Fix: added aDispatcherproperty to theDependencyObjectshim and made theDeploymentshim derive fromDependencyObject. Shim-only — no reinstall
- Compat: Battlewagon (Ironsun Studios) promoted from Untested → Playable — fixed and confirmed working end-to-end this session.
- Feat: hardcoded achievement catalogue added for Battlewagon (Ironsun Studios) — all 18 achievements (200 GamerScore total) now available in WPR.
- Feat: hardcoded achievement catalogue added for Hydro Thunder GO (Pixelbite Games) — all 14 achievements (200 GamerScore total) now available in WPR.
- Feat: hardcoded achievement catalogue added for Zuma's Revenge! (PopCap) —
all 14 achievements (200 GamerScore total) keyed to the game's
EAchievementTypeenum names, with icons sliced from the TrueAchievements sprite. Retroactive-friendly: the game'sSyncAchievementsXLivebi-directionally syncs the player's saved unlocks with the WPR DB. - Compat: Assassin's Creed Pirates (Ubisoft Paris, Silverlight) brought up to
a clean managed launch — it now boots to MainPage and binds the
DrawingSurfacecontent provider — but remains Broken/not playable. The game engine is Ubisoft's Spark2: native ARM (ARMNT) C++ modules (Geea renderer, Lua scripting, D3D11) with no x86 or managed build, and the Lua + assets ship as AES-encrypted.spdcontainers. It can't execute on desktop x64, ARM emulation isn't viable, and a managed reimplementation is gated on reverse-engineering encrypted content from non-runnable binaries. Full analysis inDocs/Spark2_Managed_Reimplementation_Feasibility.md. - Fix: AC Pirates never reached MainPage on the managed launch path — a chain
of missing Silverlight/WP8 types threw at startup. Fix: shimmed
System.Windows.Navigation.UriMapperBase/UriMapper/UriMapping,System.Windows.FlowDirection,System.Windows.Markup.XmlLanguage,FrameworkElement.Language/FrameworkElement.FlowDirection,System.Net.HttpUtility, andMicrosoft.Phone.Info.DeviceStatus; and added staticRootFramediscovery inSilverlightAppHost. Shim-only — no reinstall - Fix: WinRT winmd-hybrid titles bound types incorrectly — the winmd stubber
didn't reproduce the .NET WinRT projection. Fix:
WinmdStubber/WindowsTypeSynthesizernow project collection interfaces (IMap→IDictionary,IVector→IList, etc.) and value-type structs (Windows.Foundation.Size/Point/Rect) correctly. A library-wide improvement benefiting all winmd-hybrid titles. Shim-only — no reinstall - Feat:
BrandedSplashRenderer— games whose native engine WPR can't host now show a branded splash (the app's own key art on a themed background) instead of a D3D test pattern. A library-wide affordance. - Compat: Battleship (Electronic Arts) promoted from Untested → Playable, now with an achievement catalogue; the game boots and runs end-to-end.
- Fix: Battleship black-screened then crashed on startup — the game creates
a push-notification channel during startup, but the missing
Microsoft.Phone.Notification.HttpNotificationChanneltype threw aTypeLoadException, so the game's canvas stayed null and it crashed. Fix: added a no-opHttpNotificationChannelshim. Shim-only — no reinstall - Fix: Battleship crashed on its online REST thread with a
MissingMethodException— the game called the synchronousGamer.GetPartnerToken(string), which was absent from the GamerServices shim. Fix: added the synchronousGamer.GetPartnerToken(string)overload. Shim-only — no reinstall - Fix: on-screen text was blank in Battleship (and every localized WP7 game)
— the WPR assembly resolver only probed the install root, so localized
satellite resource assemblies (
<game>.resources.dll) in their per-culture subfolders (en/,en-US/, …) never loaded and the string table stayed empty. Fix: the resolver now loads satellite resource assemblies from their per-culture subfolders. A library-wide improvement. Shim-only — no reinstall - Fix: Battleship launched fullscreen — it stamped
PresentationParameters.IsFullScreen=truedirectly, bypassing the graphics-manager guard. Fix: force windowed at the FNA window choke point, which covers every fullscreen path without affecting backbuffer sizing, so games now always launch windowed on desktop. A library-wide change. Shim-only — no reinstall - Fix: repeated
LeaderboardReader.LeaderboardIdentityMissingMethodException(WPR-wide) — the shim property was mis-named and the identity was discarded. Fix: the property now round-trips. Shim-only — no reinstall - Feat: hardcoded achievement catalogue added for Battleship — all 20 achievements (200 GamerScore total) with icons, wired to the game's real unlock keys.
- Compat: Babel Rising 3D promoted from Untested → Playable (first-hand verification on this fork); the game now boots and runs end-to-end and achievements work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue.
- Fix: Babel Rising 3D crashed on launch / ran a dead engine — the Shiva
engine (cross-compiled to C# via llvm2cs) never initialised. Root cause:
WPR's
Type2.GetTypeshim (which the patcher substitutes forType.GetType(string, bool)) only resolved assembly-qualified type names, so the game's lookup of the unqualifiedcom.indigen.llvm2cs.generated.Programreturned null. Program init was skipped, no nativehermes_*functions registered, and every frame silently errored — surfacing as aninvalid declared function: hermes_enginePausecrash when the window lost focus. Fix: resolve unqualified type names against the calling assembly, restoring the originalType.GetTypesemantics. This fixes the whole class of Shiva/llvm2cs-based games, not just Babel. Shim-only (Type2.csimplementation — theType.GetType→Type2patcher entry already existed, so nothing changed in the patcher table): rebuild only, no reinstall. - Fix: hardened the FNA game loop so a WP7 title's activation handler that
throws can no longer crash the game on a window focus change — each
Activated/Deactivatedsubscriber now runs under its own guard. A library-wide robustness improvement. Shim-only — no reinstall - Feat: hardcoded achievement catalogue added for Babel Rising 3D — all 12
achievements (200 GamerScore total) with names, descriptions, GamerScore
and icons. Wired to the game's real unlock keys via
MandoSocial, so they match the game's internal achievement keys exactly and unlocks are tracked.
- Docs: rebuilt the Compatibility List as a comprehensive master list. Instead of only the ~50 titles we had hand-tested, it now seeds every Xbox LIVE–enabled Windows Phone game (283 titles) as the baseline and rates each on this fork — most are ❔ Untested, which is the to-do list rather than a verdict. Added count badges, a "Status at a glance" breakdown (35 Playable / 5 Partial / 5 Broken / 238 Untested; 32 with achievement catalogues), a focused "Tested on this fork" view, and the full 283-row table in a collapsible section.
- Docs: the universe of titles is taken from Wikipedia's List of Xbox Live games on Windows Phone (every WP game that shipped with Xbox LIVE achievements / Gamerscore). The list was cross-checked against TrueAchievements, Exophase and XboxAchievements.com — no WP achievement title confirmed by two or more of those databases is missing from it, so the Wikipedia list is treated as a complete enumeration. Five achievement titles WPR supports or has encountered that the Wikipedia list omits (Penguins Can't Fly, Acedia: Indie Horror, Asphalt Pogonya, Ragdoll Run, BBB: App-ocalypse) are carried as additional entries marked †.
- Docs: folded the old "Legacy reports" table into the master list (legacy playable/partial/broken titles now carry an ❔ Untested status with a legacy note), and refreshed the Home page "compatibility at a glance" summary to match.
- Docs: added an interactive web edition of the compatibility list (searchable,
sortable, filterable) at https://bubbleshum.github.io/WPR/, served via
GitHub Pages from the
gh-pagesbranch, and linked from the wiki. - Docs: the interactive list now shows box art for 272 of the 283 titles (covers sourced from TrueAchievements) with a toggleable cover-grid view; the 11 without art (the 5 † extras plus a few apps TA doesn't track) fall back to a placeholder tile.
- Compat: Crimson Dragon: Side Story promoted from Legacy Broken → Playable (first-hand verification on this fork); the game no longer black-screens on launch and now boots and runs end-to-end.
- Fix: Crimson Dragon: Side Story black-screened on launch — game init aborted
before anything drew. Root cause: in
ApplicationPatchertheGamerServicesComponenttype refs were rescoped to the WP7 assemblyMicrosoft.Xna.Framework.GamerServicesExtensions, which does not exist at runtime, so the load threw aFileNotFoundExceptionthat aborted game init. Fix: bind those type refs directly to the WPR shim assemblyMicrosoft.Xna.Framework.GamerServices, and correct the dead-branch ordering in the assembly-ref rewrite loop. Patcher-table change — affected games need reinstalling - Compat: ilomilo promoted from Legacy → Playable (first-hand verification on this fork); the game runs end-to-end and achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue.
- Feat: hardcoded achievement catalogue added for ilomilo — all 15
achievements (200 GamerScore total) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/6d8088a0-77d6-df11-a844-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys are positional (Achievement1–Achievement15, generated by the game as$"Achievement{i+1}"), mapped in Xbox achievement-definition order; the game reads and awards them via the standard WP7 GamerServices path (BeginGetAchievements/BeginAwardAchievement) and read-back is index-safe, so unlocks are tracked. - Compat: Guitar Hero 5 Mobile achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue. The game was already Playable on this fork (promoted 22/05).
- Feat: hardcoded achievement catalogue added for Guitar Hero 5 Mobile — all
20 achievements (10 GamerScore each, 200 GamerScore total) with names,
descriptions, GamerScore and icons, committed under
Src/Database/Achievements/d289b7d1-60d9-df11-a844-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered from the game DLL (Guitar Hero 5.dll) are the literals in theLiveAchievements.m_achivementKeystable (e.g.COMPLETE_SONG_GUITAR,FIVE_STARS_FOUR_SONGS), indexed by theeAchievementIDenum and awarded viaLiveAchievements.AwardAchievement→BeginAwardAchievement(m_achivementKeys[(int)id]), so they match the game's internal achievement keys exactly and unlocks are tracked. - Compat: Dream Track Nation promoted from Legacy → Playable (first-hand verification on this fork); the game runs end-to-end and achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue.
- Feat: hardcoded achievement catalogue added for Dream Track Nation — all 12
achievements (200 GamerScore total) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/66a55fdc-bf85-4f8e-bf91-b9f42a8691fa/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Achievements are awarded in-game via the standard WPR GamerServices pipeline and display on the WPR achievements page. - Compat: Ghostscape added as Playable — the Psionic point-and-click haunted-house escape game runs end-to-end, and achievements now work (the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue).
- Feat: hardcoded achievement catalogue added for Ghostscape — all 16
achievements (200 GamerScore total) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/f3f72235-5c9d-44cf-a880-4c385fd0bab2/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys are the literal strings the game passes toAwardAchievement("…"), so they match the game's internal achievement keys exactly and unlocks are tracked.
- Compat: Final Fantasy achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue. The game was already Playable on this fork (promoted 21/05).
- Feat: hardcoded achievement catalogue added for Final Fantasy — all 18
achievements (200 GamerScore total) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/c6eaa012-9ee1-4125-b85d-dc2cbf868d8c/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Achievements are awarded in-game via the standard WPR GamerServices pipeline (the game'skeyName[]table →BeginAwardAchievement), so they match the game's internal achievement keys exactly and unlocks are tracked. - Compat: Sonic The Hedgehog 4: Episode I achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue. The game was already Playable on this fork (confirmed 22/05).
- Feat: hardcoded achievement catalogue added for Sonic The Hedgehog 4:
Episode I — all 16 achievements (200 GamerScore total) with names,
descriptions, GamerScore and icons, committed under
Src/Database/Achievements/d46de6ea-3774-e011-81d2-78e7d1fa76f8/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered from the game DLL (Sonic4 ep I.dll) are the literalsA1–A16, mapping 1:1 to the in-gameAppMain.achievementstable, so they match the game's internal achievement keys exactly and unlocks are tracked. Per-achievement icons sliced from the TrueAchievements sprite sheet. - Compat: Star Wars: The Battle for Hoth held at Partial — now playable end-to-end after the two fixes below (boots, front-end menus, loads and plays levels; previously booted but hung on a black screen at level start). Held at Partial because it renders sideways/rotated 90° on desktop (a panel-rotation emulation was attempted and reverted) and some corner HUD icons may not appear.
- Fix: Star Wars: The Battle for Hoth hung on a black screen at level start
and waited forever. Root cause: the game plays an intro video via
MediaPlayerLauncherand only continues — loading the level — when the app is reactivated after the video. WPR'sMediaPlayerLauncher.Show()was an empty stub, so the completion never fired; the game had already torn down its front-end and sat on a black screen. Fix:Show()now skips the video and signals completion, andApplicationLaunchbridges that to a deferred app-reactivation on the game thread (WprGameThread). Shim-only — no reinstall - Fix: the real blocker behind the level-start hang —
OnGameActivatednever received the reactivation. Root cause: thePhoneApplicationService.Activatedevent's subscribe accessor dropped handlers that attached after the app was already activated, which is the normal case (games subscribe inInitialize), so the game's handler was never retained. Fix: the accessor now always retains the subscriber; also benefits any game relying onActivatedfiring more than once (resume/relaunch). Shim-only — no reinstall - Compat: Star Wars: The Battle for Hoth held at Partial — the game runs and achievements now work (the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue), but the in-game UI is a bit off, so it is not fully playable end-to-end on this fork.
- Feat: hardcoded achievement catalogue added for Star Wars: The Battle for
Hoth — all 18 achievements (200 GamerScore total) with names, descriptions,
GamerScore and icons, committed under
Src/Database/Achievements/83a571ff-92d0-df11-9eae-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree.
- Compat: Fable Coin Golf demoted from Playable → Partial. Menus operate fine, but starting a level shows a black screen, so it is not playable end-to-end on this fork. Was previously Playable (promoted 23/05).
- Compat: Bejeweled Live + achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue, and they display correctly in the WPR UI. The game was already Playable on this fork.
- Feat: hardcoded achievement catalogue added for Bejeweled Live + — all 20
achievements (10 GamerScore each, 200 GamerScore total) with names,
descriptions, GamerScore and icons, committed under
Src/Database/Achievements/f0e9779c-54d6-4d3d-96fd-a85b92874160/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered from the game assembly; per-achievement icons sourced from TrueAchievements. - Compat: Z0MB1ES (on teh ph0ne) achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue. The game was already Playable on this fork (confirmed 22/05).
- Feat: hardcoded achievement catalogue added for Z0MB1ES (on teh ph0ne) — all
20 achievements (10 GamerScore each, 200 GamerScore total) with names,
descriptions, GamerScore and icons, committed under
Src/Database/Achievements/eb52de06-ad4f-4433-b652-987255481eb0/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Achievements are themed on the game's mini-games (I MAED A GAM3, Time Viking, Endless Z0mb1es, etc.). - Compat: Castlevania Puzzle (Encore of the Night) achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue. The game was already Playable on this fork (promoted 22/05).
- Feat: hardcoded achievement catalogue added for Castlevania Puzzle — all 16
achievements (200 GamerScore) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/accb1d9f-4120-e011-854c-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered by decompilingCastlevaniaPuzzle_WP7.dll— the literal strings inAchievements.LIVE_ACHIEVEMENT_NAMES, awarded viaProgressionData.earnAchievement→AwardAchievement→BeginAwardAchievement(key)— and equal the TrueAchievements display names verbatim, so they match the game's internal achievement keys exactly and unlocks are tracked. Per-achievement icons sliced from the TA sprite sheet. Awards fire from in-game triggers during play and are not retroactive. - Compat: Star Wars: The Battle for Hoth promoted from Legacy Broken → Partial (first-hand verification on this fork); the game no longer crashes on launch and now boots. Gameplay not yet fully verified, so held at Partial.
- Fix: Star Wars: The Battle for Hoth crashed and quit immediately on launch,
two ticks into boot, with a
MissingFieldExceptionforWPR.XnaCompability.GraphicsDeviceManager2.DefaultBackBufferWidth/DefaultBackBufferHeight. Root cause: the first line of the game'sCGame.InitializeMain()reads the XNA static fieldsGraphicsDeviceManager.DefaultBackBufferWidth/Height; the patcher redirects the type to ourGraphicsDeviceManager2shim, emittingldsfld GraphicsDeviceManager2::DefaultBackBufferWidth.ldsfldresolves the field token against the exact declared type and does not walk to the FNA base class, and the shim didn't declare those fields, so it threw. Fix: add the two shadowed static fields (public new static readonly int DefaultBackBufferWidth/Height, values 800/480 matching the FNA base) toSrc/Core/WPR.XnaCompabilityPatch/GraphicsDeviceManager2.cs. Shim-only — no reinstall - Compat: MonstaFish promoted from Legacy → Playable (first-hand verification on this fork); the game runs end-to-end and achievements work — the game tracks unlocks and the achievement toast fires off its hardcoded catalogue.
- Compat: WP7 hardware Back-button navigation confirmed working on desktop — in-game screens that only exit via Back now navigate a single step per Esc press. Benefits every WP7 game; verified on The Sims Medieval (the in-game Achievements screen and pause menu now navigate correctly, Esc = Back; achievements were already working off the hardcoded catalogue).
- Fix: on desktop the WP7 hardware Back button could not be pressed at all, so
any in-game screen that only exits via Back (e.g. The Sims Medieval's
Achievements screen) was a dead end. Root cause: the WP7 Back button mapped
only to SDL
SDLK_AC_BACK, which no desktop keyboard can emit. Fix: map the desktop Escape key to the WP7 Back button inSrc/ThirdParty/fna/src/FNAPlatform/SDL2_FNAPlatform.cs. Shim-only — no reinstall - Fix: holding Escape for a normal ~100ms press registered as many Back
presses across frames, cascading through menus into the pause menu and
leaving it unusable. Root cause: the WP7 Back button was level-triggered.
Fix: make Back edge-triggered in
Src/ThirdParty/fna/src/FNAPlatform/SDL2_FNAPlatform.cs— Back is now cleared each frame at the top ofPollEventsand asserted for exactly one frame per fresh keydown (set only onevt.key.repeat == 0), so one key press equals one Back. Shim-only — no reinstall - Compat: Cro-Mag Rally (Pangea Software) promoted from Legacy → Playable (first-hand verification on this fork); the game runs end-to-end and achievements now work — the game tracks unlocks and the achievement toast fires off its new hardcoded catalogue.
- Feat: hardcoded achievement catalogue added for Cro-Mag Rally — all 14
achievements (200 GamerScore) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/3e237715-f0a9-e011-a53c-78e7d1fa76f8/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered directly from the game assembly (PangeaCoreLib.LIVESupport); names/descriptions/scores from TrueAchievements; per-achievement icons sliced from the TA sprite sheet. Keys match the game's internal achievement keys exactly so unlocks are tracked. - Fix: newly-added achievement catalogues (no accompanying
.csedit) never reached the build output, so the catalogue rows were missing at runtime. Root cause: the Desktop "Copy pre-made database" build target runsAfterTargets="Build", but Rider/VS fast up-to-date check skipped invoking MSBuild when only content files changed, so the target never ran. Fix: setDisableFastUpToDateCheckinWPR.UI.Desktop.csproj, and hardenProgram.Mainto resolve the bundledDatabase\viaAppContext.BaseDirectoryinstead of the current working directory. Build/run-target change — rebuild and restart WPR; no reinstall (catalogues are picked up at next launch via the startup reconcile) - Compat: Asteroids Deluxe achievements now work — the game tracks unlocks, achievements display in-game and on the WPR achievements page, and the achievement toast fires (verified unlocking "Credit Where Credit Is Due"). Already Playable on this fork (verified 23/05).
- Feat: hardcoded achievement catalogue added for Asteroids Deluxe — all 10
achievements (200 GamerScore) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/85f9fa94-da3d-e011-854c-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Krome "Game Room" engine title. - Fix: Asteroids Deluxe threw
MissingMethodExceptionon the credits screen — the Game Room engine reads settings via the genericIsolatedStorageSettings.TryGetValue<T>overload, which our shim didn't provide. Fix: added the genericTryGetValue<T>overload to theIsolatedStorageSettingsshim. Shim-only — no reinstall - Fix: Asteroids Deluxe achievement-icon load and the unlock toast raced on
the same icon PNG, throwing an
IOException. Root cause:Achievement.GetPicture()opened the PNG without sharing, so the toast and the in-game icon load contended for the file handle. Fix:GetPicture()now opens icon PNGs read-only with shared access. Shim-only — no reinstall
- Compat: The Sims Medieval achievements now work — the game tracks unlocks
and the achievement toast fires off its new hardcoded catalogue (20
achievements / 200 GamerScore). Its entry was migrated out of the old
Database/TrueAchievements/AchievementsNameToKey.jsonname→key map into a committed per-game catalogue underSrc/Database/Achievements/a703c941-2b1c-49c5-ae00-abb8a0745b1e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. The game was already Playable (first-hand verified on this fork, 22/05). - Compat: Civilization Revolution promoted from Legacy → Playable (first-hand
verification on this fork); achievements work — the game tracks unlocks and
the achievement toast fires off its hardcoded catalogue
(
Src/Database/Achievements/f1126266-30a0-4bfc-8985-97cb1d6821b0/). - Compat: Risk promoted to Playable — boots past its logo and plays end-to-end; achievements now work (the game tracks unlocks and the achievement toast fires).
- Fix: Risk hung on a black logo screen and never reached the menu. Root
cause:
MpWiFiNetwork..ctorcallsDeviceExtendedProperties.GetValue("DeviceUniqueId"), which ourMicrosoft.Phoneshim returnednullfor; the resultingNullReferenceExceptionwas silently swallowed by the broad catch inXNAGame.Update, so the game wedged on its logo with no error surfaced. Fix: the shim now returns a stable 20-byte device id (SHA-1 of the machine name) forDeviceUniqueId. Shim-only — no reinstall - Feat: hardcoded achievement catalogue added for Risk — all 20 achievements
(200 GamerScore) with names, descriptions, GamerScore and icons, committed
under
Src/Database/Achievements/4e70a2e0-b2bb-4647-886d-a0977c5a9b90/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys are fixed literals from the game'sGetKeyFromMedalIdover theMedalHandler.MedalIdenum, so they match the game's internal achievement keys exactly and unlocks are tracked. - Feat: re-added a first-chance exception logger (
[wpr-fce]) to the per-game debug log to surface exceptions that games swallow in broad catch blocks — this is what pinpointed the Risk NRE. - Feat: launch notification now prefers the curated catalogue game name ("Risk") over the manifest title.
- Compat: Assassin's Creed (Altaïr's Chronicles HD) achievements now work — the game tracks unlocks and the achievement toast fires.
- Feat: hardcoded achievement catalogue added for Assassin's Creed — all 19
achievements (200 GamerScore) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/40d77c09-c1e6-df11-a844-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered by decompiling the game'sBeginAwardAchievementcall sites (including exact quirks such as a trailing space and missing apostrophes), so they match the game's internal achievement keys exactly and unlocks are tracked. - Compat: The Sims 3 demoted from Playable → Partial — the game runs but renders sideways (rotated 90°, wrong screen orientation), so it is not fully playable. Same root issue as Need For Speed Undercover (engine bakes a landscape-right phone rotation; on a desktop window the content reads sideways).
- Compat: Asphalt 5 achievements now work — the game tracks unlocks and the achievement toast fires.
- Feat: hardcoded achievement catalogue added for Asphalt 5 — all 16
achievements (200 GamerScore) with names, descriptions, GamerScore and
icons, committed under
Src/Database/Achievements/20e77ac3-00c2-416e-8054-7d081afb73de/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys recovered by decompiling the game'sBeginAwardAchievementcall sites, so they match the game's internal achievement keys exactly and unlocks are tracked. - Compat: Angry Birds achievements now work — the game tracks unlocks and the achievement toast fires.
- Feat: hardcoded achievement catalogue added for Angry Birds — all 20
achievements with names, descriptions, GamerScore and icons, committed
under
Src/Database/Achievements/e4571a02-0b87-e011-986b-78e7d1fa76f8/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys match the game's internal achievement keys, so unlocks are tracked and the achievement toast fires. - Compat: Kinectimals promoted from Legacy → Playable (first-hand verification on this fork) and now ships an achievement catalogue.
- Fix: Kinectimals hung forever on its splash screen and never reached the
menu. Root cause: its
AchievementManager.Initialise()callsGetAchievements()and indexes the returned collection by achievement name every tick; with the achievement DB empty, ourAchievementCollectionstring indexer returnednullon a miss, so the game dereferenced null →NullReferenceExceptionevery frame and the splash → menu transition never completed. (The native FAudio "Empty group!" warnings in the logs were unrelated and harmless.) Fix: harden theAchievementCollectionstring indexer to return an unearned placeholder instead ofnull, matching real-WP7 behaviour whereGetAchievements()always returns the game's full catalogue. Shim-only — no reinstall - Feat: hardcoded achievement catalogue added for Kinectimals — all 15
achievements with names, descriptions, GamerScore and icons, committed under
Src/Database/Achievements/5a3f9c59-1d30-4895-bb76-641bdd959a8c/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. Keys match the game's internal award keys, so unlocks are tracked and the achievement toast fires correctly.
- Compat: The Sims 3 promoted from Legacy → Playable (first-hand verification on this fork) and now ships an achievement catalogue.
- Feat: hardcoded achievement catalogue added for The Sims 3 — 18
achievements / 200G, with per-achievement icons sliced from
TrueAchievements and the real in-game achievement keys recovered by
decompiling
sims3.dll. Committed underSrc/Database/Achievements/9995f674-0ad7-df11-a844-00237de2db9e/as anachievements.jsonmanifest + one PNG per achievement, mirrored into the Android assets tree. - Compat: hardcoded achievement catalogues rolled out to 14 games — Zombies!!!,
Plants vs Zombies, 3D Brick Breaker Revolution, Brain Challenge, Bug Village,
Fruit Ninja, Fruit Ninja (2013), Max and the Magic Marker, MonstaFish, Need
For Speed Undercover, Civilization Revolution, Tentacles, Tiki Towers, Tower
Bloxx New York. Each has an
achievements.jsonmanifest + per-achievement icons committed underSrc/Database/Achievements/<productId>/and mirrored into the Android assets tree. - Compat: Fruit Ninja — in-game new achievement earns now record correctly. Achievements the game already marked earned in its own save aren't re-awarded (the game skips them), so they don't appear retroactively in WPR. That's game-save behaviour, not a WPR bug.
- Feat: achievement catalogues are now the sole source of achievement data.
XnaAchievementSeederreconciles non-destructively at install and at app startup (for installed games): inserts new rows, updates changed name/description/score/icon, removes rows whose key is no longer in the catalogue, and never resets earned state. The runtime TrueAchievements scraper path was removed and the old IL/XMLXnaAchievementCodeExtractorwas deleted. - Fix: any XNA game that set a not-yet-present gamer property/stat during play
crashed with a bogus "Please check your memory usage" dialog and then exited
(seen on Fruit Ninja 2013 on an achievement unlock). Root cause:
Microsoft.Xna.Framework.GamerServices.PropertyDictionary.GetPropertyignored itsdemandCreateflag and returned null, so the first write of a fresh property NRE'd inSetValue/SetTypedValue; the game caught it and surfaced the memory dialog. Fix: honourdemandCreateby allocating a newObjectPropertyValuewhen the key is absent. Shim-only — no reinstall - Fix: in-game gamerpic rendered blank (and crashed games that draw it).
GamerProfile.GetGamerPicturereturnedStream.Nullwhen no avatar was configured, soTexture2D.FromStreamproduced a null texture. Fix: fall back to a bundled default avatar. Shim-only — no reinstall - Fix: the Windows achievement-unlock toast briefly stole window focus →
SDL
FOCUS_LOST/FOCUS_GAINED→ FNAGame.IsActiveflipped →OnActivated/OnDeactivatedfired mid-tick, which some WP7 ports throw inside. Fix: newWprActivationGuardmakes the SDL focus branches ignore the toast-induced focus blip so the toast no longer disrupts the game. Shim-only — no reinstall - Fix: the WPR Achievements page (trophy nav) was loaded once and cached, so a game catalogued/installed after the page was first viewed didn't appear until restart. Fix: the page now reloads each time it's shown. Shim-only — no reinstall
- Compat: Zombies!!! (Babaroga) added as Playable. Boots and plays end-to-end;
its in-game achievement screen now populates instead of rendering empty. Root
cause of the empty list: the game builds its own achievement UI from our
SignedInGamer.BeginGetAchievementsshim and callsTexture2D.FromStream(device, Achievement.GetPicture())per row — with no seeded icon,GetPicture()threw and the build loop aborted right after itsu.Clear(), leaving the list empty. Fixed by shipping a hardcoded achievement catalogue for the game (17 entries + real 64×64 icons), keyed to the literals the game passes toXnaGame.AwardAchievement("…")so unlocks register. - Feature: achievements are now sourced solely from committed per-game
catalogues under
Src/Database/Achievements/<productId>/(anachievements.jsonmanifest + one PNG per achievement). They are autofilled / reconciled into the DB non-destructively at install and at startup — new rows inserted, changed metadata updated, earned state never reset. The old install-time IL/XML achievement extractor and the runtime TrueAchievements scraper were removed. Catalogues built so far: Zombies!!!, Plants vs Zombies, Brain Challenge, Bug Village, Fruit Ninja, Max and the Magic Marker, MonstaFish, Need For Speed Undercover, Civilization Revolution, Tentacles, Tiki Towers, Tower Bloxx.
- Compat: Mirror's Edge promoted from Broken → Playable after the
GamerServicesDispatcher.WindowHandlefix below - Fix: Mirror's Edge booted to a flat grey screen (RGB 84,84,84) and never
drew anything else —
LoadContentwas never invoked, so the game cleared to its background colour every frame and sat there. Root cause: Mirror's Edge'sGame.Initialize()override setsGamerServicesDispatcher.WindowHandle, wrapped in a try/catch that only swallowsGamerServicesNotAvailableException,NotSupportedException, andInvalidOperationException. Our shim'sWindowHandleproperty threwNotImplementedExceptionon both get and set, which escaped the game's narrow catch, propagated up into FNA'sGame.DoInitialize, and was swallowed there — leaving the game in a half-initialised state whereLoadContentand the rest of the boot sequence never ran. Fix: inSrc/Core/Microsoft.Xna.Framework.GamerServices/GamerServicesDispatcher.cs, changedWindowHandleto a no-op auto-property (public static IntPtr WindowHandle { get; set; }). We have no Live UI tied to a host window handle anyway, so the stored value is never read back by our stack. Shim-only — no reinstall - Compat: Need For Speed Undercover promoted from Legacy → Partial
(first-hand verification on this fork). Java-midp port wrapped in XNA
(entry point
midp.JavaLibGameinnf9_xna.dll). Engine hardcodes a landscape-right rotation for a phone held physically tilted:midp.Display.ctorunconditionally setsorientation = LANDSCAPE_RIGHTandbackBuffer.isLandscape = true;midp.Graphics.lanscapeTransformisRotZ(π/2) × Translate(width, 0)keyed offPresentationParameters.BackBufferWidth;midp.Graphics.clipRecthardcodes scissor clamps at 480 × 800 portrait logical bounds. Symptom: on a desktop landscape window (no physical tilt) the engine renders portrait UI content rotated 90° CW, so text reads top-to-bottom and the scene appears rotated 90° from what a desktop user expects. Currently launches in a portrait 480 × 800 window with content rotated 90° (sideways-readable); playable in that state if the user tilts their head or rotates their monitor. Investigated four host-side workarounds (per-game rotation setting + RT trampoline;PreparingDeviceSettingsswap to landscape PP dims; PP swap + scissor rotation transform; PP swap + scissor rotation +SpriteBatchtransform override with letterbox fit) — each either failed to progress past the EA splash, hit the engine's hardcoded portrait scissor clamps, left engine-rotated text sideways, or misaligned non-UI draws (cars, background, EA splash) with the letterbox region. All reverted. Net: no clean desktop-landscape interpretation without per-game asset/engine patches; likely affects other Java-midp ports too. No net code changes landed
- Compat: Fable Coin Golf promoted to Playable — plays end-to-end and closes cleanly after the two fixes below
- Fix: Fable Coin Golf aborted during initial content load with a
ContentLoadExceptionwrappingFileNotFoundExceptionforContent/data/Brightwall_Wall_Rock_Snow__0.xnb. Root cause: the XAP ships without that chapter-2 texture, but the obstacle list still references it, and the reference is embedded as an external reference inside the BasicEffect XNB rather than being read via a directOpenStreamcall. FNA'sTitleContainer.OpenStreamcorrectly rethrowsFileNotFoundException(as required by Castlevania Puzzle's localized-asset try/catch fallback — see the 22/05 entry), so the missing asset surfaced as a fatal load failure rather than degrading. Fix: inSrc/ThirdParty/fna/src/Content/ContentReader.cs,ReadExternalReference<T>now catchesContentLoadExceptionwhose inner cause isFileNotFoundExceptionand returnsdefault(T). Embedded external references inside other XNBs degrade gracefully; directOpenStreamcallers (Castlevania Puzzle's localization fallback) still see the exception and can run their own catch. Shim-only — no reinstall - Fix: Fable Coin Golf crashed on window close with a fatal
AccessViolationExceptionraised from native FNA3D — uncatchable, took the host process down. Root cause:ResetWprSingletonsinSrc/Core/WPR/ApplicationLaunch.cshad a broad sweep that walked every type in every Default-ALC sibling DLL and calledf.GetValue(null)on its static fields, which implicitly triggered the static constructor of any untouched type. Fable'sCIwAttractor.cctorbuilds aVertexBuffervia the native FNA3D path; at shutdown theGraphicsDevicewas already torn down, so the native call dereferenced freed device state and raised the AV. Fix: removed the broad sweep entirely. Sibling-DLL touches are now restricted to the hand-curated_PerLaunchFlagsToResetallow-list (currently justPressPlay.FFWD.Application.quitNextUpdatefor Tentacles, which Fable doesn't use), so untouched types never get cctor-triggered at shutdown. Shim-only — no reinstall - Compat: Asteroids Deluxe promoted from Broken → Playable after the
Type2.GetTypefix below — clears theKrome.GameRoom.UI.Screens.InGameScreenData.set_Machinecrash recorded in the 22/05 entry - Fix: Asteroids Deluxe (and any Krome-based title where a sibling library
DLL calls
Type.GetType("X, MainUserAssembly")) crashed during the initial screen-state machine transition with aFileLoadExceptionwrappingNotSupportedException: A non-collectible assembly may not reference a collectible assembly. Root cause:Krome.dll(sibling library, loaded into the DefaultAssemblyLoadContextby design to satisfy the non-collectible-cannot-reference-collectible rule) calledType.GetType("AsteroidsDeluxe, ..."), which our patcher routes throughWPR.WindowsCompability.Type2.GetTypeinSrc/Core/WPR.WindowsCompability/Type2.cs. That shim previously delegated straight to the frameworkType.GetType(string), whose binder resolves assemblies through the Default ALC — butAsteroidsDeluxe.dlllives in the per-launch collectible user ALC, so the CLR's cross-ALC collectibility check tripped and the bind failed. Fix:Type2.GetTypenow searchesAssemblyLoadContext.Allfor an assembly whose simple name matches the type's assembly qualifier and resolves the type viaAssembly.GetTypedirectly, bypassing the framework binder entirely. The new path is a pure managed lookup with no cross-ALC collectibility validation, so the binding succeeds. Shim-only — no reinstall - Compat: Tentacles confirmed Playable end-to-end including clean relaunch after the fix below (first launch was already fine; second launch was silently quitting at frame 0)
- Fix: Tentacles silently closed its XNA window immediately on the second
launch in a WPR session — no error, no log line, just an instant quit
after the first frame. First launch was fine, and the symptom only
appeared if the user backed out via the main-menu Back button (which
routes
MainMenu.OnDoQuit → PressPlay.FFWD.Application.Quit) on launch one. Root cause: Tentacles is built on the PressPlay.FFWD mini-engine (PressPlay.FFWD.dll), which ships as a sibling DLL of the mainTentacles.dll. WPR's assembly resolver routes sibling DLLs into the non-collectible DefaultAssemblyLoadContext(to satisfy the "non-collectible assemblies may not reference collectible assemblies" rule), so FFWD's managed statics survive across launches.PressPlay.FFWD.Application.quitNextUpdateis aprivate static boolthatApplication.Quit()flips totrue; the next frameApplication.Updatereads it and callsGame.Exit(). On launch one this works correctly. On launch two, FFWD was already loaded in Default ALC, the newApplicationinstance read the still-trueflag at frame 0 and immediately calledGame.Exit(). Fix: inSrc/Core/WPR/ApplicationLaunch.cs, track sibling DLLs that the Default-ALC resolver pulls from the user install folder (new_DefaultAlcUserSiblingslist) and extendResetWprSingletonsto reset per-launch state on those siblings between launches with a deliberately narrow policy: clear allIList/IDictionarystatic fields in place (mutation, notSetValue, so it works throughstatic readonly), and reset specific known per-launch flag fields by name via an allow-list (_PerLaunchFlagsToReset), currentlyPressPlay.FFWD.Application.quitNextUpdate. Adding fields to the allow-list requires manual confirmation that the field is a plain managed bool/int, not[ThreadStatic]or JIT-inlined — an earlier blanketSetValueon every writable value-type static crashed with a fatal0x80131506 COR_E_EXECUTIONENGINE. Shim-only — no reinstall - Compat: Tiki Towers promoted from Legacy → Playable (first-hand verification on this fork)
- Compat: Storm in a Teacup tested on this fork — marked Partial. Boots and is playable end-to-end but exhibits major graphics issues during gameplay
- Compat: Asteroids Deluxe marked Broken on this fork — crashes during the
initial screen-state machine transition
(
Krome.GameRoom.UI.Screens.InGameScreenData.set_Machine) before gameplay starts, surfacing asFileLoadExceptionwrappingNotSupportedException: A non-collectible assembly may not reference a collectible assembly. Root cause:InGameScreenDatacallsType.GetType("AsteroidsDeluxe, ...")to reflect into its own user assembly, which is redirected throughWPR.WindowsCompability.Type2.GetTypeatSrc/Core/WPR.WindowsCompability/Type2.cs.Type2.GetTypedelegates straight to the frameworkType.GetType(string), which resolves assemblies via the defaultAssemblyLoadContext— butApplicationLaunchloads every user/game assembly into a per-launch collectible ALC (_CurrentUserAlcinSrc/Core/WPR/ApplicationLaunch.cs) so launches can unload cleanly. The CLR refuses to bind a non-collectible static reference (WPR.WindowsCompability) to a collectible assembly (AsteroidsDeluxe.dll) and throws. Likely fix is shim-only: routeType2.GetTypethrough the active user ALC — either via theType.GetType(string, Func<AssemblyName, Assembly>, …)overload with a resolver that delegates to_CurrentUserAlc.LoadFromAssemblyName, or by splitting the type name and resolving the assembly explicitly. Not yet landed - Compat: Guitar Hero 5 Mobile promoted from Legacy → Playable (first-hand verification on this fork)
- Compat: Final Fantasy 3 demoted from Legacy → Broken — first-hand
verification on this fork. Square Enix's NDS → WP7 port ships its own
in-process Nitro/G3X-to-XNA renderer inside
syrcusW.dll, and the NDS background tile loaders (GXS_LoadBG0Char,GXS_LoadBG0Scr,GXS_LoadBGPltt,GXS_LoadOAM,GX_LoadTexPltt,GX_SetCapture, and ~25 siblings) ship as empty-bodied stubs.Game.Tickticks normally, presents happen at 800x480 and no exceptions are thrown, but with the BG palette/char/screen upload path no-op'd the DS background tiles never become XNA textures — maps and menus render as a black backdrop with only the foreground sprite layer and font glyphs visible (~3-4 draw calls/frame). Not fixable shim-side: WPR's existing patcher entries and FNA shims are sufficient, the bug is inside the game's own port code. Would require binary-patchingsyrcusW.dllto translate NDS BG palette/char/screen memory layout into XNA texture data — multi-day RE job, not a shim addition - Compat: The Sims Medieval promoted from Legacy → Playable (first-hand verification on this fork)
- Compat: Angry Birds promoted from Legacy Broken → Playable (first-hand verification on this fork)
- Compat: Max and the Magic Marker promoted from Legacy → Playable (end-to-end after the three fixes below)
- Compat: Pac-Man promoted from Legacy → Playable (first-hand verification on this fork)
- Fix: Max and the Magic Marker crashed on window close with an
AccessViolationExceptionoriginating inFNA3D_AddDisposeTexturefrom~Texture(). Root cause: theTexturefinalizer ran afterGraphicsDevice.Disposehad already destroyed the FNA3D device, so the native dispose call dereferenced freed device state. Fix: guard the native dispose call inSrc/ThirdParty/fna/src/Graphics/Texture.cson!GraphicsDevice.IsDisposed. Shim-only — no reinstall - Fix: Real touchscreen input never registered in Max and the Magic Marker
(and any other XNA game polling SDL touch). Root cause: SDL2's touch
device IDs are 64-bit (
SDL_TouchID), butTouchPanel.LastActiveTouchIdwas declaredint, so the value was truncated as it round-tripped throughTouchPaneland the polling path calledSDL_GetNumTouchFingers(bogusId)— which always returned 0. Widened the field tolonginSrc/ThirdParty/fna/src/Input/Touch/TouchPanel.csand dropped the(int)casts inSrc/ThirdParty/fna/src/FNAPlatform/SDL2_FNAPlatform.cs. Shim-only — no reinstall - Fix: Single-finger drawing in Max and the Magic Marker refused to start a
stroke — one real finger was being reported as two simultaneous touches.
Root cause: SDL synthesises mouse events from touch events by default
(
SDL_HINT_TOUCH_MOUSE_EVENTS = 1); we already filtered the synthetic events in our event pump, but the mouse-as-touch poll still read the pollutedSDL_GetMouseState, writing a phantom finger into slot 7 alongside the real one. Max's drawing logic treats a 2-touch frame as a multi-finger gesture and refuses to start a stroke. Fix: setSDL_HINT_TOUCH_MOUSE_EVENTS = "0"in the Windows init block ofSrc/ThirdParty/fna/src/FNAPlatform/SDL2_FNAPlatform.csso SDL stops synthesising mouse events from touch entirely. Shim-only — no reinstall - Compat: Z0MB1ES (on teh ph0ne) confirmed Playable
- Compat: I Dig It promoted from Broken → Playable (end-to-end after the two fixes below)
- Fix: I Dig It crashed at frame 1 of
IDigItApp.UpdatewithFileLoadException(0x80131515)wrappingNotSupportedException: A non-collectible assembly may not reference a collectible assemblyon its first reference to its bundledChipmunk.dllphysics wrapper. Root cause: theAssemblyLoadContext.Default.Resolvinghandler inApplicationLaunchloaded every sibling DLL it found in the install dir into the collectible user ALC and handed the resulting assembly back to its Default-ALC requestor. The CLR then refused to bind a non-collectible static reference to that collectible assembly, so the JIT failed at the IDigItApp.Update call site. Fix: split the handler's two cases — the main game DLL still routes into the user ALC (FNA'sContentTypeReaderManager.Type.GetTypelegitimately needs the collectible type back, and loading it into Default would re-trigger the launch-1-statics contamination bug guarded by the existing comment), but sibling DLLs now load into the Default ALC so non-collectible static refs bind cleanly. Trade-off: those siblings persist across launches; for self-contained native-wrapper libs like Chipmunk that's harmless. Added a_CurrentMainAssemblyNamefield to drive the discrimination. Shim-only — no reinstall - Fix: After clearing the Chipmunk crash, I Dig It got past the splash but
still wedged just before the menu rendered, this time with
MissingMethodException: LeaderboardReader.get_TotalLeaderboardSize(). Our shim hadTotalLeaderboardSizedeclared as a method; XNA exposes it as anintproperty. Adding only that surfaced the next missing member (get_PageStart), so the full property surface (CanPageDown,CanPageUp,IsDisposed,IsSynchronizedWithLiveServer,Leaderboard,PageSize,PageStart,TotalLeaderboardSize) plusEndPageDown/EndPageUp/EndRead-
PageDown/PageUp+IDisposable.Disposewas filled in in one pass. All stubs report "no leaderboard available" (false / 0 / empty / fresh reader), so the game treats the leaderboard screen as empty rather than crashing — appropriate given there's no live Xbox LIVE backend. Shim-only — no reinstall
-
- Compat: Castlevania Puzzle promoted from Partial → Playable (story / arcade mode now start; previously tapping a save slot silently no-op'd)
- Fix: Castlevania Puzzle's save-slot screen rendered correctly but tapping a
slot to start the game did nothing. The slot tap fires
DashResourceProvider.getLocalizedBinary, which uses the standard WP7 localization-fallback idiomtry { OpenStream("dat\\data\\items.en-GB") } catch { OpenStream("dat\\data\\items") }. Our FNATitleContainer.OpenStreamwas catchingFileNotFoundException(and every other exception), logging it to[wpr-ex], and returningnullinstead of rethrowing. The game'scatchtherefore never fired, the fallback to the unsuffixed file never ran, and the subsequentnew BinaryReader(null)threwArgumentNullExceptioninsideGame.Update— whichGame.Tickswallows. The save-slot UI stayed visible, so the user perceived the "Start Game" button as missing. Fix: rethrow at the end of both catch blocks inTitleContainer.OpenStreamafter theContent/Scenes/fallback has been given a chance to run.[wpr-ex]diagnostics still log on the way out. Likely had silent secondary effects in any other game using the same localization-fallback pattern. Shim-only — no reinstall - Compat: Assassin's Creed: Altaïr's Chronicles promoted from Partial →
Playable (end-to-end after
SignedInGamer.SignedIndeferred-invoke fix below) - Fix: Assassin's Creed crashed in
XNAGame..ctorwith aNullReferenceExceptioninside its ownSignedInhandler. Root cause:SignedInGamer.SignedIn'saddaccessor took two paths — a deferred 2sTask.Delayfor the very first subscriber in the session, and a synchronous invoke for any later subscriber (gated by a staticFirstSignInSessionDoneflag). Two compounding problems: (1)SignedInGamer.Reset()was called afterActivator.CreateInstance(mainType!)inApplicationLaunch.Start, so the flag set by a previous game launch in the same WPR session carried into the new game's ctor; (2) the synchronous path then fired the just-attached handler during+=, while the game's ctor was still mid-construction, and the immediate-fire branch had no try/catch wrapper (unlike the deferred branch). Assassin'sXNAGame.aaccessed athis-field its ctor hadn't initialised yet, NRE'd, and the exception escaped up throughActivator.CreateInstance. Fix: collapse the two paths into one — every subscription dispatches onTask.Run(delay 0 for late subscribers, 2s for the first), goes through the same_SignInGatesemaphore + try/catch, and never runs synchronously from+=. Also movedSignedInGamer.Reset()to run beforeActivator.CreateInstance. Shim-only — no reinstall - Compat: Plants vs Zombies promoted from Broken → Playable (end-to-end after achievement-seed + SpriteBatch tolerance fixes below)
- Fix: PvZ launched to a black screen because
Lawn.AchievementsWidget.DrawNRE'd insideAchievements.GetAchievementItem— the game's staticgAchievementListwas empty, so the lookup returned null and the NRE escaped mid-SpriteBatch.Begin, wedging every subsequent frame on"Begin has been called before calling End". Root cause: PvZ stores its 18 achievement keys in an inlineAchievements.ACHIEVEMENT_KEYS[]static array (built in the cctor), so none ofXnaAchievementCodeExtractor's three sources —Content/xml/socialnetworks.xml.xnb, ILldstrnearAwardAchievement*callsites, orContent/Achievements/*.xnbfilenames — recovered any keys at install time. The seeder wrote 0 rows;BeginGetAchievementsreturned 0 rows; the game'sGetAchievementsCallbackadded 0 items togAchievementList. Added a Source D (KnownProductCatalogues) keyed by ProductId that returns hardcoded keys recovered via decompilation, threadedproductIdthroughXnaAchievementCodeExtractor.ExtractRichandXnaAchievementSeeder.SeedAsync. Install-time change — affected games need reinstalling. Now seeds 18 rows andBeginGetAchievements: 18 rowsconfirms it - Fix: After the achievement seed worked the game flickered on main menu and
in level —
Lawn.GameSelector.DrawOverlaystill NRE'd every frame on some other null reference, but the deeper problem was that PvZ'sSexy.Graphicslayer tracks its ownspritebatchBeganflag separately from FNA'sbeginCalled, and the two desync once any Draw exception leaves the game's flag stale. The result was a within-frame double-Begin viaSetupDrawMode → EndFrame → EndDrawImageTransformed → BeginFrame, throwingInvalidOperationExceptionand dropping every other frame. We can't reach the game's private flag from the shim. Made FNA'sSpriteBatch.Begin/Endtolerant of out-of-order calls: a secondBeginwithout an interveningEndsoft-resets and starts a fresh batch (drops the queued sprites of the discarded batch); a strayEndwithout a matchingBeginno-ops. First 5 of each are logged so we can spot if it's firing in production. Shim-only — no reinstall - Feat: Diagnostic
[wpr-trace] BeginGetAchievements: N rows for <ProductId>log inSignedInGamer.BeginGetAchievementsconfirms whether the install- time seed populated for a given game on first launch - Feat: Keyboard accelerometer simulator. New Controls page in the desktop
sidebar binds four keys (defaults WASD) to tilt directions; readings flow
through the existing
Microsoft.Devices.Sensors.Accelerometerso games see them without any per-game shim work. Sensitivity slider, master toggle, in-game tilt-overlay (Avalonia for Silverlight host, FNADrawableGameComponentfor XNA), and a live-preview dial on the Controls page. Orientation-aware: the screen-relative key intent gets rotated into the device-portrait frame the WP7 sensor contract expects, so a landscape game (W = "tilt up the screen") produces the correct device-X tilt the game interprets as steer-left. Desktop orientation is inferred from the back-buffer aspect because FNA'sWindow.CurrentOrientationonly updates from SDL display-rotation events that never fire on the desktop.Accelerometer.CurrentValue/IsDataValid/TimeBetweenUpdateswere also added so games that poll instead of subscribing toReadingChangedsee live readings too - Compat: Hydro Thunder GO promoted from Partial → Playable (steerable via the keyboard accelerometer)
- Compat: Uno confirmed Playable
- Fix: Sonic 4 Episode I self-paused on every Update tick. The game's
AppMain.isForegroundflag is flipped true only by itsGame.Activatedhandler, andActivatednever fired on WPR becauseINTERNAL_isActivewas initialisedtrue(suppressing the BeforeLoop setter's no-op transition to avoid Asphalt 5's pre-Initialize KeyNotFoundException). Net effect:isForegroundstayed false, the game's pause condition (!isForegroundORed into the trigger) re-armed every frame, and pause reasserted itself immediately after dismissal. Fix: defer a one-shotOnActivatedto the end of the firstGame.Tick, where every game's per-Update state (including Asphalt 5's) is already populated - Fix: Window background/foreground transitions now fire
Deactivated/Activatedcorrectly on desktop and Android. Restored theSDL_WINDOWEVENT_FOCUS_LOST → IsActive=falsebranch inSDL2_FNAPlatform.PollEventsthat had been commented out under a//RnDmarker. SymmetricFOCUS_GAINEDwas already wired - Feat: Multi-touch input is now additive with the mouse-as-touch shim.
UpdateTouchPanelStatepreviously branched either-or — ifTouchPanel.MouseAsTouchwas on (the default for XNA games on WPR) the real-finger poll loop was skipped entirely, capping all input at a single touch even on multi-touch hardware. New shape: real fingers fill slots0..MAX_TOUCHES-2fromSDL_GetTouchFinger; whenMouseAsTouchis on the mouse takes the last slot with synthetic finger IDint.MaxValueso it can never collide with a real finger's ID. Sonic 4's "hold D-pad + tap jump" gameplay now works - Fix: Asphalt 5 splash → menu tap-to-continue now registers. The
per-
Game.TickFrameworkDispatcher.Update()call added on 21/05 was redundant — stock FNA'sGame.Updatealready pumps the dispatcher at its end. Pumping twice per tick madeTouchPanel.Updaterun twice in close succession; the second run promotedtouches[0]fromPressedtoMovedbeforeCGame1.g()could read it, soh2.b(press handler) never recorded the finger andh2.d'sif (i > 0)release-guard always failed. Splash-statelt.b()waiting onbe.ey.fm != 0was the surfaced case. Removed the redundant pump in FNAGame.Tick - Compat: Asphalt 5 promoted from Partial → Playable
- Compat: Sonic 4 Episode I confirmed Playable (pause loop fixed, multi-touch routed)
- Compat: Tentacles promoted from Broken → Playable (end-to-end after the fixes below)
- Fix: FNA's
ContentTypeReaderManagercouldn't resolveReflectiveReader<PressPlay.FFWD.Scene>becauseType.GetType()doesn't see types in the user game's collectible ALC, and the existingstring.Split(',')fallback broke on the generic argument[[PressPlay.FFWD.Scene, PressPlay.FFWD, …]](the comma between the inner type and its assembly hint was indistinguishable from the outer delimiter). Replaced withType.GetType's resolver-callback overload that walksAppDomain.CurrentDomain.GetAssemblies()— which returns every loaded assembly across every ALC — so generic readers parameterised by user-ALC types resolve correctly. Tentacles' Preloader scene XNB now deserialises - Fix: FFWD-based games call
Application.LoadLevel("X")with bare scene names even though every level XNB ships underContent/Scenes/. ContentManager constructedContent/X.xnb, the file wasn't there,AssetHelper.Load<T>silently swallowed the failure and returneddefault(T), and the loading screen hung forever waiting onloadingProgress == 1.0f.TitleContainer.OpenStreamnow retriesContent/<name>.xnbasContent/Scenes/<name>.xnbwhen the original is missing and has no subdirectory hint. Safe for non-FFWD games (fallback file simply won't exist either) - Fix:
Microsoft.Phone.Shell.StandardTileData.Countwasintin our shim but the WP7 SDK usesint?. Tentacles' live-tile updater callsset_Count(int?)every frame from a component Update and was trippingMissingMethodException~once per tick - Fix:
FNA.Game.RunLoopnow wraps the finalOnExiting(this, EventArgs.Empty)in try/catch + log. Tentacles'MetricsSender.CreateTearDownExtendedKeysNREs onGlobalManager.Instance.currentProfilewhen the user closes during early boot (currentProfile is null until the preloader finishes loading it). Can't fix the game code, but the host no longer surfaces its "unexpected error" dialog on close - Fix:
SignedInGamer.SignedInhandler invocations now serialise behind aSemaphoreSlim. Tentacles'Game1.Initializeregisters the same callback twice; both invocations were firing in parallel via separateTask.Delay.ContinueWiths, racing on the sharedAchievementContext.Currentand tripping EF Core'sConcurrencyDetectorinsideGamer.GetProfile. Handlers still get their independent ~2 s delay; only the synchronous Invoke runs single-file - Fix: Mouse-as-touch clicks now produce
GestureType.Tapgestures on desktop.SDL_MOUSEMOTIONwas forwarded toINTERNAL_onTouchEventunconditionally, including hover (no button held). Hover motion ranGestureDetector.OnMovedwhich setactiveFingerId = 1; the nextMOUSEBUTTONDOWN'sOnPressed(1)then sawactiveFingerId != NO_FINGERand routed into pinch-init (state = PINCHING). The matchingMOUSEBUTTONUPranOnReleased_Pinchinstead of Tap detection — so Tap-gated screens (Tentacles'LemmyTravelScreen, "tap to continue" prompts) never advanced from mouse but worked fine from real touch (no hover). Fix:SDL2_FNAPlatformskips the synthesised Moved event whenevt.motion.state == 0. Drag (button-held motion) still goes through, so swipe/pinch/drag from mouse continue to work - Feat: Periodic FFWD loading-state heartbeat in FNA
Game.Tick([wpr-heartbeat], fires ~every 2 s past the first-30-ticks verbose trace cap). ReflectsPressPlay.FFWD.ApplicationandPressPlay.Tentacles.Scripts.LevelHandlerstatic fields plus the active screen stack and the current level identity — turned a "stuck on loading screen" symptom into a precise gate-by-gate diagnosis. Best-effort, swallows all reflection errors,[Conditional("DEBUG")]-gated - Feat:
ContentManager.Load<T>now logs the underlying exception with type/HResult/inner/stack before rethrowing ([wpr-content]). FFWD'sAssetHelper.Loadsilently catches ContentManager.Load failures and returnsdefault(T); without the trace, a missing ContentTypeReader or malformed XNB was invisible. Trace lets the caller's swallow stand — only adds visibility - Feat: Assembly-resolver diagnostics in
ApplicationLaunch—[wpr-resolve-user]/[wpr-resolve-default]lines log every Resolving probe with full exception details whenLoadFromAssemblyPathfails
- Fix: Asphalt 5 sat on a blank loading screen —
StartupModeenum integer values now match the WP7 SDK (Launch=1,Activate=2), and FNA'sGame.IsActiveno longer fires a spuriousActivatedevent at first frame - Fix: Tentacles crashed at exit on a null
ApplicationCurrentMemoryUsage—Microsoft.Phone.Info.DeviceExtendedPropertiesnow returns the WP7 memory counters (ApplicationCurrentMemoryUsage,ApplicationPeakMemoryUsage,ApplicationMemoryUsageLimit) - Fix: XNA games that wait on
MediaPlayer/ song-finished callbacks before advancing past their splash now progress —Game.Tickauto-pumpsFrameworkDispatcher.Update()once per update, matching WP7 XNA 4.0 behaviour - Feat: Per-game
wpr_game_debug.logand the in-engine[wpr-trace]output are now#if DEBUG-gated viaWprDebugTrace— Release builds elide the trace formatting and file listener entirely (no log spam, no per-frame cost) - Feat: Richer assembly-resolver diagnostics in
ApplicationLaunch—Resolvingfailures log the underlying exception type, HResult and inner exception instead of the opaque "Operation is not supported" surface error - Compat: Asphalt 5 promoted from Broken → Partial (loads splash, gameplay TBD)
- Compat: Final Fantasy promoted to Playable
- Compat: Fruit Ninja confirmed Playable (no longer blocked on
GamerProfile.GetGamerPicture)
- Fix: Small bug on second launch of XNA games, where resources arent released fully
- Feat: Added Windows based notifications
- Feat: Added game icon as window icon for XNA