Platform Guide
Platform Setup & Cross-Platform Development
MonoGame supports a wide range of platforms. This guide walks through setting up each target, managing platform-specific code, and building for distribution.
Download the runnable sample project
Use the verified ZIP bundle for this article to review the extracted example files, run the sample host, and repackage the sources without bin or obj folders.
Common prerequisites
All platforms require the .NET SDK and MonoGame templates. Install them once and you are ready for any target.
dotnet new install MonoGame.Templates.CSharp
dotnet new --list | Select-String "MonoGame"
Available templates include:
mgdesktopgl— Cross-platform desktop (OpenGL)mgwindowsdx— Windows desktop (DirectX)mgandroid— Androidmgios— iOSmgnetstandard— Shared library for multi-platform projects
Windows (DirectX & OpenGL)
Windows is the most common development target. Choose DirectX for best Windows-native performance or OpenGL (DesktopGL) for cross-platform compatibility from day one.
DirectX project
dotnet new mgwindowsdx -n MyGameDX
cd MyGameDX
dotnet run
DirectX projects use SharpDX bindings and compile shaders with fxc. They produce the best performance on Windows but do not run on Linux or macOS.
DesktopGL project (recommended for cross-platform)
dotnet new mgdesktopgl -n MyGameGL
cd MyGameGL
dotnet run
DesktopGL uses SDL2 and OpenGL. The same binary runs on Windows, Linux, and macOS with no code changes for most projects.
IDE options
- Visual Studio 2022+ — Full debugging, IntelliSense, and the MGCB Editor extension.
- Visual Studio Code — Lightweight, works on all desktop platforms. Use the C# Dev Kit extension.
- JetBrains Rider — Cross-platform IDE with strong .NET support.
Linux
Use the DesktopGL template. Linux requires a few additional packages for SDL2 and OpenAL audio.
Install dependencies (Debian/Ubuntu)
sudo apt update
sudo apt install -y libsdl2-dev libopenal-dev
dotnet new mgdesktopgl -n MyLinuxGame
cd MyLinuxGame
dotnet run
Fedora / RHEL
sudo dnf install -y SDL2-devel openal-soft-devel
Arch Linux
sudo pacman -S sdl2 openal
If you encounter a DllNotFoundException for libSDL2, ensure the library is on your LD_LIBRARY_PATH or install the -dev package for your distribution.
macOS
DesktopGL projects run on macOS with the .NET SDK installed. Homebrew can provide the SDL2 library if it is not bundled.
brew install sdl2
dotnet new mgdesktopgl -n MyMacGame
cd MyMacGame
dotnet run
App bundle for distribution
To distribute a .app bundle, publish as self-contained and wrap the output in a macOS application structure:
dotnet publish -c Release -r osx-x64 --self-contained
# Then package the output into MyGame.app/Contents/MacOS/
Android
MonoGame provides an Android template. You need the Android SDK, Java JDK, and either Visual Studio with the Xamarin/MAUI workload or the .NET Android workload.
Prerequisites
- .NET SDK 8.0 or later
- Android SDK (API level 21+)
- Java JDK 11 or later
- Visual Studio with .NET MAUI or Xamarin workload, or
dotnet workload install android
Create and run
dotnet workload install android
dotnet new mgandroid -n MyAndroidGame
cd MyAndroidGame
dotnet build -t:Run
Touch input
On Android, use TouchPanel instead of mouse input. MonoGame maps touches to a collection you iterate each frame.
TouchCollection touches = TouchPanel.GetState();
foreach (TouchLocation touch in touches)
{
if (touch.State == TouchLocationState.Pressed ||
touch.State == TouchLocationState.Moved)
{
_playerPosition = touch.Position;
}
}
Screen orientation and lifecycle
// In Activity1.cs or your main activity
[Activity(
Label = "MyGame",
MainLauncher = true,
ScreenOrientation = ScreenOrientation.Landscape,
ConfigurationChanges = ConfigChanges.Orientation |
ConfigChanges.ScreenSize |
ConfigChanges.KeyboardHidden)]
public class Activity1 : AndroidGameActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var game = new Game1();
SetContentView(game.Services.GetService<Android.Views.View>());
game.Run();
}
}
iOS
Building for iOS requires a Mac with Xcode installed. Use the MonoGame iOS template and deploy to the iOS Simulator or a physical device with an Apple Developer account.
Prerequisites
- macOS with Xcode 15+
- .NET SDK 8.0 or later
dotnet workload install ios- Apple Developer account (for device deployment)
Create and run on simulator
dotnet workload install ios
dotnet new mgios -n MyiOSGame
cd MyiOSGame
dotnet build -t:Run -p:_DeviceName=:v2:udid=YOUR_SIMULATOR_UDID
Retina and safe area
iOS devices have varying screen densities. Use GraphicsDevice.PresentationParameters to get the actual back buffer size and respect the safe area insets to avoid notch overlap.
// In your Game class
int screenWidth = GraphicsDevice.PresentationParameters.BackBufferWidth;
int screenHeight = GraphicsDevice.PresentationParameters.BackBufferHeight;
// Use the Viewport to handle safe areas
Rectangle safeArea = GraphicsDevice.Viewport.TitleSafeArea;
// Position UI elements within safeArea bounds
Consoles overview
MonoGame supports Xbox, PlayStation, and Nintendo Switch through platform-specific ports that require developer programme membership. These are not available through the public NuGet packages.
Xbox (UWP / GDK)
- Join the ID@Xbox programme.
- Use the MonoGame WindowsDX or UWP template as a starting point.
- Xbox-specific APIs (achievements, multiplayer) require the GDK SDK.
- Test with Xbox dev mode on a retail console or a development kit.
PlayStation
- Register at PlayStation Partners.
- MonoGame ports for PlayStation are maintained under NDA by the FNA/MonoGame community.
- Expect platform-specific input mapping and certification requirements.
Nintendo Switch
- Apply at the Nintendo Developer Portal.
- FNA (a sister project to MonoGame) has established Switch ports used by shipped titles.
- Joy-Con input, docking detection, and HD Rumble require platform SDKs.
Console development requires signing NDAs and purchasing development hardware. Start with PC/mobile targets and port once your game is feature-complete.
Managing cross-platform code
Use conditional compilation symbols and shared projects to keep one codebase targeting multiple platforms.
Compiler directives
#if ANDROID
// Touch input only
TouchCollection touches = TouchPanel.GetState();
#elif IOS
// Touch with safe area awareness
TouchCollection touches = TouchPanel.GetState();
Rectangle safe = GraphicsDevice.Viewport.TitleSafeArea;
#elif WINDOWS
// Keyboard and mouse
KeyboardState kb = Keyboard.GetState();
MouseState mouse = Mouse.GetState();
#else
// DesktopGL (Linux, macOS, Windows)
KeyboardState kb = Keyboard.GetState();
#endif
Shared project structure
Create a shared .NET Standard library for all platform-agnostic game logic (ECS, physics, AI). Each platform project references the shared library and adds its own startup code.
MySolution/
|-- MyGame.Shared/ (netstandard2.0 - game logic, no platform code)
| |-- GameWorld.cs
| |-- Components/
| `-- Systems/
|-- MyGame.DesktopGL/ (mgdesktopgl - Windows/Linux/macOS)
| `-- Program.cs
|-- MyGame.WindowsDX/ (mgwindowsdx - Windows DirectX)
| `-- Program.cs
|-- MyGame.Android/ (mgandroid)
| `-- Activity1.cs
`-- MyGame.iOS/ (mgios)
`-- AppDelegate.cs
CI/CD and automated builds
Automate builds for every platform using GitHub Actions or similar CI services. Build DesktopGL on a Linux runner, WindowsDX on a Windows runner, and mobile on macOS for iOS support.
name: Build MonoGame
on: [push, pull_request]
jobs:
build-desktop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- run: dotnet build MyGame.DesktopGL/ -c Release
- run: dotnet publish MyGame.DesktopGL/ -c Release -o out/
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- run: dotnet build MyGame.WindowsDX/ -c Release
For publishing to Steam, itch.io, or app stores, see the Publishing Your Game guide.