NS 게임을 Apple ARM으로 네이티브 포팅
목표는 원래 게임 코드를 대상 기기에서 보고, 조작하고, 저장할 수 있는 결과를 만드는 것입니다. CPU가 ARM64로 동일하더라도 명령어 번역 작업만 줄어들 뿐, OS ABI, 메모리, 스레드, 그래픽, 오디오 및 입력 호환 레이어를 생략할 수 없습니다.
언어 및 아키텍처 요구 사항
- 새 포팅 코어는 반드시 Rust(
.rs)로 작성하며, Cargo workspace를 사용해 리소스 파싱, 공유 ABI, 오프라인 수정, 셰이더 변환, 호스트 런타임을 분리합니다. 기존 Rust 프로젝트는 직접 재사용합니다. 기존 C/C++ 네이티브 모듈은 명확한 FFI 경계를 통해 연결하며, 이미 검증된 모듈을 언어 통일을 위해 다시 작성하지 않습니다. 사용자가 다른 기술 스택을 명시하면 이를 따르고 차이점을 기록합니다. - Swift는 런처 및 Apple 플랫폼 UI에 사용합니다. Objective-C/Objective-C++, C/C++은 필요한 시스템 브리징 또는 기존 네이티브 라이브러리에 사용합니다. AArch64 어셈블리는 진입점, 레지스터 저장 및 호출 트램펄린으로 제한합니다. Metal Shading Language(MSL)은 GPU 프로그램에 사용합니다. Python/Bash는 리소스 준비, 빌드, 서명 및 진단을 오케스트레이션하는 데만 사용하며, 프레임 단위 재생 또는 게스트 실행 핫 경로에는 사용하지 않습니다.
- 작업 순서는 로컬 리소스 파싱 → AArch64 오프라인 수정 → 원래 게임 머신 코드 네이티브 실행 → Horizon/SDK 호환 → NVN 명령어 녹화 및 Metal 재생입니다. 원래 게임 로직을 유지하며, 게임플레이를 다시 작성하거나 호스트 데모 화면을 만들거나 빈 API 스텁만 제공하는 식의 포팅은 하지 않습니다.
- 구현을 시작하거나 게임 간에 코드를 재사용하기 전에 architecture-and-workflow.md를 읽고 모듈 경계, 게임 버전 설정, 최단 종단간 검증 경로를 결정합니다. 이 참고 자료는 실제 Rust/Cargo 기반 포팅 구조에서 추출되었으며, 원본 프로젝트가 로컬에 있을 필요는 없습니다.
작업 시작
- 사용자가 지정한 디렉토리나 현재 워크스페이스에서 대상 저장소를 찾습니다. 참고 저장소는 사용자가 제공하거나 현재 워크스페이스에서 찾을 수 있을 때만 읽으며, 개발자 로컬 경로를 가정하지 않습니다. 대상 저장소의 설명, 로컬
AGENTS.md, Git 상태, 빌드 진입점 및 최신 검증 기록을 읽습니다. 먼저 사용자가 구현, 진단, 또는 평가만 원하는지 확인합니다. 평가 작업은 읽기 전용으로 유지합니다. - 입력 매트릭스를 구축합니다: 게임/타이틀 ID, 본체/업데이트/DLC, 표시 버전, NPDM 아키텍처, 실제 NSO 모듈 빌드 ID, 대상 OS/칩, 소스 코드 버전, 실행 방식. 실제 추출된 모듈을 기준으로 하며, 파일 이름이나 게임 이름으로 AArch64를 추정하지 않습니다.
- 정해진 경로를 유지합니다. 기존 네이티브 호환 레이어가 있으면 추출, 수정, 호스트 및 Metal 아키텍처를 재사용하고 모듈별로 비교합니다. 다른 게임의 주소 패치를 그대로 가져오지 않습니다. 새 프로젝트는 먼저 재사용 가능한 호환 레이어가 있는지 확인한 후 작업량을 결정합니다. AArch32 입력은 이 AArch64 직접 실행 경로에 적합하지 않습니다. 사용자에게 적절한 버전을 찾도록 하거나 다른 실행 경로가 필요함을 명확히 합니다.
- 먼저 반복 가능한 최단 검증 경로를 선택합니다: 실행 → 타이틀/메뉴 → 씬 → 조작 → 정상 종료 → 새 프로세스에서 저장 불러오기. 단계별로 실제 차단 문제를 해결하며, 로그, 코드 및 화면을 통해 원인을 확인합니다.
문제별 참고 자료
- 코드 로딩, 패치, Horizon ABI, 스레드 및 플랫폼 배포: runtime-and-platforms.md를 읽습니다.
- 검은 화면, 그래픽 깨짐, 지형/물 색상 이상, 셰이더 또는 성능 문제: graphics-and-debugging.md를 읽습니다.
- 검증, 진행 상황 판단, 복기 및 인계: validation-and-cases.md를 읽습니다. 이 문서에는 이전 가능한 사례와 증거 경계가 포함됩니다.
구현 폐쇄 루프
- 먼저 장애가 발생한 계층을 기록합니다: 추출/식별 → 명령어 수정 → 로딩/재배치 → SDK/서비스 → 명령어 녹화 → Metal 재생/제출 → 실제 창 → 게임 동작.
- 매 라운드마다 하나의 반증 가능한 가설을 세우고, 최소한의 필수 증거를 수집한 후 국소적으로 수정합니다. 진단 스위치는 기본적으로 꺼져 있으며, 개수/크기 제한이 있습니다. 예외에는 모듈 상대 위치, 요청 또는 리소스 정보가 포함되어야 하며, 키는 노출되어서는 안 됩니다.
- 하위 수준 의미 수정에 적합한 검증 방법을 선택합니다: 명령어 동등성, ABI 레이아웃, 동시성, 실제 GPU 읽기. 정적 검사와 빌드 후 사용자가 허용한 범위 내에서 실제 게임을 실행합니다. 사용자가 테스트를 금지하면 검증되지 않았다는 기록만 남기고 임의로 실행하지 않습니다.
- 해당 버전의 소스 코드, 빌드, 설치 패키지, 실행 ID, 로그 및 스크린샷은 서로 연결될 수 있어야 합니다. 새 빌드가 이전 장치의 로그로 성공을 증명할 수 없습니다.
- 진단 반례를 보존하고 현재 결론을 업데이트합니다. 프레임 캡처/단일 스텝은 타이밍을 변경할 수 있습니다. 수정 후에는 진단을 끄고 새 프로세스로 재테스트합니다. 표면적인 이상 현상을 없애기 위해 캐릭터 높이, 물 색상, 충돌 또는 게임 진행을 하드코딩으로 수정하지 않습니다.
- 알 수 없는 서비스, 명령어 또는 형식에 대해서는 명확한 실패 정보를 남깁니다. 호출자가 다운그레이드를 허용한다는 증거가 있을 때만 의미 있는 다운그레이드를 구현합니다. 일반적으로 성공을 반환하여 미구현 기능을 은폐하지 않습니다.
리소스 및 전달
- 소스 패키지, 키, 펌웨어는 로컬에 보관합니다. 키 값을 명령 인수, 로그 또는 저장소에 기록하지 않습니다. 이 콘텐츠를 스킬 안으로 복사하지 않습니다. 원저작자의 라이선스 및 저작권 표시를 유지합니다.
- 사용자 소스 패키지는 읽기 전용입니다. 추출된 콘텐츠, 수정된 모듈, 캐시, 아카이브 및 로그는 독립적이고 무시된 데이터 디렉토리를 사용합니다. 게임과 버전별로 격리하며, 다른 에뮬레이터의 상태를 덮어쓰지 않습니다. 소스 코드를 롤백해도 사용자 아카이브를 삭제하지 않습니다.
- 캐시는 입력 빌드 ID, 수정기/변환기 버전, 플랫폼 및 컴파일 옵션의 변경을 식별할 수 있어야 합니다. 알 수 없거나 혼합된 버전은 게스트 코드 진입 전에 거부해야 합니다.
- macOS와 iOS/iPadOS는 각각 빌드, 서명 및 검증합니다. 설치 스크립트의 성공은 해당 단계만 증명합니다. iPhone, iPad, 시뮬레이터 및 Mac의 결과는 각각 보고합니다.
- 로컬 iOS 빌드에는 원래 게임 수정 코드가 포함될 수 있습니다. 배포 또는 게시 전에 앱 번들 콘텐츠와 라이선스를 확인하고, 배포 권한이 있는 콘텐츠만 배포합니다. 로컬 파생물을 자동으로 업로드하지 않습니다.
완료 보고서에는 다음이 포함되어야 합니다: 수정한 내용, 실제로 어디까지 실행되었는지, 증거가 어떤 빌드와 장치에 해당하는지, 여전히 어떤 제한이 있는지, 다음으로 어떤 차단 문제를 검증해야 하는지. 확인할 수 없는 완료율 또는 '완전 호환'과 같은 표현은 피합니다.