Claude와 함께 PlayStation 1 개발환경을 처음부터 만들었습니다

source reddit
보안 소프트웨어 엔지니어이자 게임 개발자를 꿈꾸는 사람임.
과거에는 주로 PICO-8을 가지고 놀았고, 제한된 하드웨어에서 최대한 많은 것을 뽑아내는 일에 매료됐음. 오래된 플랫폼용 게임을 개발하고 싶다는 꿈을 오래전부터 품고 있었고, 특히 PS1은 어릴 때 직접 가지고 자란 콘솔이라 더 매력적으로 다가왔음. 기존 툴링과 SDK에 접근해 보려 했지만 전부 C++ 기반이라 시작하기가 꽤 어려웠음. 그래서 어느 날 “됐고, 직접 만들자”라고 마음먹고, PS1 개발 환경을 처음부터 작성하는 거대한 작업에 착수했음. 수년간 꿈꿔온 일이었고, LLM 없이는 나에게 완전히 불가능했을 거임.
이미 방향은 알고 있었음.
원본 하드웨어에 최대한 충실한 에뮬레이터를 만들어 매우 빠르게 반복 개발할 수 있게 하는 것. 현재는 전체 머신을 에뮬레이션함. R3000A CPU, GPU, GTE, CD-ROM, DMA, SPU, 타이머, MDEC까지 포함됨. 정확성을 유지하기 위해 PeterLemon, Amidog, ps1-tests의 65개 이상 bare-metal 하드웨어 테스트 ROM을 known-good 레퍼런스와 비교하는 VRAM 해싱 방식으로 돌리는 테스트 스위트를 만들었고, 실제 PS1에서 실행하는 하드웨어 테스트 CD도 제작해 값을 다시 읽고 실제 실리콘 기준으로 에뮬레이터를 튜닝하는 중.
모든 하드웨어 기능에 깔끔한 인터페이스를 제공하는 SDK도 만들었음. PS1에서는 대부분의 기능이 BIOS를 통해 노출되고 기존 SDK들도 이를 많이 활용하지만, 나는 반대로 최대 성능을 위해 하드웨어와 직접 통신하도록 설계했음.
no_std기반이며mipsel-sony-psx를 타깃으로 하고, GPU(프레임버퍼, ordering table, primitive, DMA, 폰트), GTE(3D 변환을 위한 COP2 word encoding), 컨트롤러, SPU 오디오(ADPCM), CD-ROM 및 ISO9660, 메모리 카드 전용 모듈을 갖춤. 흥미로운 부분은 공유 프로토콜 계층임. SDK 인코더와 에뮬레이터 디코더가 정확히 같은 타입 정의를 사용하므로, 인코딩 불일치는 런타임의 미스터리 버그가 아니라 컴파일 타임 에러가 됨.SDK 위에는 비교적 현대적인 계층도 올렸음. 그래서 raw GTE word와 ordering table 대신 카메라와 씬 단위로 사고할 수 있는 상태.
이 모든 것을 묶기 위한 에디터도 만들었음.
wgpu와egui로 구축했고, 에뮬레이터가 사용하는 것과 동일한 하드웨어 렌더러를 구동함. 따라서 에디터에서 보는 것이 콘솔에서 실행되는 결과와 일치함. 가장 기대됐던 부분은 에뮬레이터를 Claude와 직접 연결했다는 점임. 약 25개의 디버그 엔드포인트를 노출하는 MCP 서버를 구성해, 모델이 작업 중 CPU 상태, VRAM, 레지스터를 직접 들여다볼 수 있게 했음. Claude에게 하드웨어를 살펴보라고 말하는 것만으로 PS1 게임을 디버깅하는 경험은 거의 꿈처럼 느껴짐.요구사항 중 하나는 전체를 Rust 단일 스택으로 작성하는 것이었음. 이제 Cargo 명령만으로 테스트, 2개 타깃(MIPS와 ARM) 빌드, PS1 호환
.bin/.cue생성, CD 굽기까지 깔끔하게 처리됨.그리고 몇 달의 작업 끝에, 드디어 살아 움직임. 이름은 PSoXide라고 붙였고, 이제 큰 보상을 주는 중임. 최근에는 첫 두 Celeste 게임의 포트를 출시했는데, 실제 하드웨어에서 실행되는 모습도 공개했음. 동시에 3D 아티스트와 함께 PS1용 오리지널 소울라이크 게임도 작업 중. 사이드 프로젝트로 진행한 만큼 처음부터 코드가 가장 깔끔하지는 않을 수 있음. 하지만 AI 이전 시대부터 소프트웨어 엔지니어로 일해온 경험 덕분에, 장기적으로는 모델과 오케스트레이션을 제어하면서 코드가 유지보수 가능하고 확장 가능한 상태로 가도록 이끌 수 있다고 봄.
나에게 이 프로젝트는 저위험 프로젝트임. 순전히 열정으로, 이 플랫폼을 사랑해서 하는 일임. 그리고 바로 이 부분이 AI 논의에서 자주 놓치는 지점이라고 생각함. 대부분 LLM이 저품질 결과물을 대량으로 찍어낸다는 이야기지만, 그것은 하나의 사용 방식일 뿐임. 자신이 진짜로 아끼는 무언가를 향해 사용하면, LLM은 창의성을 대체하는 것이 아니라 해방시킴. 이 프로젝트는 혼자였다면 결코 시도하지 못했을 일이고, 모델은 내가 20년 동안 존재하길 바랐던 무언가를 만드는 데 도움을 주고 있음. 레트로 하드웨어 개발에 LLM을 활용하는 사례는 많이 들어보지 못했지만, 앞으로 더 많이 일어났으면 함. 우리는 오래된 콘솔을 위한 새로운 게임의 황금기에 들어서고 있다고 믿으며, 나는 그 흐름을 전적으로 환영함.
PSoXide, Celeste PSX 컬렉션, 내 두 개의 PICO-8 게임까지 모두 itch.io 페이지에 올려둠: https://bonnie-studios.itch.io/
네가 뭘 했고 뭘 썼는지 하나도 이해 못 하겠지만, 축하하고 나 같은 비기술자들을 위한 ms-dos / win 95 / ps1 게임의 진짜 부활을 정말 바람.
Master of Magic?
꽤 괜찮은 품질에 100달러도 안 되는 가격으로, 게임보이 같은 에뮬레이터 많이 써서 쉽게 플레이 가능함. 내 건 Anbernic RG40XX임. 대부분 이동 중에 Helfire datadisc 있는 Diablo 1 함. 컴퓨터로는 도저히 못 하겠는데, 이동 중에는.. 와! (portmaster version)
내가 궁금한건 이 부분뿐임
“Cargo commands now elegantly cover testing, building across 2 targets (MIPS and ARM), down to creating a PS1 compatible .bin/.cue and burning the CD”
이 부분에서 겪은 실패를 자세히 설명해줬으면 함, 어떤 문제들에 부딪혔는지 들어보고 싶음솔직히 그 특정 항목들에서는 엄청난 난관은 없었음. PlayStation은 MIPS 머신이라 게임 코드는 mipsel-sony-psx로 크로스 컴파일됨(nightly + build-std), 반면 에뮬레이터/에디터는 내 호스트에서 네이티브로 빌드되는데, 내 Mac M3의 ARM임. 처음에 진짜 고민이 필요했던 부분 하나는 bare-metal 빌드와 host 빌드가 실제로 단일 cargo 호출을 공유할 수 없다는 점이었고, 그래서 repo를 각자 .cargo 설정을 가진 별도 workspace로 나눴음. 그게 정리되고 나서는 순조로웠고, cargo가 전체를 돌림.
디스크 쪽도 감당 가능했음. PS1 디스크는 잘 문서화된 system area가 있는 ISO9660일 뿐이라, 호환 packer(작은 EXE packer와 ISO builder)를 작성하는 건 이미 범위가 명확한 일이었음. toolchain이 표준 .bin/.cue를 뱉고, 나는 흔한 기성 도구로 그걸 CD-R에 굽는데, 그런 도구는 많음.
진짜 난관은 실제 하드웨어와 에뮬레이터 사이의 동등성을 맞추는 거였음. 콘솔에서 뭔가 다르게 보이거나 들릴 때마다 hardware test disc에 테스트를 하나 이상 추가해서, 작업당 필요한 cycle부터 특정 함수의 edge case까지 전부 정확히 측정할 수 있게 했음. 그 부분은 신중한 계획이 필요했는데, 사실상 반복 한 번마다 디스크 하나를 낭비하는 셈이기 때문임.
이건 내가 본 scope creep 중 가장 아름다운 것임
10-20년 전에 수상한 키오스크에 가서 누군가가 신성한 게임 디스크를 건네주는 대가로 100달러를 냈던 기억이 남
이제 사람들은 20달러짜리 온라인 구독으로 그걸 함
참 굉장한 시대에 살고 있음뭐에 100?
Homebrew랑, 거기에 쑤셔 넣을 수 있는 만큼의 torrent로 꽉 찬 디스크
네 것만큼 고급은 아니지만, 레트로 컴퓨터 코딩이 어떻게 돌아가는지 보려고 commodore 64용 tic-tac-toe 게임을 만들었음. LLM 없이는 못 했을 거임.
https://github.com/jaredevans/c64-tictactoe흥미롭네, 이게 SID chip으로 음악 만드는 데도 적용될지 궁금함.
물론 가능함. 몇 분 걸렸음: 코드는 링크 참고.
https://pastebin.com/wKTayQa6
마음에 듦, 그리고 대부분이 무슨 뜻인지는 전혀 모르겠지만, 20년 전에 만들었던 twin stick top down hoard shooter 컨셉을 다시 만들고 saturn이나 playstation으로 포팅하면서 claude 도움을 받아볼까 한동안 생각해왔음. pico-8을 시작점으로 삼는 것도 고려했음. 그래서 이게 어디까지 갈지 관심 있음. 꽤 멋져 보임.
그렇다면 PSoXide로 네 shooter를 다시 만들어보는 걸 권장함, SDK가 2D 게임을 편하게 포팅할 만큼 충분히 성숙했고, 여기 예제도 많음: https://github.com/EBonura/PSoXide/tree/main/engine/examples
젠장, 이런 프로젝트 너무 좋음. 멋져 보이고 완전 내 취향임 😃 계속 잘해줘!! 나도 11월부터 혼자 mmorpg를 벽돌 쌓듯 만들고 있는데, 몇 년 동안 꿈꾸던 거였고 나도 이것에 대해 정확히 같은 감정을 갖고 있음: " 나는 순전히 열정으로, 그냥 그 플랫폼을 사랑해서 하고 있고, 이게 이 전체 AI 논의에서 사라지는 부분이라고 생각함. 담론의 대부분은 LLM이 slop을 찍어내는 것에 관한 얘기지만, 그건 사용 방식 중 하나일 뿐임. 네가 진짜로 신경 쓰는 것에 겨냥하면, LLM은 창의성을 대체하지 않고 해방시킴. 이건 혼자서는 절대 시도하지 못했을 프로젝트고, 모델은 내가 20년 동안 존재하길 원했던 것을 만들도록 도와주고 있음."
꽤 멋진 프로젝트임.
나는 소프트웨어 엔지니어는 아니지만, 전생에는 Narrative Designer라고 불리는 거칠고 야심 찬 프론트엔드 개발자였고, AI는 예전에 내 창의성을 억눌렀던 소프트웨어 개발의 측면들로 들어가게 도와주고 있음. 그렇긴 해도, 이 글은 실제로 stack을 알고 AI를 어디에 조율해야 하는지 아는 게 Opus에게 “어, ps1 celeste hack 만들어줘, 실수하면 나 소리 지름”이라고 말하는 것보다 훨씬 더 멀리 가게 해준다는 좋은 예시일 가능성이 큼.이거 너무 좋음! 우리는 이런 걸 선물받은 거임, 진짜 10-15년 된 하드웨어랑 집안 가전에서 나온 잡다한 부품들로 지금 내가 할 수 있는 게 그냥 미쳤음
꽤 인상적임. 15년 전에 내가 구워서 실행했던 Nes emulator(imbnes)가 있었는데, 디스크 검증/부팅 과정에서 디스크가 회전 속도를 올리는 동안 뚜껑 스위치를 눌러둔 상태로, 정품 디스크를 여러 속도에서 여러 번 디스크 스왑해야 했음. Claude가 그걸 완전히 우회하도록 도와준 것 같아서, 정말 멋짐!
고마움! 사실 imbnes는 알고 있었고, 조사하다가 우연히 발견했음. LLM 이전 시대에 그런 걸 해냈다는 데 엄청난 존경심이 있음!
아주 멋진 프로젝트임, 잘했고 네가 한 걸 전부 공유해줘서 고마움!
짧은 질문 하나: 무단 코드 실행을 막는 보호 장치가 있는 상황에서, 실제 하드웨어에서 어떻게 실행되게 했음? Sony 화면 뒤의 Playstation 화면이 좀 이상해 보였는데, 그게 그 부작용이었음?고마움! 즐겼다니 기쁨! 사실 그건 2개의 별개 문제임. 콘솔이 구운 디스크를 읽으려면 modchip이 필요함, 실제 PS1 게임에는 CD-R로는 재현할 수 없는 anti-piracy signal이 물리적으로 디스크에 찍혀 있음.
이상한 PS 로고는 다른 문제임, 그 부팅 단계는 disc system area, 즉 BIOS가 로고 화면을 그리기 위해 읽는 첫 몇 섹터의 license/region data에서 그려짐. 그건 Sony의 저작권 데이터라 내 disc builder에서는 선택 사항으로 남겨두고, 내 image에는 제대로 된 게 들어있지 않아서 BIOS가 그 화면을 제대로 그리지 못하고 이상하게 나옴. Sony의 저작권 데이터를 포함하지 않으려고 최대한 조심했으니, 사실 빠진 로고는 그 부작용임.답변 고마움, 정말 흥미롭네! 감사함 - 그리고 다시 말하지만, 완전 멋짐! 😊
나는 ai-engineering 쪽이 궁금함. 어떻게 정리하면서 진행했음? SDD를 썼음? memory management는 어땠음? code review는 어떻게 했음? 어떤 hooks/rules/skills가 가장 효과가 컸음? github에 뭐 있음?
특별히 엄청 fancy한 건 안 함. Zed에서 기본 memory setup으로 agent를 돌리고, 내가 많이 의존하는 건 Graphify, CLAUDE.md, 그리고 최근에는 custom orchestrator(아직 초기 단계)뿐임. code review는 정기적으로 하고, merge되기 전에 가능한 한 diff를 많이 직접 읽음. 진짜 gate는 test suite임, hardware test가 가차 없어서, 실제 콘솔 동작에서 벗어나는 건 diff가 얼마나 깔끔해 보이든 잡힘. 그래서 나는 이걸 SDD라고 부르기보다는 hardware-driven development라고 하겠음, 실제 PS1을 golden truth로 취급하는 거임. 그게 모델을 정직하게 유지시킴.
정리는 거의 전적으로 명확한 관심사 분리와 깔끔한 폴더 구조에서 나옴. repo는 실제보다 커 보이는데, macro level에서는 그냥 네 부분(emulator, SDK, engine, editor)이고, 각각 자체 workspace에 있음. Celeste collection 같은 downstream project는 PSoXide를 third-party dependency로 가져오는데, 덕분에 core가 깔끔하게 유지됨.
그리고 응, PSoXide 포함 내 모든 프로젝트는 full source가 공개되어 있음: https://bonnie-studios.itch.io/맞음, 테스트가 제일 중요함.
좋네.
claude를 어떻게 사용했는지 조금 더 자세히 설명해줄 수 있음? 물론 high level로.
그러니까 BIOS가 일부 공통 로직은 제공하지만, 서로 다른 하드웨어 revision에 대한 translation layer 역할은 하지 않는다는 뜻으로 들림. 아니면 차이가 있더라도 이 SDK에서 직접 처리할 수 있을 만큼 작다는 뜻이거나?
그리고 개발할 때 iteration time을 줄이고, disc는 final test pass용으로 아끼려면 ODE가 가치 있다는 말로도 들림.응, 첫 번째는 네 말이 정확하고, 내가 인지하고 있는 잠재적 blind spot이기도 함. 지금까지 SDK는 꽤 잘 버텨줬지만, 내 물리 테스트는 내가 가진 콘솔 하나, SCPH-9002로 제한되어 있음. 변수를 좀 추가하려고 Superstation-one을 주문했고, 범위를 넓히기 위해 결국 PSone도 하나 구할 수 있음. 어차피 대부분 사람들은 emulator에서 플레이할 거고, 그쪽은 내가 완전히 커버하고 있으니 서두르진 않음, 결국 passion project니까.
그리고 맞음, ODE는 좋은 아이디어임. 다만 Superstation-one이 오는 중이라, 테스트 대부분은 거기에 의존하고 가끔씩 실제 하드웨어용 CD를 굽게 될 것 같음. 중앙화된 testing suite가 있으면 많이 도움 됨
omg
꽤 멋짐.
