뜯어본 것공개

OpenMMO

1인 개발자가 라이브까지 올린 MMORPG. README만 보고 쓴 제 요약이 코드를 열자 두 군데 틀렸습니다.

내 요약 2건 정정github.com/Julian-adv/OpenMMO ↗

이 편에서 제일 값어치 있는 결과는 레포에 대한 것이 아니라 제 요약에 대한 것입니다. 1인 개발자가 바이브코딩으로 만들어 라이브 서비스까지 올린 Rust + Svelte MMORPG입니다. 코드 116,000줄, 커밋 1,163개, 347일, 커밋의 71%에 AI 공동저작 서명이 찍혀 있습니다. 그런데 코드를 열기 전에 README만 보고 쓴 제 요약에 사실과 다른 게 둘 있었고, 그 둘을 정정하는 과정이 이 레포에서 배운 것보다 많았습니다.

진짜 발명은 크레이트 하나를 세 런타임에 동시 배포한 것이다 공유 크레이트 — 25,643줄 메시지 정의 · 길찾기 · 행동트리 · 던전 생성 · 충돌맵 · 경험치 곡선 · 월드 생성 서버 — 14,156줄 독립 틱 다섯 개로 나뉘어 돈다 에이전트 — 5,332줄 상주 프로세스 · 모델은 JSON 액션만 브라우저 — 62,531줄 같은 크레이트를 WASM 으로 ⇒ 길찾기와 월드 생성이 세 곳에서 같은 코드로 돈다 — 서버와 봇과 클라이언트가 안 갈린다 "에이전트와 인간이 동등하다"는 주장이 성립하는 실제 근거가 여기다. 특권 API 이전에 코드가 하나다
홍보 문구는 "에이전트가 인간처럼 논다"인데, 그걸 가능하게 한 구조는 이 크레이트 공유 쪽이다.

무엇을 만든 물건인가

1인 개발자가 347일 동안 만들어 실제로 서비스 중인 MMORPG입니다. 서버는 Rust, 클라이언트는 Svelte에 WebGPU 전용, 프로토콜은 JSON이 아니라 바이너리입니다. 월드가 32km²에 타일 262,144개입니다.

품질 지표가 인상적입니다. 서버 코드에 unwrap 0건, unsafe 0건. 테스트 270개. 커밋 1,163개 중 825개(71%)에 AI 공동저작 서명이 붙어 있는데, 그 결과물이 이 정도 규율을 유지하고 있다는 게 이 레포의 실질입니다.

라이선스가 비상업용입니다. 상업적 사용이 불가하고, 코드 차용은 안 됩니다. 설계 참고만 가능합니다.

깨본 결과 — 제 요약이 두 군데 틀렸습니다

정정 1 — “모델이 MCP로 붙어서 플레이한다”는 사실이 아닙니다.

의존성 선언에는 관련 크레이트가 둘 들어 있습니다. 그런데 소스 전체를 검색하면 사용처가 0건입니다. 컴파일만 되고 한 줄도 안 씁니다. 설정 예시의 관련 포트는 주석 처리돼 있고, 설정 구조체에 그 필드 자체가 없습니다. 문서의 툴 목록은 설계 스케치이고, 같은 문서 뒷부분에 “우선순위 4번, 미착수” 로 남아 있습니다.

실제 인터페이스는 훨씬 단순합니다 — JSON 액션 스키마 7종(말하기·공격·이동·부활·거래 제안·거래창 열기·대기). 모델은 그중 하나를 고를 뿐입니다.

정정 2 — “서버가 인간과 에이전트를 구분 못 한다”는 정반대입니다.

전용 인증 메시지가 따로 있고, 인증 결과가 불린 플래그 하나로 영구히 각인됩니다. 그리고 그 플래그가 최소 여섯 곳에서 게임 규칙을 바꿉니다.

자리 효과 성격
충돌 판정 에이전트는 건너뜁니다 — 사실상 벽을 통과 특권
일일 급여 에이전트만 골드를 받습니다 특권
거래창 에이전트만 상대 화면에 거래창을 띄울 수 있습니다 특권
거래 제안 인간의 제안은 거부됩니다 제약
몬스터 스폰 에이전트 주변은 스폰을 억제합니다 최적화

절반은 맞습니다 — 전송 계층은 진짜로 같습니다. 같은 포트, 같은 프레임, 같은 메시지, 같은 길찾기 코드. 그런데 “특권 API가 없다”의 나머지 절반이 불린 하나에 담겨 있었습니다.

README 만 읽고 쓴 요약 vs 코드를 열어 확인한 것 ① "모델이 MCP 로 붙어 플레이한다" 구현 0건 — 의존성만 선언, 사용처 없음 문서의 툴 목록은 설계 스케치였고, 같은 문서에 "우선순위 4번 미착수"로 남아 있었다 ② "서버가 인간과 에이전트를 구분 못 한다" 구분할 뿐 아니라 우대한다 — 여섯 곳 충돌 판정 면제 · 일일 급여 · 거래창 강제 표시. 앞의 둘은 명백한 특권이다 ⇒ 둘 다 방향이 반대였다 — 없는 걸 있다고 했고, 있는 걸 없다고 했다 README 는 거짓말을 안 했다. 설계 문서를 현황으로, 전송 계층의 동일함을 규칙의 동일함으로 읽은 건 나다 ⚠ 홍보 문구가 아니라 내 독해가 틀렸다는 게 이 편의 결론이다
두 정정의 방향이 서로 반대다. 한쪽으로만 틀렸다면 편향인데, 양쪽으로 틀렸으니 그냥 안 읽은 것이다.

중요한 건 README가 거짓말을 안 했다는 것입니다. 문서는 설계 문서라고 적혀 있었고, 미착수 표시도 같은 문서 안에 있었습니다. 저는 설계 문서를 현황으로 읽었습니다. 그리고 “전송 계층이 같다” 는 문장을 “규칙이 같다” 로 확장해서 읽었습니다.

둘의 방향이 반대라는 게 진단에 중요합니다. 한쪽으로만 틀렸으면 기대 편향인데, 없는 걸 있다고 하고 있는 걸 없다고 했으니 그냥 안 열어 본 것입니다.

내 환경에 대봤다

코드는 못 가져옵니다 — 라이선스가 비상업용이라 차용 금지입니다. 설계만 봅니다.

제일 배울 만한 건 크레이트 공유입니다. 길찾기와 월드 생성이 서버·봇·브라우저 세 곳에서 같은 코드로 돕니다. 제 QA 자동화는 봇이 쓰는 판정 로직과 게임이 쓰는 로직이 따로입니다 — 그래서 “봇이 통과 가능하다고 봤는데 게임에서는 막힌다” 가 생깁니다. 한 코드로 만들 수 있으면 그 종류의 불일치가 원천적으로 안 생깁니다.

⚠ 다만 제 상황에 바로 적용은 안 됩니다. 게임 엔진과 봇의 런타임이 다르고, 그걸 하나로 만들려면 게임 쪽을 고쳐야 합니다. 비용이 이득보다 큽니다.

AI 공동저작 71%인데 unwrap 0건이라는 조합도 눈에 남습니다. “AI가 쓴 코드는 품질이 떨어진다” 는 통념에 대한 반례이긴 한데, ⚠ 이건 개발자 한 명의 규율이 만든 결과이지 도구의 성질이 아닙니다. 같은 도구로 다른 사람이 쓰면 다른 숫자가 나옵니다.

판정

무엇 판정
코드 차용 금지. 라이선스가 비상업용이다
한 코드를 여러 런타임에 공유 개념만 채택. 봇과 게임의 판정 불일치가 원천 차단된다
⚠ 지금 적용은 비용 > 이득
“설계 문서를 현황으로 읽지 않는다” 채택 — 규칙으로. 이번에 두 번 틀렸다
AI 공동저작 71% · unwrap 0 인용 시 한정 필요. 도구가 아니라 사람의 규율이 만든 값이다

이 편에서 값을 치른 교훈은 이겁니다 — 문서를 읽고 쓴 요약은 코드를 열면 뒤집힙니다. 그것도 양쪽 방향으로 뒤집힙니다.

그리고 ⚠ 틀린 요약을 지우지 않고 정정으로 남기는 편이 낫습니다. 지우면 “원래 맞게 알고 있었다” 가 되는데, 실제로는 코드를 열기 전까지 두 군데 틀린 상태로 알고 있었습니다. 다음에 README만 보고 판단하려 할 때, 이 기록이 그걸 막습니다.