-
Notifications
You must be signed in to change notification settings - Fork 1
Contributing
Thanks for the interest. WPR is an alpha preservation project — there's a lot of low-hanging fruit (missing shims, untested games, broken patcher entries) and contributions of all sizes are welcome.
-
Test games and report results (commit hash + first
[wpr-ex]line from the per-game log goes a long way). -
Add missing shims — usually a few lines of
Microsoft.*/System.*API surface that a game needs. - Fix patcher table misses — type/method references the game's IL uses that don't map to a shim yet.
-
Implement Silverlight controls —
LongListSelector,WrapPanel,PhoneTextBox,PerformanceProgressBar,GestureService/GestureListenerare notable absences. - Improve Android — currently launches to a white screen on this fork.
- Documentation — wiki edits / FAQ entries / Compat List updates.
- Clone:
git clone https://github.com/Bubbleshum/WPR.git cd WPR - Open
Src/WPR.slnin Rider (recommended) or VS 2022 17.8+. - Set startup project to
WPR.UI.Desktopand run.
Full detail and CLI build flags: Building WPR.
-
CLAUDE.mdin the repo root — the canonical project conventions: build-flag pitfalls, reinstall-vs-rebuild rule, shim file layout, end-of-session cleanup. - Architecture on the wiki — how install / patch / launch / shims fit together.
Burns everyone at least once. Internalise this:
| Change | Action |
|---|---|
| Shim implementation change (any .cs under WPR.*Compability, Microsoft.*, System.*, FNA, GamerServices) |
Rebuild only. Installed games pick up the new behaviour on next launch. |
| Patcher table change (new entries in ApplicationPatcher.cs's Patches / MemberPatches) |
Rebuild and reinstall the affected games. The IL was rewritten at install time; new redirects don't apply retroactively. |
| Achievement extractor change ( XnaAchievementCodeExtractor.cs) |
Install-time — affected games need reinstalling. |
When your PR description mentions a fix for a specific game and lists a patcher / extractor change, call out that a reinstall is needed so reviewers know what to test.
WPR.SilverlightCompability mirrors the upstream Silverlight / WP namespace
hierarchy on disk:
| Upstream type | File path |
|---|---|
System.Windows.Shapes.Rectangle |
System/Windows/Shapes/Rectangle.cs |
System.Windows.Controls.Primitives.Popup |
System/Windows/Controls/Primitives/Popup.cs |
Microsoft.Phone.Shell.PhoneApplicationService |
Microsoft/Phone/Shell/PhoneApplicationService.cs |
The C# namespace declaration in every file is WPR.SilverlightCompability
— the directory structure is pure organisation, the assembly is one flat
DLL. When adding a new shim type, look up the upstream namespace, mirror it
as directories, drop the class file in. The filename matches the type name.
Keep the doc comment /// Shim for <c>System.X.Y.TypeName</c>. on each
shim — it's the canonical record of which upstream type the file shadows.
WPR.WindowsCompability and WPR.XnaCompability are still flat. Don't make
a separate pass just to reorganise them; apply the mirror-tree convention
the next time you touch them.
dotnet build <project>.csproj -c Debug `
-f net8.0-windows10.0.17763.0 `
-maxcpucount:1 -nodeReuse:false --nologoBuild a leaf project for fastest feedback (e.g. the project containing the file you just edited). Full-chain builds via the CLI sometimes fail with spurious "namespace not found" cascades — defer those to Rider.
The Android leg often fails on this dev box with NU1202 (workload
mismatch) — that's why we explicitly pass -f net8.0-windows10.0.17763.0.
See Building WPR for the full list of flags and what each one does.
Before opening a PR (or wrapping a task), clean up anything you created just for diagnosis:
-
Log files you wrote to the repo root or under
Src/(e.g.build_*.log,restore_*.log,install_*.log). Leave pre-existing files alone. -
Stray
global.json/ scratch csprojs created just to probe SDK behaviour. -
Orphan
dotnet/MSBuild/VBCSCompilerprocesses you spawned (Get-Process+ match the command line). Do NOT kill processes belonging to Rider (ReSharperHost,JetBrains.*) or VS (devenv).
Don't clean obj/ or bin/ — those are normal incremental build artifacts.
- Follow existing project conventions (look at neighbouring files).
- Meaningful names over short ones.
- Prefer clarity over cleverness.
- Avoid unnecessary abstractions — shims should be thin.
- Keep platform-specific code isolated where possible.
Use WprDebugTrace.WriteLine($"[wpr-trace] ...") for trace output. The
wrapper is #if DEBUG-gated, so Release builds elide the formatting and
file writes entirely (no per-frame cost). The convention for prefixes:
| Prefix | When |
|---|---|
[wpr-trace] |
Informational milestones |
[wpr-ex] |
Swallowed exceptions |
[wpr-heartbeat] |
Periodic state snapshots (e.g. FFWD loader gates) |
[wpr-content] |
ContentManager.Load failures |
[wpr-resolve-user] / [wpr-resolve-default]
|
Assembly resolver probes |
- Keep PRs focused on a single change. "Fix PvZ achievements" + "Make SpriteBatch tolerant" + "Add keyboard accelerometer" should be three PRs, not one.
- Mention any reinstall requirement in the PR description.
- For compat fixes, name the game(s) in the PR title and add an entry to the wiki's Update History once merged.
If you test a game and the result changed, file an issue with:
| Info | Example |
|---|---|
| Game name | Hydro Thunder GO |
| WPR commit hash | c5e988d9 |
| Platform | Windows 11 22H2 |
| Status | Playable / Partial / Broken |
First [wpr-ex] line |
(paste — include the stack, not just the message) |
The log lives at %LocalAppData%\WPR\Apps\<ProductId>\wpr_game_debug.log —
see Troubleshooting.
- Copyrighted game assets / XAPs / decompiled commercial code.
- Proprietary SDK files (the WP7 SDK reference assemblies).
- Anything that would put the preservation project at legal risk.
- Architecture — pipeline, shim layout, reinstall rule.
- Building WPR — full build instructions.
- Update History — recent changes.