WallOfPain is a Windows wallpaper application that occasionally replaces the desktop with animated glitch events. It returns to assets/tree.jpg after every event. Source assets are read only; event frames are rendered to temporary bitmap files under the operating system's temp directory.
- Windows 10/11.
- .NET 8 SDK.
- Network access on the first build to restore
SixLabors.ImageSharp.
From the repository root:
.\build.ps1
.\dist\WallOfPain\wallpaper.exebuild.ps1 publishes self-contained win-x64 executables, assembles the complete release directory, and creates an empty log file. Copy dist\WallOfPain as one unit; do not separate the executable from assets or config.
On first launch, choose Add to Startup. This writes a WallOfPain value under the current user's Windows Run registry key. Run the executable again to start the service. unregister.exe removes that startup value.
Useful development commands:
dotnet run --project WallOfPain.csproj -- --debug --event scary --severity severe
dotnet run --project WallOfPain.csproj -- --debug --effect noise
dotnet run --project WallOfPain.csproj -- --validate --skip-startup-check
.\scripts\Verify-AssetIntegrity.ps1Press Ctrl+Alt+Shift+G to skip the current event and Ctrl+Alt+Shift+Q to exit. If another instance is running, the application offers cancel, open another, or close the existing instance and continue.
| Path | Purpose |
|---|---|
.gitignore |
Excludes .NET intermediates, generated releases, logs, IDE state, and temporary files. |
README.md |
Project overview, usage, configuration, asset rules, and this file map. |
Directory.Build.props |
Shared MSBuild settings; redirects intermediates/output into artifacts and excludes it from default item discovery. |
WallOfPain.csproj |
Main .NET 8 Windows executable; enables WinForms, publishes self-contained win-x64, references ImageSharp, and copies assets and config. |
Unregister.csproj |
Companion project that builds unregister.exe. |
build.ps1 |
Cleans staging, publishes both projects, assembles dist\WallOfPain, copies runtime content, and checks required files. |
src\Program.cs |
Main application: argument parsing, startup registration, event discovery/scheduling, rendering, glitch effects, wallpaper updates, fullscreen detection, logging, and cleanup. |
src\Unregister\Program.cs |
Utility that removes the WallOfPain startup registry value and reports the result with a dialog. |
scripts\Verify-AssetIntegrity.ps1 |
SHA-256 comparison of source event images against packaged copies. |
config\settings.json |
Runtime defaults for delays, glitch probabilities, render size, weights, random-event frame counts, fullscreen suppression, effects, and overrides. |
assets\tree.jpg |
Normal desktop wallpaper restored between events. |
assets\events\ |
Source event catalogue; each child folder is one playable event. |
artifacts\ |
Generated MSBuild output and publish staging; ignored and regenerable. |
dist\WallOfPain\ |
Generated self-contained release; ignored and deployed as a complete folder. |
The event folders are amessage, aroomofclocks, beforeafall, bsod, colors, concerned, corruptedsmile, downunder, dream, escapetheroom, flowertime, getready, happy, help, house, hypercube, number, purpleface, random, savefile, scary, sky, smile, smilingclock, underthemall, upsidedown, and well.
Each contains image frames (.png, .webp, .jpg, or .jpeg) and exactly one timing file named [seconds]x[loops].txt, such as 0.5x2.txt. The timing file controls frame duration and sequence repetitions. Frames are naturally sorted (10.webp follows 9.webp). random is special: each play selects a shuffled subset between randomMinimumImages and randomMaximumImages.
config/settings.json is loaded beside the executable. Delay values are seconds. Severity and event weights are relative weights, not percentages. enabledEffects accepts rgb, horizontal, vertical, blocks, invert, color, and noise. An override can set an event's severity and/or effects:
"eventOverrides": {
"amessage": { "severity": "subtle", "effects": ["rgb"] }
}The release writes logs\wallofpain.log, recording startup, event lifecycle, warnings, and errors. It trims the oldest megabyte when the file would exceed 5 MB. Temporary event wallpapers are written to %TEMP%\WallOfPain and reused in a two-file cycle.
Startup registration is never silent: it is an explicit first-run choice and can be removed with unregister.exe.