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:

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

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

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

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)

PlayStation

Nintendo Switch

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.