Skip to content

MahJax UI Guide

MahJax ships with a FastAPI backend and a static JS frontend, so you can battle the bundled mahjax.no_red_mahjong bots in any browser. This guide shows the basics for running the UI in a release setting.

Quickstart

pip install mahjax
uvicorn mahjax.ui.app:create_app --host 0.0.0.0 --port 8000

You need Python 3.10+. Use --reload while developing but turn it off in production.

Core Features

  • Instant play – the UI only shows legal actions, so every human move is valid.
  • Bilingual board – the backend sends both Japanese and English SVGs, and the toggle swaps between them without extra requests.
  • Round insight – modal summaries list winners, yaku, fan/fu, honba, kyotaku, plus a 50-entry action log.
  • Observer toggle – hide enemy hands until a non-human Ron/Tsumo or the round end reveals them.
  • Pluggable agents – register Python callables with AgentRegistry (ships with Rule-based and Random) and they show up right away in /api/agents.

Using the UI

  • Header controls: choose the agent, match length (single, east, or half), seat (fixed or random), optional seed, display names, AI delay in ms, and whether to hide opponent hands. The Start and End buttons spawn or delete sessions.
  • Board & actions: the human seat stays at the bottom. Tile buttons map to discard IDs (0–33). Extra buttons cover riichi, tsumo, ron, pass, kan, pon, and chi. If only a dummy action remains, an “Advance” button sends Action.DUMMY.
  • Scoreboard & log: scores use turn order relative to the human and display current deltas. Logs show discards, calls, and declarations.
  • Round summaries: when _terminated_round flips on, the server returns roundSummary, and the UI shows standings plus winner info. Press “Next Round,” or “End Game” if isGameEnd is true.

Extending Agents & UI

  • Custom Agents: Register new agents using AgentRegistry. Your agent must be a callable accepting (state, rng) and returning a valid action ID.
  • Frontend Customization: Edit mahjax/ui/static/app.js and styles.css directly. No Node.js build step is required.

Adding Custom Agents

To add your own agent to the dropdown menu, create a wrapper script that registers your agent function before starting the app.

  1. Define your agent: Create a function (state, rng) -> int.
  2. Register and Run:
# my_ui_app.py
from pathlib import Path
from mahjax.ui.app import create_app

app = create_app()

# Register your agent implementation
app.state.manager.registry.load_callable_from_path(
    file_path=Path("path/to/my_agent_impl.py"),
    attribute="act",  # Function name in your file
    description="My Custom Agent"
)
  1. Run uvicorn my_ui_app:app --host 0.0.0.0 --port 8000. The agent now appears in /api/agents, so the UI selector lists it right away.

Troubleshooting & Limits

  • Blank board? Confirm mahjax/ui/static exists and FastAPI mounts it. Check the console for /static 404 errors.
  • Buttons stuck? The game is in awaiting_ai or round_end. Wait for auto-play or dismiss the summary modal.
  • AI idle? Check ai_delay_ms and watch /api/game/{id}/auto responses.
  • Hidden hands never reveal? Clear the checkbox or note that only non-human wins unhide opponents.
  • The current build only supports 4-player Riichi without red dora and runs without auth. Protect it behind a reverse proxy or VPN before exposing it to the internet.