[모비노기] 마비노기 모바일 일본판(PC) 리눅스 구동 설정 가이드
한동안 관심을 끊고 살았더니 마비노기 모바일이 일본에서도 런칭된걸 이제야 알아서 리눅스(아치리눅스계 CachyOS)에서 설치해 봄.
먼저 NGM을 설치, 마비노기 모바일 클라이언트도 설치하고 아래 가이드를 읽을 것.
[모비노기] 모비노기 설치를 위한 넥슨 게임 매니저(NGM) 설치 가이드
본 문서는 리눅스(CachyOS/Arch, KDE Wayland) 환경에서 마비노기 모바일 일본판(マビノギモバイル) PC 버전을 Wine으로 설치하고, 일본 넥슨 공식 웹사이트를 통해 정상 실행하기 위해 필요한 구성 요소와 설정 절차를 정리한 매뉴얼입니다.
1. 기본 환경 및 사전 요구사항
- 운영체제: Arch Linux 계열 (CachyOS 등), KDE Plasma
- Wine Runner: GE-Proton11-11-x86_64 권장 (
~/.local/share/Steam/compatibilitytools.d/GE-Proton11-11-x86_64/files/bin/wine) - Wine Prefix:
/home/elmitash/Games/mobinogi - 게임 설치 경로:
drive_c/Nexon/MabinogiMobile_JP/MabinogiMobile.exe
2. 세부 설정 절차
1) 일본어 로케일(ja_JP.UTF-8) 준비
호스트 OS가 한국어 로케일인 경우, 게임 클라이언트가 일본 서비스 환경으로 구동될 수 있도록 사용자 계정에 ja_JP.UTF-8 로케일을 빌드합니다.
mkdir -p ~/.locale
localedef -f UTF-8 -i ja_JP ~/.locale/ja_JP.UTF-8
2) 웹 브라우저 프로토콜 핸들러 등록
공식 웹사이트에서 [ゲームスタート] 클릭 시 전달되는 ngm://launch/... 요청을 리눅스 런처 스크립트로 전달하기 위한 데스크톱 파일을 생성합니다.
파일 경로: ~/.local/share/applications/ngm-handler.desktop
[Desktop Entry]
Type=Application
Name=Nexon Game Manager Handler
Exec=/home/elmitash/Games/mobinogi/launch_ngm.sh %u
StartupNotify=false
NoDisplay=true
MimeType=x-scheme-handler/ngm;
핸들러 등록 및 MIME 데이터베이스 갱신:
xdg-mime default ngm-handler.desktop x-scheme-handler/ngm
update-desktop-database ~/.local/share/applications/
3) 런처 브릿지 스크립트 작성
웹 브라우저의 웹 토큰(ias:wt:...)을 기반으로 넥슨 공식 IAS API에서 정식 일회용 게임 티켓(ias:t:...)을 실시간 수령하고, Wine 환경에서 게임을 기동하는 스크립트입니다.
파일 경로: /home/elmitash/Games/mobinogi/launch_ngm.sh
#!/bin/bash
RAW_URI="$1"
echo "========================================================" >> /tmp/launch_ngm.log
echo "[$(date '+%Y-%m-%d %H:%M:%S')] NGM Handler Triggered" >> /tmp/launch_ngm.log
echo "RAW_URI: $RAW_URI" >> /tmp/launch_ngm.log
python3 - << 'PYEOF' "$RAW_URI" >> /tmp/launch_ngm.log 2>&1
import sys, urllib.parse, urllib.request, subprocess, os, re, time, json
raw = sys.argv[1] if len(sys.argv) > 1 else ""
decoded = urllib.parse.unquote(raw)
if not decoded.startswith("ngm://"):
print(f"Invalid URI format: {decoded[:100]}")
sys.exit(1)
def get_arg(name, text):
m = re.search(r"-" + name + r":'([^']*)'", text)
if m: return m.group(1)
m = re.search(r"-" + name + r":([^\s]+)", text)
if m: return m.group(1)
return ""
token = get_arg("token", decoded)
insign_raw = get_arg("insign_token", decoded)
game = get_arg("game", decoded)
publisher = get_arg("publisher", decoded)
webtoken = ""
gid = "2943"
if insign_raw:
try:
insign_obj = json.loads(insign_raw)
webtoken = insign_obj.get("webtoken", "")
gid = str(insign_obj.get("gid", "2943"))
except Exception as e:
print("Failed to parse insign_token JSON:", e)
# 1. 넥슨 IAS API를 통한 정식 게임 티켓 실시간 발급
ias_ticket = ""
if webtoken:
try:
ias_url = "https://public.api.nexon.com/ias/live/public/v3/issue/ticket/by-web-token"
req_body = json.dumps({"gid": gid}).encode("utf-8")
req = urllib.request.Request(
ias_url,
data=req_body,
headers={
"Content-Type": "application/json",
"x-ias-web-token": webtoken,
"User-Agent": "inface-sdk"
},
method="POST"
)
with urllib.request.urlopen(req, timeout=10) as resp:
resp_data = json.loads(resp.read().decode("utf-8"))
ias_ticket = resp_data.get("ticket", "")
print(f"[IAS] Successfully issued IAS ticket: {ias_ticket[:45]}...")
except Exception as e:
print(f"[IAS] Error issuing ticket: {e}")
nexonsn_int = 0
if token.startswith("NP12:"):
parts = token.split(":")
if len(parts) >= 4 and parts[3].isdigit():
nexonsn_int = int(parts[3])
obd_code = "67c4"
if "@" in game:
obd_code = game.split("@")[1]
session_id_int = int(time.time() * 1000) % 1000000000000
locale = "JP"
# 2. 게임 실행 인자 및 환경변수 구성
nx_args = {
"passport": token,
"ticket": ias_ticket,
"a2sk": "",
"locale": locale,
"nxlog_session_id": session_id_int,
"nexon_sn": nexonsn_int,
"gid": gid,
"obd_code": obd_code,
"obd_tag": "818",
"obd_env": "live",
"manifest_name": "MabinogiMobile_JP",
"insign_webtoken": webtoken,
"execution_info": ""
}
cmdline_arg = (
f"{{ticket:{ias_ticket},passport:{token},a2sk:,locale:{locale},"
f"nxlogsessionid:{session_id_int},nexonsn:{nexonsn_int},executioninfo:}}"
)
wine_bin = "/home/elmitash/.local/share/Steam/compatibilitytools.d/GE-Proton11-11-x86_64/files/bin/wine"
game_exe = "/home/elmitash/Games/mobinogi/drive_c/Nexon/MabinogiMobile_JP/MabinogiMobile.exe"
env = os.environ.copy()
env["WINEPREFIX"] = "/home/elmitash/Games/mobinogi"
env["LOCPATH"] = "/home/elmitash/.locale"
env["LANG"] = "ja_JP.UTF-8"
env["LC_ALL"] = "ja_JP.UTF-8"
env["DXVK_LOG_LEVEL"] = "none"
env["STAGING_SHARED_MEMORY"] = "1"
env["WINE_LARGE_ADDRESS_AWARE"] = "1"
env["NXPlatformArgs"] = json.dumps(nx_args)
stdout_log = open("/tmp/mabinogi_stdout.log", "w")
cmd = [
wine_bin,
game_exe,
cmdline_arg,
"-logFile",
"C:\\users\\steamuser\\AppData\\LocalLow\\devCAT\\マビモバ\\unity_output.log"
]
print(f"[EXEC] Spawning MabinogiMobile.exe...")
# start_new_session=True로 런처 스크립트 종료 후에도 프로세스 유지
subprocess.Popen(cmd, env=env, stdout=stdout_log, stderr=stdout_log, start_new_session=True)
print(f"[EXEC] Process spawned successfully.")
PYEOF
스크립트에 실행 권한을 부여합니다:
chmod +x /home/elmitash/Games/mobinogi/launch_ngm.sh
3. 게임 실행 방법
- 브라우저로 마비노기 모바일 일본 공식 홈페이지에 로그인합니다.
- 메인 페이지의 [ゲームスタート (게임 시작)] 버튼을 클릭합니다.
- 브라우저 프롬프트 창에서
Nexon Game Manager Handler를 여시겠습니까?가 뜨면 [열기(허용)]를 선택합니다. - 게임이 일본 로케일 환경에서 자동 실행되어 서버/캐릭터 선택 화면으로 진입합니다.