-
Notifications
You must be signed in to change notification settings - Fork 1
Troubleshooting
When a game misbehaves under WPR, the per-game debug log is almost always the fastest path to a diagnosis. This page covers where it lives, what to look for in it, and the common failure patterns.
Every game launched via a Debug build writes a per-game trace to:
%LocalAppData%\WPR\Apps\<ProductId>\wpr_game_debug.log
Replace <ProductId> with the GUID-shaped folder name for the game in
question. (ApplicationLaunch mirrors Trace and Debug output into
this file via the WprDebugTrace wrapper.)
Release builds skip this trace entirely — no log file, no per-frame cost. If you're investigating a bug, use a Debug build.
| Prefix | Meaning |
|---|---|
[wpr-trace] |
Informational milestone — Game.Update tick #N, Game.Draw tick #N done, etc. |
[wpr-ex] |
Swallowed exception. Look here first. |
[wpr-heartbeat] |
Periodic FFWD loading-state heartbeat (Tentacles-style games) |
[wpr-content] |
ContentManager.Load failure detail |
[wpr-resolve-user] / [wpr-resolve-default]
|
Assembly-resolver probe / failure |
The first [wpr-ex] is usually the proximate cause; subsequent ones are
often cascade failures from the same broken state. Read the stack
trace under each [wpr-ex], not just the message — the message alone
often understates the problem.
The game's Draw is throwing, and the SpriteBatch is left in a wedged
state so every subsequent Begin() re-throws. This used to be terminal;
since 22/05/2026 the FNA shim's SpriteBatch.Begin / End are tolerant
of out-of-order calls (soft-reset + start fresh).
If a black screen persists now, the problem is upstream of the recovery:
something further out (achievement seeding, content loading, the game's
own state machine) is throwing every frame. The first [wpr-ex] in the
log will name the offending method.
The recovery is working but the underlying NRE still fires every frame.
You'll see [wpr-trace] SpriteBatch.Begin #N: double-Begin tolerated or
SpriteBatch.End #N: stray End tolerated log lines. Look upstream for an
NullReferenceException that's recurring.
MissingMethodException: <FullyQualifiedName> means the game's IL
references a method our shim doesn't implement. The shim project's source
tree mirrors upstream namespaces; the type's file lives at
Src/Core/.../<Type>.cs. Add the missing member.
Almost always Enumerable.First() / Single() on an empty collection
inside the game's own code. Look at what the game expects to find — often
it's a content manifest, a resource bundle, or a gamer-profile entry that
we haven't populated yet.
The game expected a piece of WP7 state we haven't faked. The stack trace to the first non-game frame is the boundary — figure out what our shim returns to the game from there, and what the game expected instead.
Example pattern: Lawn.AchievementsWidget.Draw NRE'd inside
Sexy.Achievements.GetAchievementItem because the install-time
achievement seed wrote 0 rows (the extractor's three sources all missed
PvZ's inline ACHIEVEMENT_KEYS[] array). Source D in
XnaAchievementCodeExtractor was added to handle ProductId-specific
hardcoded catalogues.
[wpr-ex] Game.Run threw: is the visible symptom. Possible upstream
causes:
- Assembly resolution failure during the FNA / Game ctor — look at
[wpr-resolve-user]/[wpr-resolve-default]lines. -
Activator.CreateInstanceon an XNA game class that does something weird in its ctor (Acedia: Indie Horror does this).
For FFWD-based games (Tentacles, etc.) the [wpr-heartbeat] line shows
exactly which gate the loader is waiting on. Reflects
PressPlay.FFWD.Application and the active screen stack every ~2 s.
Did you also add a Patches entry in ApplicationPatcher.cs? Yes →
did you reinstall the game? The IL was rewritten at install time;
patcher table changes don't apply retroactively. Verify by checking
whether <game>.dll.original's sibling <game>.dll is newer than the
patcher change — if not, the install pipeline didn't re-run.
See the reinstall-vs-rebuild rule in Architecture.
The shim DLL is referenced by the patched game DLL by name — no rebuild of the game install is needed. Make sure the WPR shim rebuilt; close and re-launch the game.
Check the install log for XnaAchievementCodeExtractor: N hardcoded achievement(s) or N achievement(s) from socialnetworks.xml.xnb. If the
extractor returned 0, the seed wrote 0 — neither
Content/xml/socialnetworks.xml.xnb nor AwardAchievement IL literals
nor Content/Achievements/*.xnb filenames worked for this game.
For new "uses an inline ACHIEVEMENT_KEYS[]" titles, add a Source D entry
in XnaAchievementCodeExtractor.KnownProductCatalogues keyed by ProductId.
XNA MediaPlayer and song-finished callbacks now work as of 21/05/2026
(Game.Tick auto-pumps FrameworkDispatcher.Update() once per update).
If sound is still wrong, suspect XACT — that path isn't fully complete.
-
Pull the latest
mainand rebuild. Compatibility shifts fast. - Reinstall the game if a recent change touched the patcher table (mentioned in Update History) or the achievement extractor.
-
Read the per-game
wpr_game_debug.log— first[wpr-ex]line is usually the lead. - Search existing issues at https://github.com/Bubbleshum/WPR/issues.
If the issue is still there, open a new one with:
| Info | Example |
|---|---|
| Game name | Hydro Thunder GO |
| WPR commit hash | c5e988d9 |
| Platform | Windows 11 22H2 |
| What you did | Opened a .xap, hit Run |
| What happened | Black screen for 30 s then closed |
First [wpr-ex] line(s) from the log |
(paste — include the stack trace, not just the message) |
For honesty: the following are normal in alpha and not bugs per se:
- Some games fail to boot.
- Some games crash mid-gameplay.
- Some shaders look wrong.
- Some audio is missing in titles using XACT.
- Android target shows a white screen.
The Compatibility List tells you what to expect for the specific title you're testing.
- Architecture — pipeline, patcher table, reinstall rule.
- Compatibility List — known status per game.
- Update History — what changed and when.
- Building WPR — Debug vs Release; the per-game log only exists in Debug builds.