
OpenSmash는 브라우저에서 Super Smash Bros. 64와 Super Smash Bros. Melee를 플레이하면서 이미지 업로드로 새 캐릭터를 만드는 프로젝트다. 이름과 선택 사항인 사진을 입력하면 저폴리곤 리깅 메시, 캐릭터 선택 화면 초상화, 스톡 아이콘, 시리즈 엠블럼, 아나운서 음성을 생성한다. Smash 64에서는 원작의 12개 스켈레톤 중 하나에 캐릭터를 넣고, Melee에서는 26개 무브세트 중 하나의 의상으로 적용한다.
전체 영상은 유튜브에서 볼 수 있다. smash.fun에서 Smash 64를, smash.fun/melee에서 Melee를 체험할 수 있다. 소스 저장소는 GitHub에 공개돼 있다.
저장소에 닌텐도 에셋을 넣거나 사이트에서 제공하지 않는다. Smash 64는 디컴파일을 바탕으로 한 PC 포트 BattleShip을 엔진으로 사용하며, 플레이어가 자신의 ROM에서 게임 에셋을 브라우저로 추출한다. Melee는 WebAssembly로 빌드한 고정 버전의 Melee PC 포크를 사용하고, 플레이어가 자신의 디스크 이미지에서 데이터를 읽는다. 스프라이트, 스켈레톤, 아나운서 음성 클립, 의상 템플릿 등 게임에서 유래한 생성기 입력 자료도 각자의 ROM이나 디스크에서 다시 만들 수 있다. 자세한 내용은 게임에서 가져오는 입력 자료를 참조하면 된다.
프로젝트 구성과 준비
프로젝트 아래의 구성 요소는 여러 저장소를 포크해 연결한 것이다. WebAssembly 빌드와 파이프라인 연결 지점을 고정하기 위해 자체 복사본을 유지하며, BattleShip의 서브모듈도 이 복사본을 가리킨다.
turtlesoupy/BattleShip은 JRickey/BattleShip에서 포크했다. PC 포트로, macOS·Linux·Windows·Android 네이티브 빌드와 Emscripten 빌드, 캐릭터 삽입 코드(port/), 파이프라인 덤프 연결 지점을 포함한다.turtlesoupy/ssb-decomp-re는 VetriTheRetri/ssb-decomp-re에서 포크한 게임 디컴파일이다.decomp/에 포함한다.turtlesoupy/libultraship은 JRickey/libultraship을 거쳐 Kenix3/libultraship에서 포크했다. N64 포트의 렌더링·오디오·입력 계층이며libultraship/에 포함한다.turtlesoupy/Torch는 JRickey/Torch를 거쳐 HarbourMasters/Torch에서 포크했다. ROM에서 에셋을.o2r아카이브로 추출하며, 브라우저 작업을 위해 WebAssembly로도 컴파일한다.torch/에 포함한다.turtlesoupy/opensmash-melee-pc는 999sian/melee-pc에서 포크했다.opensmash/browser브랜치에 Emscripten/WebGPU 빌드, 사용자 의상 슬롯, 실행 연결 코드를 추가했다.engines/melee/upstream.json에서 버전을 고정한다.- doldecomp/melee는 의상 변환기의 구조·심볼 참고 자료로 쓰는 Melee 디컴파일이며,
engines/melee/melee에 서브모듈로 포함한다.
BattleShip의 README에 Smash 64 관련 프로젝트의 라이선스와 크레딧이 있다.
저장소를 받아 작업할 때는 두 저장소를 나란히 복제하고 emsdk도 옆에 둔다.
opensmash/ BattleShip/ git clone https://github.com/turtlesoupy/BattleShip pipeline/ git clone https://github.com/turtlesoupy/opensmash (this repo) emsdk/ https://github.com/emscripten-core/emsdk melee-pc/ cloned for you by engines/melee/tools/build_upstream.py (Melee only)
사이트 서버는 엔진을 pipeline/BattleShip/web-dist에서 찾고, 없으면 ../BattleShip/web-dist를 확인한다. 따라서 심볼릭 링크(ln -s ../BattleShip pipeline/BattleShip)를 만들거나 저장소를 나란히 두면 된다.
저장소의 주요 디렉터리는 다음과 같다.
pipeline/: 생성기다.run_character.py가 이름과 사진을 플레이 가능한 캐릭터로 만든다.web-prototype/: React 프런트엔드와 Node 서버로 구성한 사이트다. 캐릭터 목록, ROM·디스크 확인, 두 엔진 실행(/은 Smash 64,/melee는 Melee), Cloud Run·Firestore·GCS를 사용하는 호스팅 캐릭터 생성 흐름을 포함한다.asset-sources/와tools/에는 사이트의 3D 소품·글꼴과 제작에 쓴 Blender 스크립트가 있다.engines/: 엔진별 코드다.engines/ssb64/에는 BattleShip 실행 어댑터가,engines/melee/에는 Melee 빌드·의상 변환기·실행 구성 요소·호스팅 변환 서비스·데스크톱 셸이 있다. 자세한 내용은engines/melee/README.md를 참조하면 된다.skels/: Smash 64의 대상 스켈레톤 12개, 캐릭터별 맞춤 프로필, 메시를 맞추는 데 쓰는 기준 부품 데이터가 있다. Melee 스켈레톤은 변환할 때 디스크에서 가져온다.play/: 로컬 생성 결과를 저장하며 Git에서 제외한다. 운영 캐릭터 목록은 공개 GCS 버킷에 있으며web-prototype/config/baked-assets.json에서 고정한다.scripts/,tools/: 일괄 실행 도구, ROM에서 자료를 가져오는 스크립트, 스프라이트 추출기, 위키피디아 캐릭터 목록 시드가 있다.eval/: 메시 평가 도구 모음이며 설명은EVAL.md에 있다.config/,docs/,assets/: 문서와 생성기가 참고하는 스타일 자료가 있다.config/의 로컬 캐릭터 포함·제외 목록은 Git에서 제외한다.
Smash 64 네이티브 빌드와 ROM 빌드
브라우저 밖에서 Smash 64를 플레이하려면 BattleShip으로 데스크톱 게임을 빌드하거나, 에뮬레이터·실제 콘솔용 실험적 N64 ROM을 만들 수 있다. 두 방식 모두 사이트 캐릭터와 사용자가 만든 비공개 캐릭터를 초상화·이름·엠블럼·아나운서 음성과 함께 넣을 수 있다. Melee를 브라우저 밖에서 실행하는 방법은 아래 Melee 항목에 설명돼 있다.
두 빌드는 모두 build.py와 같은 캐릭터 선택 옵션을 쓴다. 네이티브 빌드는 원래 캐릭터 목록을 유지하고 추가 선택 화면 페이지에 사용자 캐릭터를 넣는다. ROM 빌드는 페이지를 추가하지 않고 원래 슬롯을 최대 12개까지 교체한다.
명령은 저장소 루트에서 실행한다. 옆에 최신 BattleShip 체크아웃이 있어야 하고 서브모듈을 초기화해야 한다. 미국판 v1.0 ROM을 BattleShip/baserom.us.z64에 두거나 명령에 --rom /path/to/baserom.us.z64를 지정한다. ROM은 로컬에 남는다. 사전 요구 사항과 다른 저장소 배치는 빌드 설정을 참조하면 된다.
네이티브 데스크톱 빌드
BattleShip의 플랫폼별 사전 요구 사항을 설치한 뒤 빌드한다. 기본값은 사이트의 공개 캐릭터 전체 목록이다. 사용자 캐릭터는 추가 선택 화면에 표시되며 L/R 또는 화면의 화살표로 페이지를 바꾼다. 빌드와 다운로드가 끝나면 오프라인에서도 작동한다.
# Build with the full public roster:
python3 build.py native
# Or choose just a few website fighters:
python3 build.py native --characters queen,50cent,abrahamlincoln
사용자 캐릭터나 비공개 캐릭터를 추가하려면 사이트 설정에서 캐릭터 다운로드 URL을 복사한다. --characters none은 링크로 지정한 캐릭터만 포함하고, 공개 캐릭터 ID를 지정하면 링크 캐릭터와 함께 넣는다.
python3 build.py native --characters none --character-url 'PASTE_DOWNLOAD_URL'
python3 build.py native --characters queen,50cent --character-url 'PASTE_DOWNLOAD_URL'
queen 같은 ID는 사이트에서 사용하는 슬러그다. 여러 링크를 넣으려면 --character-url을 반복한다. 네이티브 빌드에서는 사용자 목록을 바꿔도 원래 캐릭터를 계속 사용할 수 있다. 무브세트 기본값과 링크에 관한 내용은 비공개 캐릭터 링크를 참조하면 된다.
실행하려면 생성된 build/native-PLATFORM-REGION-CONFIG/ 폴더에서 macOS는 Play.command, Windows는 Play.bat을 연다. 모든 데스크톱 플랫폼에서는 해당 폴더의 play.py를 Python으로 실행할 수도 있다. macOS 예시는 다음과 같다.
python3 build/native-darwin-us-release/play.py
N64 ROM 빌드
ROM 빌드는 에뮬레이터나 EverDrive 같은 N64 플래시 카트리지에서 사용할 build/rom/opensmash.z64를 만든다. 선택한 각 캐릭터가 원래 슬롯 12개 중 하나를 교체하고 선택하지 않은 슬롯은 원본 캐릭터로 남는다. 이 빌드에는 페이지를 넘기는 캐릭터 선택 화면이 아직 없다.
--characters와 --character-url 옵션은 네이티브 빌드와 같다. 명령에서 native 대신 rom을 쓴다. 공개 목록 전체가 아니라 넣을 캐릭터를 선택해야 한다. 추가 ROM 빌드 의존성과 vpk0cmd를 설치한다.
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -r hardware-rom/requirements.txt
# Bake selected website fighters into a ROM:
python3 build.py rom --characters queen,50cent --vpk0 /path/to/vpk0cmd
# Or bake in a custom/private fighter:
python3 build.py rom --characters none --character-url 'PASTE_DOWNLOAD_URL' --vpk0 /path/to/vpk0cmd
Windows에서는 .venv\Scripts\Activate.ps1로 가상 환경을 활성화한다. 도구가 BattleShip/decomp/tools/vpk0cmd에 설치돼 있거나 PATH에 있으면 --vpk0를 생략할 수 있다.
빌더는 각 캐릭터의 사이트 무브세트를 우선 사용하지만 슬롯이 충돌하면 다시 배정할 수 있다. 실제 배정 결과는 build/rom/characters.json에서 확인한다. 교체 슬롯을 직접 지정하려면 로컬 목록 설정을 참조하면 된다.
ROM 지원은 실험 단계다. ROM 빌드에서는 정점마다 최대 네 관절의 영향을 혼합하는 스켈레탈 스키닝을 사용하며 MIPS 컴파일러가 필요하다. 메모리와 성능 때문에 메시 세부 수준과 목록 크기에도 한계가 있다. 자세한 내용은 스키닝 설정과 검증과 ROM 안내를 참조하면 된다. 이 제약은 네이티브 빌드와 웹사이트 빌드에는 적용되지 않는다.
두 대상 모두 --output-dir PATH로 빌드별 출력 디렉터리를 분리하고 --dry-run으로 빌드 명령을 미리 볼 수 있다. 순정 네이티브 빌드와 로컬 에셋 목록을 포함한 모든 옵션은 BUILDING.md에 있다.
사이트 실행
Node 20 이상과 pnpm(corepack enable), Super Smash Bros. USA(NTSC-U v1.0) ROM이 필요하다. ROM의 SHA-1은 e2929e10fccc0aa84e5776227e798abc07cedabf여야 하며 다른 지역판은 거부된다. 엔진을 직접 빌드할 때는 Emscripten도 필요하다. ROM을 저장소에 커밋하면 안 된다. 아래 절차는 Smash 64를 실행한다. Melee 부분은 선택 사항이며 별도로 설정한다.
먼저 BattleShip/에서 ROM을 baserom.us.z64에 두고 emsdk를 활성화한다(source ../emsdk/emsdk_env.sh). 그런 다음 엔진을 빌드한다.
emcmake cmake -B build-wasm -G Ninja -DCMAKE_BUILD_TYPE=Release -DSSB64_VERSION=us
cmake --build build-wasm --target BattleShip.js -j
scripts/build_torch_wasm.sh
scripts/package_web.sh build-wasm web-dist
사이트는 /engine/에서 web-dist/를 제공한다. 그 안의 모든 파일 URL에는 빌드 버전이 들어가며, ROM에서 파생한 아카이브는 포함하지 않는다. 브라우저가 첫 실행 때 아카이브를 만든다(BattleShip의 브라우저 ROM 추출 문서). C 코드를 바꾼 뒤에는 ninja -C build-wasm BattleShip.js를 실행하고 package_web.sh도 다시 실행한다.
운영 캐릭터 목록 1000개 이상(약 3.3GB)을 web-prototype/.baked-characters에 내려받는다.
cd web-prototype && PUBLIC_BUCKET=smash-the-weights-fighter-assets pnpm assets:fetch
또는 다음 절에서 설명하는 방법으로 직접 생성해 play/에 둘 수 있다. 개발 모드 서버는 play/를 직접 읽는다. 사이트를 시작하려면 다음을 실행한다.
cd web-prototype && pnpm install && pnpm dev:safe
http://127.0.0.1:4174을 열고 ROM을 넣으면 플레이할 수 있다. dev:safe는 로컬 캐릭터 작업자를 꺼서 /create가 크레딧을 쓰지 않도록 한다. pnpm dev는 웹 UI에서 실제 생성 작업을 실행한다. /melee에는 Melee 캐릭터 목록이 표시되지만, 다음 절의 Melee 에셋 서비스가 실행 중이기 전에는 경기를 시작할 수 없다. ROM 확인, 인증, 휴대전화로 넘기는 절차, 호스팅 생성 흐름은 web-prototype/README.md에 설명돼 있다.
Melee
Melee에서는 같은 생성 캐릭터를 Melee 자체 스켈레톤과 무브세트에 적용한다. 관련 코드는 engines/melee에 있다.
변환기는 생성된 리깅 메시를 받아 게임의 바인드 행렬을 사용해 선택한 Melee 캐릭터 스켈레톤에 맞춘다. 텍스처를 하나의 아틀라스로 합쳐 실제 의상 .dat 파일을 만든다. 물리, 히트박스, 애니메이션은 Melee 원본 데이터를 그대로 사용하므로 사용자 캐릭터는 26개 무브세트 중 하나를 빌린다. 기본 무브세트는 Smash 64의 기반 캐릭터에 따라 정한다. 예를 들어 Mario는 Mario, DK는 Donkey Kong을 사용한다. 캐릭터 소유자는 사이트 캐릭터 창의 Melee 설정에서 무브세트를 바꿀 수 있다. 메시 맞춤은 fitter의 WebAssembly 빌드로 브라우저에서 이뤄진다. 게임에서 유래한 스켈레톤 템플릿은 각 플레이어의 디스크에서 가져오며, 게임플레이용 게임 데이터는 사이트가 제공하지 않는다.
로컬 실행에는 수정하지 않은 Melee USA 1.02 디스크 이미지(ISO 또는 GCM)가 필요하다. 고정된 엔진 포크를 빌드한 뒤 사이트 옆에서 Melee 에셋 서비스를 실행한다.
python3 engines/melee/tools/build_upstream.py --jobs 6
python3 engines/melee/tools/serve_melee.py --upstream --port 8781 --characters play/ui
cd web-prototype && MELEE_LOCAL_ORIGIN=http://127.0.0.1:8781 pnpm dev
http://127.0.0.1:4174/melee를 열고 안내가 나오면 디스크를 선택한다. 브라우저에서 디스크를 해시하고 읽으며 업로드하지 않는다. 도구 체인 사전 요구 사항(LLVM 22, GCC 16, Node 22.13 이상, Emscripten)과 업스트림 동기화 절차는 engines/melee/UPSTREAM.md에 있다. --characters에는 생성 결과 디렉터리 트리(예: play/ui)를 지정한다. 각 슬러그 디렉터리에 rigged.glb와 character.json이 있어야 한다. 변환기는 처음 사용할 때 이 자료로 의상을 준비한다.
smash.fun에서 캐릭터를 가져오려면 사이트의 캐릭터 다운로드 창에서 Copy Melee import URL을 선택한다. 로컬 Melee 실행기나 데스크톱 앱에서 Create에 해당 링크를 넣으면 컴퓨터에서 변환한다. 호스팅 사이트에서는 공유 캐릭터 목록을 사용하므로 링크가 필요 없다. 의상은 웹 컨테이너 안의 Python 하위 프로세스가 요청 시 준비한다(서버 안내).
배포할 때 web-prototype/infra/deploy.sh는 롤아웃 전에 engines/melee/tools/prepare_web_release.py를 실행한다. 이 도구는 엔진 고정 버전, fitter, 템플릿 코드의 지문을 확인하고 변경된 경우에만 다시 빌드한다. 콘텐츠 해시가 붙은 입력 팩을 비공개 버킷에 게시하고 해당 배포의 매니페스트를 고정한다. 검증된 게임 추출 작업 공간(MELEE_WORKSPACE)과 엔진 요구 사항 및 google-cloud-storage를 설치한 Python 환경(MELEE_BUILD_PYTHON)이 필요하다.
브라우저 밖에서는 네이티브 엔진을 감싼 Electron 셸 기반 독립 데스크톱 알파 버전을 Windows와 Apple Silicon에서 사용할 수 있다. turtlesoupy/opensmash-melee 릴리스에서 배포한다. 소스는 engines/melee/IMPORT.json에 출처를 기록한 뒤 이 저장소의 engines/melee로 가져왔다. 자세한 내용은 DESKTOP_RELEASE.md와 NATIVE.md를 참조하면 된다.
캐릭터 생성
필수 조건은 Python 3.11 이상, pip install -r requirements.txt, 아나운서 오디오용 ffmpeg다. 생성기는 ROM을 직접 읽지 않는다. 다만 생성기에 필요한 스켈레톤과 스프라이트 입력 자료가 ROM에서 파생되며 저장소에는 들어 있지 않다. 생성 전에 tools/derive_from_rom.py와 tools/derive_skeletons.py를 한 번 실행한다. 자세한 내용은 게임에서 가져오는 입력 자료에 있다.
.env.example을 저장소 루트의 .env로 복사한다. 이 파일은 Git에서 제외되며 모든 파이프라인 스크립트가 읽는다.
| 키 | 사용처 |
|---|---|
OPENAI_API_KEY | 캐릭터 설명(gpt-5.6-luna), T자 포즈 모델 시트·초상화·스톡·엠블럼 이미지(gpt-image-2), 정면 확인, 사이트 업로드 조정 |
TRIPO_API_KEY | 이미지에서 3D 모델 생성 및 자동 리깅. 캐릭터당 55크레딧(0.55달러). 작업 ID를 저장하므로 재시도해도 메시 생성 비용을 다시 내지 않는다. |
FAL_KEY | fal의 MiniMax 음성 합성 엔드포인트를 통한 아나운서 클립 생성 및 아나운서 음성 생성 |
MINIMAX_ANNOUNCER_VOICE_ID | 아나운서가 사용할 MiniMax 음성 복제 ID. 한 번 만들며 아래 절차를 참조한다. |
GEMINI_API_KEY | 선택 사항. 일부 실험에서 대체 이미지 모델로 사용 |
MESHY_API_KEY | 선택 사항. 사이트 소품용 web-prototype/tools/generate_mesh.py에서만 사용 |
캐릭터 한 명의 제공업체 비용은 약 0.65달러다. 실행 단계별 비용 내역은 play/ui/<slug>/cost.json에 기록한다.
아나운서 음성은 게임 아나운서의 음성을 본뜬 MiniMax 음성 복제본이다. 기준 오디오는 ROM에서 만든다(eval/announcer_conditioning_corrected/; derive_from_rom.py로 다시 생성). 자신의 fal 계정에서 복제본을 만들려면 다음을 실행한다.
python3 pipeline/create_announcer_voice.py
이 명령은 14초 길이의 이름 모음 오디오를 업로드하고 fal의 minimax/voice-clone을 호출해 미리 듣기 WAV를 저장한 뒤 음성 ID를 출력한다. ID를 .env의 MINIMAX_ANNOUNCER_VOICE_ID에 넣는다. MiniMax는 음성 복제마다 소액을 청구한다. 복제 음성을 7일 안에 TTS에 사용하지 않으면 삭제하므로, 만든 뒤 아나운서 클립을 하나 이상 생성해야 한다. 세부 내용과 귀로 조정한 제공업체 설정은 ANNOUNCER.md에 있다.
캐릭터 한 명을 만들려면 다음처럼 실행한다.
python3 pipeline/run_character.py "Weird Al Yankovic" --photo ref.png
--short WEIRDAL은 타일 캡션을 지정하며 최대 10개의 대문자를 쓴다. --display "Mozart"는 게임 내 이름과 아나운서가 읽을 이름을 지정한다. --emblem "a red accordion"은 시리즈 엠블럼을 지정하며 생략하면 추론한다. --notes "..."는 묘사·복장·시대를 조정한다. --variants all은 실험 대상인 DK와 Yoshi 스켈레톤도 생성한다.
파이프라인 단계는 expand(설명) → tpose(모델 시트) → mesh(Tripo 메시와 리깅) → convert(Smash 64 스켈레톤에 맞춤) → portrait → stock → emblem → ui → voice → melee-source(Melee 변환기에 필요한 리깅 메시와 그림을 묶음) 순이다. 마지막 패키지 하나로 모든 무브세트에 대응한다. 결과물이 이미 있으면 해당 단계는 건너뛰므로 실패 후 중단된 단계부터 다시 시작한다. 단계를 다시 실행하려면 해당 출력물을 지우거나 --force-stage <stage>를 지정한다. 설명이나 엠블럼을 고치려면 character.json을 수정한 뒤 다시 실행한다.
출력은 그림, character.json, .osbui UI 팩, announcer.wav, Melee 소스 패키지와 중간 파일을 담은 play/ui/<slug>/, Smash 64 대상 스켈레톤별 메시를 묶은 play/<slug>.osb6에 저장한다. Melee 의상은 여기서 만들지 않고 처음 사용할 때 소스 패키지에서 맞춘다. 사이트의 /create 페이지도 같은 스크립트를 실행한다.
여러 캐릭터를 만들려면 파일에 이름을 한 줄씩 적고 다음을 실행한다.
python3 scripts/batch_characters.py names.txt --workers 3
이 도구는 일시적인 제공업체 오류를 재시도하고, 조정 단계에서 차단된 이미지는 다시 생성하며, 이미 완료된 이름은 건너뛴다. 상태는 batch-state/에 저장한다. touch batch-state/STOP을 실행하면 진행 중인 작업을 끝낸 뒤 종료한다. tools/build_wikipedia_people_seed.py는 위키피디아를 바탕으로 인기도 순 이름 목록을 만든다. 로컬 파일이 있다면 config/wikipedia-roster-{inclusions,exclusions}.txt의 포함·제외 규칙도 적용한다. 사용한 규칙은 docs/character-roster-editorial-policy.md에 있다.
사이트 캐릭터 목록은 web-prototype/config/characters.json에 순서대로 기록한다. 캐릭터를 로컬에서 확인한 뒤 다음 명령으로 필요한 파일을 검사하고 슬러그를 목록 끝에 추가한다. run_character.py --publish도 같은 작업을 한다.
python3 pipeline/baked_roster.py <slug>
그 다음 실행 파일을 업로드하고 체크섬 고정 정보를 갱신한다.
cd web-prototype && PUBLIC_BUCKET=<project>-fighter-assets pnpm assets:publish
config/characters.json과 config/baked-assets.json을 함께 커밋한다. 객체는 콘텐츠 해시를 키로 사용하므로 게시 작업은 추가만 하며 이전 커밋도 재현할 수 있다. Cloud Run·작업자 작업·Cloudflare 배포는 한 스크립트로 진행한다. 자세한 내용은 web-prototype/infra/README.md에 있다.
게임에서 가져오는 입력 자료
일부 생성기 입력은 Smash 64에서 가져온다. 이 파일들은 Git에서 제외돼 있고 저장소가 공개되기 전에 이력에서도 제거됐다. 생성기나 ui_refs/를 이미지에 복사하는 작업자 Docker 빌드를 실행하기 전에 ROM에서 다시 만들어야 한다. Melee의 의상 템플릿과 메뉴 파일도 해당 도구로 디스크에서 추출한다. 자세한 내용은 engines/melee/README.md에 있다.
| 파일 | 내용 | 다시 만드는 도구 |
|---|---|---|
skels/*.skel, skels/fk*-all.log, skels/parts/*.json | 원래 포즈의 스켈레톤과 캐릭터 12명의 부품 형상 | 엔진을 실행하는 derive_skeletons.py |
web-prototype/asset-sources/css-font/{portraits,locked} | 캐릭터 선택 초상화, 화염 슬롯, 물음표, 그림자 | derive_from_rom.py |
web-prototype/visual/assets/ui_refs/ | 타일·이름 스프라이트, 스톡 아이콘, 엠블럼 시트, 글리프 아틀라스 | derive_from_rom.py(네 글자는 --skeletons 필요) |
eval/announcer_conditioning_corrected/ | 게임 내 음높이로 맞춘 음성 복제 기준 아나운서 대사 | derive_from_rom.py |
web-prototype/asset-sources/stone-tile/source-* | 캐릭터 선택 화면의 돌 질감 | derive_from_rom.py |
직접 만든 자료로 커밋된 것은 skels/*.profile.json, skels/VALIDATION.md, asset-sources/css-font/letters다. skels/reference/mario.skel은 다른 엔진 빌드에서 오래전에 캡처한 자료로 texture_check.py가 여전히 읽는다. 스크립트는 이를 LEGACY로 보고 수정하지 않는다.
스켈레톤을 만들 때 엔진을 실행하는 이유는 ROM에 관절 트리와 애니메이션은 있지만 월드 좌표 기준의 원래 포즈가 들어 있지 않기 때문이다. 덤프 연결 지점은 게임 자체의 설정·변환 코드를 실행해 결과를 출력한다. 이를 Python으로 다시 구현하는 것보다 간단하고 안전하며, 맞춤 프로필도 이 정확한 수치에 맞춰 조정했다.
필수 조건은 BattleShip/baserom.us.z64의 ROM(SHA-1 확인), 네이티브 엔진 빌드, requirements.txt에 적힌 numpy와 Pillow가 포함된 Python이다. 네이티브 빌드는 스프라이트 추출기가 읽는 BattleShip.o2r 아카이브도 만든다. BattleShip/에서 실행한다.
cmake -S . -B build-us -GNinja -DSSB64_VERSION=us -DCMAKE_BUILD_TYPE=Release && cmake --build build-us -j
검증은 다음 명령으로 실행한다.
python3 tools/derive_from_rom.py --verify --skeletons
스크립트는 임시 디렉터리에 자료를 만들고 파일마다 IDENTICAL, 이유를 덧붙인 DIFFERS(픽셀 수 또는 달라진 관절), LEGACY 중 하나를 출력한다. 차이가 하나라도 있으면 종료 코드가 0이 아니다. --skeletons는 BattleShip/build-us/BattleShip을 13번 실행한다. 캐릭터별 스켈레톤을 위해 12번(SSB64_DUMP_SKELETON), 캐릭터 선택 화면에서 스프라이트를 얻기 위해 한 번(SSB64_DUMP_SPRITES) 실행한다. 실행할 때마다 창이 열렸다 닫히며 한 번에 약 10초가 걸린다. 이 옵션을 빼면 아카이브 기반 파일만 확인한다.
자료를 다시 만들려면 다음을 실행한다. --verify를 빼면 파일을 제자리에 덮어쓴다. --out DIR을 지정하면 저장소 구조를 다른 위치에 복제한다.
python3 tools/derive_from_rom.py --skeletons
python3 tools/derive_skeletons.py --verify --fighters samus,link
python3 tools/derive_skeletons.py --verify --from-logs skels
첫 번째 derive_skeletons.py 예시는 엔진 실행을 지정한 캐릭터로 제한한다(이름 또는 fkind 번호). 두 번째는 엔진 대신 커밋된 원시 로그에서 다시 만들며, ROM 없이 구문 분석과 프로필 맵 변환을 시험한다. 두 스크립트 모두 --build-dir로 다른 네이티브 빌드 디렉터리를 지정할 수 있다.
스켈레톤 덤프의 dl= 값은 엔진이 출력하는 호스트 포인터다. 스크립트는 실행 간 결과가 일치하도록 이를 안정적인 하위 비트로 정규화한다. 이 값을 사용하는 한 곳은 0인지 여부만 확인한다.
추가 문서
EVAL.md: 메시 생성·스키닝 평가 도구와 실험 기록ANNOUNCER.md: 아나운서 음성 생성, 복제본, 제공업체 설정web-prototype/docs/site-visual-assets.md: 사이트의 콘솔·카트리지·CRT 인트로 등 소품 제작 방법web-prototype/docs/production-architecture.md: 호스팅 생성 서비스의 작업 프로토콜, 재시도, 악용 방지BattleShip/docs/: 엔진 내부, 웹 테스트 환경, 컨트롤러 포트, 브라우저 내 ROM 추출engines/melee/README.md,engines/melee/UPSTREAM.md,engines/melee/docs/: Melee 엔진, 변환기, 검증 보고서, 데스크톱 패키징docs/melee-integration.md: 두 엔진이 실행기를 공유하는 방식과 Melee 통합 때 사용한 승인 테스트 행렬
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요