NEShim Documentation
NEShim is a full-featured NES emulator built on BizHawk’s cycle-accurate core, with native Steam integration for commercial distribution. Publish any NES game on Steam as a native Windows or Linux application — with achievements, overlay support, Steam Input, save states, a rich multi-language UI, and a deep video and audio filter stack — without modifying the ROM.
Documentation
| Page | What it covers |
|---|---|
| Configuration reference | Every field in config.json, with types, defaults, and examples |
| Filters | Audio filters (7 processors), video filters (structural, overlay, color effects, motion effects), availability by renderer, combining examples, and shader architecture |
| Achievement system | How to define memory-watch triggers, encode them, and seal the config |
| Publishing guide | Step-by-step checklist for packaging a game for Steam release |
| Multi-Game Mode | An alternate, additive publish path: one binary hosting N games, each bundled in a single deploy or sold as separate Steam DLC, selected through a front-end filmstrip carousel with per-game box art and descriptions |
| Architecture | Internals: thread model, subsystem design, patterns, how to extend |
| Input system | Keyboard remapping, XInput, Steam Input, hotkeys, and the VDF file |
| Localization | Language files, Steam language detection, CJK font fallback |
| Steam Deck | Automatic adjustments (menu scale, audio default), input latency fix, publishing requirements, known differences from Windows |
Requirements
- Windows x64: Windows 10 or later; D3D11 rendering path (SDL_GPU/Vulkan fallback if D3D11 unavailable)
- Linux x64: SDL_GPU/Vulkan rendering path; runs natively on Ubuntu 22.04+, SteamOS, and other mainstream distros
- .NET 9 runtime (bundled in self-contained publish)
- Steam client — required for achievements and overlay; the emulator runs without it but Steam features are silently disabled
- Steamworks native library — must be placed alongside the executable; not included in the repository (Valve SDK license). Use the matching copy from the Steamworks.NET 2025.163.0 release zip:
steam_api64.dll(Windows) orlibsteam_api.so(Linux) renamed tolibsteam_api64.so— the wrapper’s native-library lookup resolves to that name; under the zip’s default Linux filename, Steam init fails at startup (caught internally — the app still runs, but achievements/overlay/DLC checks are silently disabled). Games deployed through Steam receive it automatically via the Steam depot. - A
.nesROM file
Quick start (publishers)
Place config.json alongside the executable and set romPath at minimum:
{
"romPath": "mygame.nes",
"windowTitle": "My Game"
}
Everything else has sensible defaults. See the configuration reference for the full list.
Quick start (developers / contributors)
# Build the full solution
dotnet build NEShim/NEShim.sln
# Run tests
dotnet test NEShim/NEShim.Tests/NEShim.Tests.csproj
# Publish the game — Windows (self-contained, win-x64, with ReadyToRun)
dotnet publish NEShim/NEShim/NEShim.csproj -c Release -r win-x64 --self-contained true -p:PublishReadyToRun=true -o publish/NEShim-win-x64
# Publish the game — Linux (cross-compiles from Windows, or run on Linux)
dotnet publish NEShim/NEShim/NEShim.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=true -o publish/NEShim-linux-x64
# Or publish all platforms at once using the publish script:
.\local-publish.ps1 1.0.0
After publishing, copy the Steamworks native library from the Steamworks.NET GitHub release zip into the output directory alongside the exe: steam_api64.dll for Windows, libsteam_api.so for Linux — rename the Linux file to libsteam_api64.so (the wrapper’s native-library lookup resolves to that name; Steam init fails at startup under the zip’s default name, caught internally and silently disabling achievements/overlay/DLC checks). See the publishing guide for details.
See the architecture guide for a detailed walkthrough of the codebase.