v3.0.0
v3.0.0
Big one. Native Linux support and multi-game publishing, on top of a full menu rewrite. No more Windows native dependencies.
Native Linux x64
NEShim now runs natively on Linux not just through Proton: SteamOS, Steam Deck, Ubuntu 22.04+, most mainstream distros. Rendering is SDL_GPU/Vulkan; Windows stays on D3D11. Getting here meant rewriting the rendering/window/input stack off WinForms and GDI+ onto SDL3, which is why most of the rest of this release touches Windows too.
Every video feature that used to be D3D11/Windows-only now works on both platforms: Video Overlay, Color Effects, all 4 Motion Effects, Picture Adjustments, Video Presets. Screen Glow/phosphor persistence needed a different implementation on SDL_GPU since it can't bind a second texture sampler like D3D11 can, so it's done with blend-mode tricks instead of a shader.
Native Steam overlay works on Linux too. GPU/Vulkan device loss (e.g. after a Deck suspend/resume) is now detected and recovered from automatically instead of crashing.
Multi-game mode
One binary can now host N games. Each game gets its own ROM, config, saves, and achievements, picked at runtime from a front-end carousel, box art, per-game descriptions, animated transitions, fully localized in all 10 languages.
Steam DLC is optional per game and freely mixable in one build: bundle a game directly with no DLC depot, or sell it separately as its own DLC depot. Optional ECDSA-signed anti-tamper protection for DLC-gated games (pub-utils --seal-dlc-map, separate keypair from achievement signing).
Fully opt-in, existing single-game publishers are unaffected. Only activates if games/multigame.json is present.
Controller input
Gamepad support moved from Windows-only XInput to cross-platform SDL3, so it works on Linux and recognizes more controller types out of the box: DualShock, Switch Pro, Steam Deck, Xbox.
Binding menus now show the player's actual hardware glyphs (DualSense Square/Cross/Circle/Triangle, Xbox icons, Switch Pro icons) instead of a generic icon set, resolved through Steam Input where available.
Local multiplayer (1-4 players)
Opt-in local multiplayer for up to 4 players, gated by a new publisher-only playerCount field in config.json (default 1: existing single player games are unaffected unless you explicitly turn it on). The BizHawk core's Four Score / Famicom 4-Player Adapter emulation handles the 3-4 player controller wiring; no ROM changes needed.
Settings gains a Player Controls entry once playerCount is above 1, listing every player's Gamepad Controls and Keyboard Controls together with gamepad rows first, keyboard rows below. Each player's binding screen shows glyphs for that player's own physical controller, so a mismatched controller brand across players never shows the wrong icons. Multiplayer is gamepad-first out of the box: players 2-4 get sensible default gamepad bindings but no default keyboard bindings, since a shared keyboard can't serve 4 people without a layout you choose yourself. A new hideKeyboardControlsForExtraPlayers developer setting (default true) keeps that submenu from being cluttered with keyboard rows most local setups won't use.
Publishers: treat playerCount as fixed once a game ships, the same as the ROM file itself since NEShim's save states are a positional binary stream, not a keyed format, so changing the controller-port wiring underneath an already-shipped game corrupts the read of any existing save.
New tooling
NEShim.PubUtilsUIa small Windows GUI for sealing achievements, for publishers who'd rather not use the CLI.pub-utilsalso gained a--validateflag to check signatures without resealing.
Also in this release
- D-Pad / analog stick linkage option
- Held-repeat when navigating sliders with a direction held
- Native Steam Input mode (trackpad/gyro) behavior documented and handled explicitly
- Menu text overflow, fullscreen/windowed scaling, and localization gap fixes
No breaking changes
Everything here is backward compatible. Existing config.json publishers don't need to change anything to keep shipping as-is.
Linux publishers: the Steamworks native library needs renaming after you copy it in, grab libsteam_api.so from the Steamworks.NET release zip and rename it to libsteam_api64.so alongside the executable. Covered in the publishing guide.
What's Changed
- merge 3.0 changes to main by @karimhadjsalem in #106
- fix release pipeline by @karimhadjsalem in #108
- fix multi-target publisher by @karimhadjsalem in #110
Full Changelog: v2.3.0...v3.0.0