Next Generation Mahjong AI Assistant
Inspired by Akagi and MajsoulHelper
「死ねば助かるのに……」— 赤木しげる
简体中文 | English
Akagi-NG is the next-generation rewrite of the original Akagi project.
It is an AI-powered assistant designed for Japanese Mahjong (Riichi Mahjong), aimed at providing real-time situation analysis and decision recommendations for online Mahjong games.
Core Philosophy of Akagi-NG:
- Modern Architecture: Rebuilt based on Electron-native architecture, Python 3.12 and React/Vite
- Decoupled Design: Complete separation of core logic, user interface, configuration management, and AI models
- High-Performance Inference: Integrated
libriichifor blazing fast Mortal model inference capabilities - Long-term Maintainability: Optimized code structure for continuous iteration
The graph below is the overall data flow of Akagi-NG in Electron desktop / MITM modes.
Components:
-
Dual-Mode Interceptor: Provides two methods for game data acquisition
- Desktop Mode: Intercepts game communication via built-in Chromium browser + resource hooks, no proxy/certificate configuration needed
- MITM Mode: Intercepts traffic from external browsers/clients via mitmproxy, supports third-party devices
-
Python Backend (DataServer): Core data processing hub
- Protocol Bridge: Converts Mahjong Soul protocol to MJAI standard format
- State Tracker Bot: Maintains complete game state machine
- AI Controller: Manages AI model and Lookahead algorithm, provides decision recommendations
- SSE Event Stream: Pushes AI decisions to frontend in real-time via Server-Sent Events
-
Electron Frontend: User interface and window management
- Main Process: Manages backend process and coordinates multiple windows
- Dashboard: Provides configuration management and game launch entry
- HUD Overlay: Transparent overlay window displaying AI recommendations in real-time
-
Game Window: Final game presentation layer
- In Desktop Mode: Chromium instance managed by Electron
- In MITM Mode: User's own browser or game client
Data Flow:
- Game Server → Interceptor: Raw game data transmitted via WebSocket
- Interceptor → Python Backend: Converted to MJAI event format
- Python Backend Processing: State tracking + AI decision computation
- Python Backend → Electron: Pushes decision results via SSE
- HUD Overlay: Displays AI suggestions overlaid on game window
graph TB
%% Game Server
GS["Game Server<br/>"]
%% Dual Mode Entry
subgraph Modes ["Dual-Mode Interceptor"]
direction LR
DesktopMode["Desktop Mode<br/>Built-in Chromium + Hook"]
MitmMode["MITM Mode<br/>mitm-proxy"]
end
%% Python Backend Core
subgraph Backend ["Python Backend"]
direction TB
Bridge["Protocol Bridge<br/>(MJAI Adapter)"]
Bot["State Tracker Bot<br/>(Game State)"]
Controller["AI Controller<br/>(Mortal + Lookahead)"]
SSE["SSE Event Stream<br/>(Real-time Push)"]
Bridge --> Bot
Bridge --> Controller
Bot --> SSE
Controller --> SSE
end
%% Electron Frontend
subgraph Frontend ["Electron Frontend"]
direction TB
MainProcess["Main Process<br/>(Backend Manager + Window Manager)"]
Dashboard["Dashboard<br/>(React UI)"]
HUD["HUD Overlay<br/>(Transparent Layer)"]
MainProcess -- "Window Management" --> Dashboard
MainProcess -- "Window Management" --> HUD
end
%% Game Window
GameWin["Game Window<br/>(Chromium Instance or Client)"]
%% Data Flow
GS <-- "Game Data" --> DesktopMode
GS <-- "Game Data" --> MitmMode
DesktopMode -- "MJAI Events" --> Bridge
MitmMode -- "MJAI Events" --> Bridge
SSE -- "SSE Connection" --> Dashboard
SSE -- "AI Decisions" --> HUD
Dashboard -- "IPC" --> MainProcess
MainProcess -- "Window Management (Desktop Mode Only)" --> GameWin
HUD -- "Visual Overlay" --> GameWin
%% Styling
classDef serverStyle fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef modeStyle fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef backendStyle fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef frontendStyle fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef gameStyle fill:#fff3e0,stroke:#ef6c00,stroke-width:3px
class GS serverStyle
class DesktopMode,MitmMode modeStyle
class Bridge,Bot,Controller,SSE backendStyle
class MainProcess,Dashboard,HUD frontendStyle
class GameWin gameStyle
-
🎮 Supported Platforms
- Mahjong Soul
- Tenhou
- Riichi City
- Amatsuki Mahjong
-
🀄 Supported Modes
- Four-Player Mahjong (4p)
- Three-Player Mahjong (3p)
-
🤖 AI Models
- Mortal (Mortal 4p / Mortal 3p)
- AkagiOT (AkagiOT 4p / AkagiOT 3p)
-
🧠 Core Functions
- Real-time hand analysis and AI discard recommendations
- Riichi Lookahead - Intelligent recommendation for the best discard after reaching
- Comprehensive Fuuro Support - Clear action prompts for Chi, Pon, and all Kan variants
- Modern Glassmorphism HUD - Smooth and unobtrusive floating window experience
- Multi-language support - Simplified Chinese / Traditional Chinese / Japanese / English
Note
Riichi Lookahead is a core feature in Akagi-NG, designed to solve the question: "When AI suggests Riichi, which tile should I discard?"
Click to view detailed logic of Riichi Lookahead
1. Why do we need it?
When the MJAI engine (such as Mortal) suggests a reach operation, the protocol only returns the action {"type": "reach"}. It does not directly tell us which tile to discard after declaring Riichi (e.g., 6m).
However, for the user, after clicking the "Riichi" button, a tile must be discarded. Without Lookahead, the user can only guess or judge which tile to cut themselves, which may lead to deviations from the AI's intended strategy (e.g., discarding the wrong tile resulting in furiten or dealing into another player's hand).
2. How it works
The core idea of Lookahead is "Simulating the Future". When the AI suggests Riichi, we create a temporary parallel universe, assume the player has declared Riichi, and then ask the AI what it would discard in that state.
The process is divided into the following steps:
- Trigger: In the current situation, the AI engine infers that
Riichiis one of the top 5 best actions. - Start Simulation: Akagi-NG creates a new, temporary
Simulation Bot. - History Replay:
- In order for the simulation bot to reach the current game state, we need to feed it all events that have occurred from the beginning of the game to the present (draws, discards, calls, etc.).
- Old Mechanism: When replaying every move of "my own actions", the simulation bot would foolishly ask the AI engine: "What should I do now?". This meant that if a game was in the 15th turn, Lookahead would need to perform 15+ AI inferences. For Online mode, this meant 15 HTTP requests, instantly triggering a 429 ban.
- New Mechanism (ReplayEngine): We now use the
ReplayEnginewrapper. During the replay phase, we explicitly know that this is just "retelling history", so when the simulation bot asks "What should I do now?",ReplayEnginedirectly returns a dummy action (such astsumogiri), completely skipping AI inference. This makes the replay process almost instantaneous and with zero network cost.
- Branching:
- When the state is fully restored to "now", we manually send a
Riichievent to the simulation bot. - At this point, the internal state of the simulation bot becomes: "The player has just declared Riichi and is waiting to discard a tile".
- When the state is fully restored to "now", we manually send a
- Final Inference:
- In this new "Declared Riichi" state, we initiate a real inquiry to the AI engine: "Which is the best discard now?"
- The engine analyzes the situation and returns a specific discard action (e.g.,
discard 6m).
- Result Display: The frontend UI receives this
6minformation. The interface will highlight Riichi and other discard recommendations (such asdamaten). It will also display the recommended discard tile6min the Riichi recommendation sub-item. If there is more than one Riichi discard candidate, the sub-items will display each Riichi discard tile and its confidence respectively.
akagi_ng_demo_en.mp4
This project is for educational and research purposes only.
Using third-party auxiliary tools in online games may violate the game's Terms of Service. The authors and contributors of Akagi-NG are NOT responsible for any consequences, including but not limited to account bans or suspensions.
Please fully understand and assume the relevant risks before use.
- Download: Go to Releases and download the latest version, then extract it.
- Deploy: Place AI model weight files (
.pth) in themodels/directory, and binary extensions (.pyd/.so) in thelib/directory. - Run: Double-click
Akagi-NG.exe. - Play: Click "Launch Game" in the Dashboard and click the monitor icon at the top right to enable HUD.
To ensure the program runs correctly, please verify the directory structure where Akagi-NG.exe is located:
Akagi-NG/
├── Akagi-NG.exe # Main Application (Electron Desktop)
├── assets/ # Platform-specific UI assets
├── bin/ # Backend core executable directory
├── config/ # Configuration directory (settings.json)
├── lib/ # libriichi binary extensions (.pyd/.so)
│ ├── libriichi.pyd
│ └── libriichi3p.pyd
├── locales/ # Localization resource files
├── logs/ # Runtime log directory
├── models/ # AI model weight files (.pth)
│ ├── mortal.pth
│ └── mortal3p.pth
├── resources/ # Electron core resources (app.asar)
├── LICENSE.txt # Open source license
├── README.txt # Quick start plain text guide
└── ... # Other runtime files (.dll, .pak, etc.)
When running Akagi-NG.exe for the first time, the integrated dashboard will appear. You can start the game directly from the dashboard to launch a dedicated browser window. Click the monitor icon in the top right of the dashboard to open the HUD overlay.
To exit the program, click the red power icon in the dashboard.
Tip
HUD (Heads-Up Display) is a new feature in Akagi-NG, providing a sleek, translucent overlay directly on your game window without manual window sticking.
All configurations for Akagi-NG are located in the config/settings.json file. You can click the gear icon in the top right of the dashboard to enter the settings panel to modify them, or use a text editor to modify this file to adjust program behavior.
This is the default working mode of Akagi-NG.
In this mode, Akagi-NG leverages its Electron core to manage a specialized Chromium instance for the game.
-
Key Features:
- Zero Config: No certificates or proxy settings needed.
- Environment Isolation: Completely isolated from your daily used browser.
- Safe and Stable: Receives data from the game server directly.
-
Usage:
- Run
Akagi-NG.exe. - Click "Launch Game" in the dashboard.
- Run
Akagi-NG supports intercepting game data via Man-in-the-Middle (MITM) attack. This allows you to play using any browser, client or on a mobile device (with proxy configured).
-
Enable Configuration: Switch on "External Proxy" in the configuration panel or modify the
mitmfield inconfig/settings.json:"mitm": { "enabled": true, "host": "127.0.0.1", "port": 6789 }
-
Set Proxy: Set your browser or system proxy to
127.0.0.1:6789. -
Install Certificate:
Note: If you use Scheme B (Clash splitting), you may be unable to open
mitm.it. Method 2 is recommended.-
Method 1: Online Installation (Recommended for Scheme A Users)
- Start Akagi-NG.
- Visit http://mitm.it.
- Download the Windows certificate (p12 or cer).
-
Method 2: Local Installation (Recommended for Scheme B Users)
- Find the
.mitmproxyfolder under the user directory (e.g.,C:\Users\<YourName>\.mitmproxy). - Double-click
mitmproxy-ca-cert.p12to install.
- Find the
-
Critical Step:
- Double-click certificate -> Install Certificate -> Select Store Location "Trusted Root Certification Authorities".
-
Warning
Be sure to install the certificate into "Trusted Root Certification Authorities".
Q: I launched the program for the first time, but it hangs on the welcome/loading screen. What should I do?
A: This is usually caused by a conflict with the DataServer's default port 8765.
Solution:
- Open
config/settings.json. - Find
"server": { "port": 8765 }and change8765to another available port (e.g.,8888). - Restart the program.
Q: I am using proxy software like Clash/v2rayN (TUN/System Proxy mode), how should I configure it?
Click to view detailed proxy split configuration schemes
This scheme is suitable for Web version players, configuration is simplest and completely isolated.
Configuration Steps (Taking Clash Verge Tun mode as an example):
-
Prepare Environment:
- Keep Clash Verge Tun mode ON.
- Ensure Akagi-NG is started and
mitm.enabledistrue(default port 6789).
-
Install SwitchyOmega:
- Chrome/Edge users please search regarding "SwitchyOmega" in the store and install it.
-
Configure Profile:
- Open SwitchyOmega settings interface.
- Click "New Profile" on the left -> Name it
Akagi-Mitm-> Select type "Proxy Profile". - In
Akagi-Mitmsettings:- Protocol:
HTTP - Server:
127.0.0.1 - Port:
6789
- Protocol:
- Click "Apply Changes" on the left to save.
-
Configure Auto Switch (Critical):
- Click "Auto Switch" on the left.
- Delete all existing rules (if any).
- Add Rules:
- Rule condition:
*.maj-soul.com -> Akagi-Mitm - Rule condition:
*.majsoul.com -> Akagi-Mitm - Rule condition:
*.mahjongsoul.com -> Akagi-Mitm
- Rule condition:
- Default Rule:
- Select "Direct", then click "Apply Changes" to save.
[!TIP] Because your system has Tun mode enabled, "Direct" traffic will be automatically taken over and proxied by the Tun network card, so you don't need to select "System Proxy" or "Clash" here.
[!IMPORTANT] If you don't enable Tun mode and only enabled System Proxy, please select "System Proxy" here.
- Start Game:
- Click the SwitchyOmega icon in the upper right corner of the browser and select "Auto Switch".
- Visit Mahjong Soul web version, Akagi-NG should be able to capture game events normally, while you can still access Google/YouTube (via Tun).
This scheme is suitable for PC/Steam Client players. Since the client cannot use plugins for splitting like a browser, we need to directly modify the Clash configuration to forward game traffic to Akagi-NG.
[!IMPORTANT] When playing with the PC/Steam client, please ensure Clash is in TUN mode, otherwise it will not be able to proxy client traffic.
-
Find Configuration Entry:
- Find your configuration file in Clash Verge (or use "Merge" / "Script" function to inject, to avoid overwriting the original configuration).
-
Add Proxy Node (Proxies): Define a node pointing to the Akagi-NG local proxy.
proxies: - name: Akagi-Mitm type: http server: 127.0.0.1 port: 6789 tls: false
You can also define a proxy group (Proxy-groups) containing the local proxy node and Direct, making it convenient to toggle whether to use the Akagi-NG local proxy.
proxy-groups: - name: 🀄 Mahjong Soul proxies: - Akagi-Mitm - DIRECT type: select
-
Add Splitting Rules (Rules): Force Mahjong Soul related domains to point to the node defined above. Please note the rule order, it is recommended to place them near the top.
rules: - PROCESS-NAME,akagi-ng.exe,DIRECT - PROCESS-NAME,雀魂麻將,🀄 Mahjong Soul - PROCESS-NAME,Jantama_MahjongSoul.exe,🀄 Mahjong Soul - DOMAIN-Keyword,maj-soul,🀄 Mahjong Soul
-
Apply Configuration: Save and refresh the Clash configuration. Now start the Mahjong Soul client, the traffic path is:
Mahjong Soul Client -> Clash (TUN) -> Matches Rules -> Forward to Akagi-NG (6789) -> Your Network/Upstream Proxy
- Python 3.12+: Required for the backend engine.
- Node.js 24+ & npm: Required for the Electron desktop and React frontend.
- Git: For cloning the repository.
- Windows: Recommended development and build platform.
Clone the repository and initialize the project:
git clone https://github.com/Xe-Persistent/Akagi-NG.git
cd Akagi-NGThe integrated build system expects a virtual environment in the akagi_backend directory:
cd akagi_backend
python -m venv .venv
# Windows
.\.venv\Scripts\activate
# Linux/macOS
source .venv/bin/activate
pip install -e .
cd ..# Install frontend dependencies
cd akagi_frontend
npm install
# Install electron desktop dependencies
cd ../electron
npm installTo launch the integrated development environment:
cd electron
npm run devTo package the application for your current platform:
cd electron
npm run buildThe build artifacts will be generated in the dist/release directory.
Important
The build process packages the application core. You still need to ensure that AI model weight files (.pth) are placed in the models/ directory and binary extensions (.pyd/.so) are in the lib/ directory of the release folder for the program to function.
This software follows the GNU Affero General Public License version 3 (AGPLv3) open source protocol.