무한대전은 오래된 레거시 MUD 게임 코드다. 원 저자는 아니고, 공개된 소스코드를 오래 간직하고 있던 사람으로서 이걸 다시 구동 가능한 상태로 복구해 보고 싶었다.
무한대전은 오래된 레거시 MUD 게임 코드다. 원 저자는 아니고, 공개된 소스코드를 오래 간직하고 있던 사람으로서 이걸 다시 구동 가능한 상태로 복구해 보고 싶었다.
이번 작업의 핵심 장애물은 세 가지였다.
특히 첫 단계부터 이런 에러가 터졌다.
error: unable to create file help/????: Illegal byte sequence
error: unable to create file objmon/ddesc/????_99: Illegal byte sequence
error: unable to create file objmon/ddesc/???ű?_40: Illegal byte sequence
파일 내용이 문제가 아니라 파일명 인코딩이 문제였다. macOS 파일시스템 제약과 레거시 코드페이지가 충돌하면서, 저장소 원본은 있는데 워크트리에 못 내려오는 상황이 생겼다.
이번 복구 의뢰 문장은 딱 이거였다.
docs 폴더의 철학/구성/컴파일 문서를 단서로 활용나는 여기서 "완전한 미화"보다 "실행 가능한 복원"을 우선순위로 잡았다.
Codex가 먼저 세운 실행계획은 6단계였다.
계획에서 바로 효과가 컸던 포인트는 두 가지였다.
처음부터 "예쁘게 다시 쓰기"로 가지 않고 "현재 동작을 보존하면서 복구"로 고정한 게 승부처였다.
기준선에서 총 3803개 중 92개가 누락 상태라는 점을 먼저 확정했다. 감으로 접근하지 않고 누락 수치를 고정해 두면, 이후 단계에서 성공/실패 판단이 명확해진다.
CP949 디코딩이 되는 경로는 UTF-8 경로로 정규화하고, 실패하는 경로는 __legacy_hex_* 규칙으로 안전한 이름을 부여했다. 이 과정에서 원본 바이트 경로와 새 경로를 manifest로 1:1 보존했다.
help, talk, ddesc, player 같은 핵심 접근 지점을 resource_path 계층으로 통일했다. 기존 코드 곳곳의 파일 오픈 로직을 그대로 두면 같은 버그가 계속 반복되기 때문이다.
Port 다중정의, 함수 시그니처 불일치, 누락 헤더 같은 전형적인 레거시 컴파일 이슈를 정리하고, -std=gnu89 중심으로 빌드 기준을 고정했다. 목표는 "경고 0"이 아니라 "재현 가능한 빌드 성공"이었다.
컨테이너에서 빌드하고, 서버 부팅/포트 리슨/기본 명령/리소스 로딩/save-load까지 스모크 시나리오로 확인했다. 복구 작업은 "컴파일됨"이 아니라 "실행됨"으로 닫아야 의미가 있다.
Rust는 리소스 인덱스/경로 해석부터 붙이고, 게임 로직 C는 당장 건드리지 않는 2단계 전략으로 뒀다. 이게 리스크 대비 효율이 가장 좋았다.
플랜 수립부터 구현 완료 보고까지 총 44분 걸렸다.
15년 동안 "언젠가 복구해야지" 하고 미뤄두던 레거시 유적이 40여 분 만에 다시 돌아가는 걸 보니까 감정이 좀 묘했다. 기쁘기도 하고, 동시에 코딩 에이전트 성능이 솔직히 무서울 정도였다.
예전에는 이런 작업이 "파일명 인코딩 + 빌드 깨짐 + 런타임 경로 버그" 삼중고 때문에 시작 자체가 부담이었는데, 지금은 문제를 단계별로 쪼개고 검증 루프를 자동화하면 생각보다 짧은 시간에 끝난다.
결국 바뀐 건 두 가지라고 본다.
무한대전 복구는 그 조합이 실제로 통하는지 확인한 사례중 하나다.
복구된 코드 브랜치: https://github.com/comfuture/muhan/tree/revive