muonline

MuOnline Clone

[![.NET Version](https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet)](https://dotnet.microsoft.com/download/dotnet/10.0) [![MonoGame](https://img.shields.io/badge/MonoGame-3.8+-E73C00?logo=nuget)](https://www.monogame.net/) [![License](https://img.shields.io/badge/License-Educational-blue)](#license) [![Build Status](https://github.com/xulek/muonline/workflows/Build%20and%20Publish/badge.svg)](https://github.com/xulek/muonline/actions) [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/xulek/muonline) **A cross-platform MuOnline client implementation built with .NET 10 and MonoGame framework.** [Features](#-features) • [Quick Start](#-quick-start) • [Building](#-building-the-project) • [Architecture](#-architecture-overview) • [Contributing](#-contributing)

⚠️ Educational Purpose Disclaimer This project is created strictly for educational and research purposes to explore game client architecture, network protocols, and cross-platform development with .NET and MonoGame. This is a non-commercial, open-source learning project that demonstrates reverse engineering and game development concepts.


Demo

https://youtu.be/_ekXCQI2byE


🎮 Features

📋 Prerequisites

Required Software

Component Version Download Link
.NET SDK 10.0+ Download
Git Latest Download
MuOnline Data Season 20 (1.20.61) Download
Data S6 Patch Season 6 Download

Platform-Specific Requirements

⊞ Windows - Windows 10/11 (64-bit) - Visual Studio 2022 (optional, for IDE support) **Graphics Backend Options:** - **OpenGL (MuWinGL)** - Better hardware compatibility, works on older GPUs - **DirectX 11 (MuWinDX)** - Better performance on modern hardware, Windows-only **Recommended:** Try DirectX first for best performance. Use OpenGL if you encounter graphics issues or have older hardware.
🐧 Linux - Compatible with most x64 distributions - Required packages: `libgdiplus`, `libopenal-dev` ```bash # Ubuntu/Debian sudo apt-get install libgdiplus libopenal-dev # Fedora sudo dnf install libgdiplus openal-soft-devel ```
🍎 macOS - macOS 11.0+ (Big Sur or later) - Xcode Command Line Tools ```bash xcode-select --install ``` - Optional: `wine` (if you want local MGCB shader/content compilation instead of prebuilt fallback)
📱 Android - Android SDK (API Level 21+) - Java Development Kit (JDK) 11 or later
📱 iOS - macOS with Xcode installed - Valid Apple Developer account (for device deployment) - iOS 10.0+ target

🚀 Quick Start

1️⃣ Clone the Repository

git clone https://github.com/xulek/muonline.git
cd muonline

2️⃣ Download Game Data

This client requires Season 20 (1.20.61) client data files for assets (models, textures, maps) but communicates using Season 6 protocol.

  1. Download: MU Red 1.20.61 Full Data
  2. Extract the archive to a location on your system
  3. Note the path to the Data folder

3️⃣ Configure Data Path

Open Client.Main/Constants.cs and update line 25:

// Windows
public static string DataPath = @"C:\Games\MU_Red_1_20_61_Full\Data";

// Linux/macOS
public static string DataPath = "/home/user/Games/MU_Red_1_20_61_Full/Data";

4️⃣ Configure Server Settings

Edit Client.Main/appsettings.json:

{
  "MuOnlineSettings": {
    "ConnectServerHost": "localhost",
    "ConnectServerPort": 44405,
    "ProtocolVersion": "Season6",
    "ClientVersion": "1.04d",
    "ClientSerial": "0123456789ABCDEF"
  }
}

This client is designed to work with OpenMU, an open-source MuOnline server implementation.

Quick Start with Docker:

# Download and run OpenMU server
curl -o docker-compose.yml https://raw.githubusercontent.com/MUnique/OpenMU/master/deploy/all-in-one/docker-compose.yml
docker-compose up -d

The server will be available at localhost:44405 (matches default client configuration).

Alternative: You can also connect to any Season 6 compatible MuOnline server.

6️⃣ Restore Tools & Build

# Restore .NET tools
dotnet tool restore

# Build the solution
dotnet build

7️⃣ Run the Client

# Windows (DirectX 11 - Recommended)
dotnet run --project ./MuWinDX/MuWinDX.csproj -f net10.0-windows -c Debug -p:MonoGameFramework=MonoGame.Framework.WindowsDX

# Windows (OpenGL - For compatibility)
dotnet run --project ./MuWinGL/MuWinGL.csproj -f net10.0-windows -c Debug -p:MonoGameFramework=MonoGame.Framework.DesktopGL

# Linux
dotnet run --project ./MuLinux/MuLinux.csproj -f net10.0 -c Debug

# macOS
dotnet run --project ./MuMac/MuMac.csproj -f net10.0 -c Debug

# macOS (force prebuilt content fallback)
dotnet run --project ./MuMac/MuMac.csproj -f net10.0 -c Debug -p:UsePrebuiltContent=true

🔨 Building the Project

Project Structure

muonline/
├── Client.Data/           # Data file readers (BMD, ATT, MAP, OZB, etc.)
├── Client.Main/           # Core game engine, networking, UI, game logic
│   ├── Client.Main.Shared.props   # shared settings
│   ├── Client.Main.*.csproj      # platform variants: desktop/windows/android/ios
├── Client.Data/           # data processing (platform variants)
│   ├── Client.Data.Shared.props
│   ├── Client.Data.*.csproj
├── Client.Editor/         # Asset editor tool
├── MuWinGL/               # Windows OpenGL executable (MonoGame.Framework.DesktopGL)
├── MuWinDX/               # Windows DirectX 11 executable (MonoGame.Framework.WindowsDX)
├── MuAndroid/             # Android executable project
├── MuIos/                 # iOS executable project
├── MuLinux/               # Linux executable project
└── MuMac/                 # macOS executable project

Development Builds (per head)

For predictable restores and to avoid missing workloads, build/clean one head at a time.

# Windows DirectX (Recommended)
dotnet clean MuWinDX/MuWinDX.csproj && dotnet build MuWinDX/MuWinDX.csproj -c Debug -p:MonoGameFramework=MonoGame.Framework.WindowsDX

# Windows OpenGL
dotnet clean MuWinGL/MuWinGL.csproj && dotnet build MuWinGL/MuWinGL.csproj -c Debug -p:MonoGameFramework=MonoGame.Framework.DesktopGL

# Linux
dotnet clean MuLinux/MuLinux.csproj && dotnet build MuLinux/MuLinux.csproj -c Debug

# macOS
dotnet clean MuMac/MuMac.csproj && dotnet build MuMac/MuMac.csproj -c Debug

# macOS (force prebuilt content fallback)
dotnet clean MuMac/MuMac.csproj && dotnet build MuMac/MuMac.csproj -c Debug -p:UsePrebuiltContent=true

# Android (requires Android workload)
dotnet workload restore
dotnet clean MuAndroid/MuAndroid.csproj && dotnet build MuAndroid/MuAndroid.csproj -c Debug

# iOS (requires macOS + Xcode + iOS workload)
dotnet workload restore
dotnet clean MuIos/MuIos.csproj && dotnet build MuIos/MuIos.csproj -c Debug

Production Builds

Build outputs are placed in bin/Release/ directories.

Windows

For the maximum-performance DirectX build, use the validated publish script:

./scripts/publish/windows-performance.ps1

The script publishes a self-contained win-x64 folder build with ReadyToRun, tiered compilation, dynamic PGO, optimized shaders, disabled runtime diagnostics, and a SHA-256 manifest. It also validates the generated runtime configuration before creating the archive.

A diagnostic Release build can be produced without the compile-time performance profile:

dotnet publish ./MuWinDX/MuWinDX.csproj -c Release -r win-x64 -p:PerformanceRelease=false

OpenGL remains available as the compatibility backend:

dotnet publish ./MuWinGL/MuWinGL.csproj -c Release -r win-x64 -o publish-gl -p:MonoGameFramework=MonoGame.Framework.DesktopGL

The GitHub Actions workflow automatically builds both Windows versions (OpenGL and DirectX) on every push to main and publishes them to GitHub Pages.

Linux

dotnet publish ./MuLinux/MuLinux.csproj -f net10.0 -c Release -r linux-x64 --self-contained

macOS

dotnet publish ./MuMac/MuMac.csproj -f net10.0 -c Release

# Force prebuilt content fallback during publish
dotnet publish ./MuMac/MuMac.csproj -f net10.0 -c Release -p:UsePrebuiltContent=true

macOS Content Build Modes (Wine vs Prebuilt)

MuMac.csproj supports two content workflows:

How it works:

To prepare prebuilt content:

  1. Build content on a machine/CI where MGCB shader compilation works (typically Windows or macOS with wine).
  2. Copy generated DesktopGL .xnb files into:
    • Client.Main/MGContent/PrebuiltContent/DesktopGL/Content
  3. Keep this folder synchronized with Client.Main/MGContent/Content.mgcb.

Android

dotnet publish ./MuAndroid/MuAndroid.csproj -f net10.0-android -c Release \
  -p:AndroidSdkDirectory="<path-to-android-sdk>" \
  -p:JavaSdkDirectory="<path-to-jdk-11>" \
  -p:AcceptAndroidSdkLicenses=True

iOS

# Requires macOS with Xcode and valid signing certificates
dotnet publish ./MuIos/MuIos.csproj -f net10.0-ios -c Release

🏗️ Architecture Overview

High-Level Design

This project implements a layered architecture with clear separation of concerns:

┌─────────────────────────────────────────────────────────┐
│                    Platform Layer                       │
│  (MuWinGL/MuWinDX, MuLinux, MuMac, MuAndroid, MuIos)    │
└─────────────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────────────┐
│                  Client.Main (Core)                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │    Scenes    │  │  Networking  │  │   Rendering  │   │
│  │ (Login/Game) │  │   (S6 Proto) │  │  (MonoGame)  │   │
│  └──────────────┘  └──────────────┘  └──────────────┘   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │ Game Objects │  │  UI System   │  │ World System │   │
│  │(Player/NPC)  │  │ (GameControl)│  │  (Terrain)   │   │
│  └──────────────┘  └──────────────┘  └──────────────┘   │
└─────────────────────────────────────────────────────────┘
                           ↓
┌─────────────────────────────────────────────────────────┐
│              Client.Data (Data Readers)                 │
│      BMD • ATT • MAP • OZB • OZG • CWS • OBJS           │
└─────────────────────────────────────────────────────────┘

Key Systems

🎬 Scene Management

🌐 Networking

🎮 Game Objects

🖼️ UI System

⚡ Threading Model

📁 File Format Support

Format Description Usage
BMD 3D models and skeletal animations Characters, monsters, items, NPCs
ATT Terrain walkability attributes Collision detection, pathfinding
MAP Terrain heightmap data 3D terrain rendering
OZB/OZG Compressed texture formats Textures for models and UI
CWS Camera walk/pan scripts Cinematic camera movements
OBJS Object placement data Map decorations and static objects

🔧 Configuration

Constants.cs (Client.Main/Constants.cs:25)

Debug vs Release builds have different configurations:

Debug Settings:

Release Settings:

Rendering Options:

appsettings.json (Client.Main/appsettings.json)

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Client.Main.Networking": "Trace"
    }
  },
  "MuOnlineSettings": {
    "ConnectServerHost": "localhost",
    "ConnectServerPort": 44405,
    "ProtocolVersion": "Season6",
    "ClientVersion": "1.04d",
    "ClientSerial": "0123456789ABCDEF",
    "Graphics": {
      "Width": 1280,
      "Height": 720,
      "IsFullScreen": false,
      "UiVirtualWidth": 1280,
      "UiVirtualHeight": 720
    }
  }
}

🎨 Graphics Backend Comparison

Windows: OpenGL vs DirectX 11

Feature OpenGL (MuWinGL) DirectX 11 (MuWinDX)
Performance Good Excellent (modern GPUs)
Compatibility Excellent (older hardware) Windows 10/11 only
Shader Model 3.0 (vs_3_0/ps_3_0) 4.0 (vs_4_0/ps_4_0)
Visual Quality Identical Identical
Cross-Platform Yes (same as Linux/macOS) Windows-only
Stability Very stable Stable (fixed GPU sync issues)

When to Use OpenGL (MuWinGL)

When to Use DirectX (MuWinDX)

Technical Notes

Both versions produce identical visual results but use different rendering paths:

Shader Compatibility:

Known Fixed Issues (DirectX):

🐛 Troubleshooting

❌ "Data path not found" error **Solution:** Ensure `Client.Main/Constants.cs` has the correct path to your MU data files. ```csharp public static string DataPath = @"C:\Games\MU_Red_1_20_61_Full\Data"; ``` Verify the path exists and contains files like `Data/Player.bmd`, `Data/Item`, etc.
❌ Cannot connect to server **Solution:** Check the following: 1. Server is running (for OpenMU: `docker ps` should show running containers) 2. `appsettings.json` has correct host/port 3. Firewall isn't blocking port 44405 4. Protocol version matches server (Season6)
❌ Black screen / Graphics not loading **Solution:** 1. Verify data files are complete (re-extract if needed) 2. Check `Constants.cs` shader settings: ```csharp public const bool ENABLE_DYNAMIC_LIGHTING_SHADER = true; ``` 3. Update graphics drivers 4. Try disabling MSAA in Constants.cs 5. **If using DirectX:** Try the OpenGL version (MuWinGL) instead
❌ DirectX: Graphics glitches, objects flickering or "exploding" **Solution:** These issues have been fixed in the latest version. If you still experience them: 1. **Update to latest version** from GitHub 2. **Clean build:** ```bash dotnet clean ./MuWinDX/MuWinDX.csproj dotnet build ./MuWinDX/MuWinDX.csproj -p:MonoGameFramework=MonoGame.Framework.WindowsDX ``` 3. **Try OpenGL version** as fallback: ```bash dotnet run --project ./MuWinGL/MuWinGL.csproj -f net10.0-windows -c Debug -p:MonoGameFramework=MonoGame.Framework.DesktopGL ``` **What was fixed:** - GPU/CPU race conditions in dynamic buffer pooling - Vertex declaration mismatches in custom shaders - Async loading deadlocks in inventory rendering
❌ DirectX: Client freezes when opening inventory **Solution:** Fixed in latest version. The issue was caused by async model loading blocking the main thread. If still experiencing freezes: 1. Update to latest code 2. Verify you're using the fixed `BmdPreviewRenderer.cs` (checks `modelTask.IsCompleted`) 3. Switch to OpenGL version temporarily
❌ Linux: "libopenal.so not found" **Solution:** ```bash # Ubuntu/Debian sudo apt-get install libopenal-dev libgdiplus # Fedora sudo dnf install openal-soft-devel libgdiplus ```
❌ macOS: MGCB fails with "Wine is not installed" **Solution options:** 1. Install `wine` and build normally: ```bash dotnet build ./MuMac/MuMac.csproj -c Debug ``` 2. Use prebuilt fallback mode: ```bash dotnet build ./MuMac/MuMac.csproj -c Debug -p:UsePrebuiltContent=true ``` If using fallback mode, ensure `.xnb` files exist in: - `Client.Main/MGContent/PrebuiltContent/DesktopGL/Content`
❌ Build errors on mobile platforms **Solution:** For desktop development, disable mobile targets: ```bash dotnet build /p:EnableMobileTargets=false ```

🤝 Contributing

Contributions are welcome! This is an educational project, and we encourage learning and experimentation.

Guidelines

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Code Style

Reporting Issues

Found a bug or have a question? Open an issue on GitHub.

📚 Additional Resources

📄 License

This project is created for educational and research purposes only.

Protocol Implementation: The Season 6 network protocol implementation is based on publicly available information and reverse engineering for educational purposes.

Recommended Use Cases:


**Made with ❤️ for the game development community** [⬆ Back to Top](#muonline-clone)