원문 캡처 · kodoque1.github.io
원문 캡처 · kodoque1.github.io

Doomception은 Doom 2 복사본 세 개를 한 프로세스에서 번갈아 실행하고, 각 복사본의 화면을 다음 복사본의 벽 텍스처로 보여주는 프로젝트다. 브라우저에서는 여러 게임 복사본의 상태를 분리하는 스케줄러를 직접 작성하고 검증하는 과제도 제공한다.

DOS에는 프로세스와 스레드, 메모리 보호 기능이 없고 Doom 2는 혼자 실행된다고 가정해 만들어졌다. 프로젝트는 운영체제가 하듯 각 복사본에 별도 메모리를 할당하고, 공유 상태를 저장·복원하며, CPU 실행을 복사본 사이에서 전환한다. 전환은 네 프레임마다 프레임 렌더링이 끝난 뒤 이뤄진다. 공통 상태는 577,494바이트지만 기록된 실행에서는 전환 시 달라진 부분이 1,336바이트였고, 호스트는 전체를 비교한 뒤 바뀐 부분만 복사했다.

세 복사본은 Doom 코드를 공유하지만, 각각 자체 힙과 스택, 화면 버퍼, ACE 코드 복사본을 가진다. Doom의 데이터는 코드가 가정하는 고정 주소에 놓이므로 한 번에 한 복사본의 데이터만 활성화할 수 있다. 전환할 때 현재 복사본의 데이터를 저장하고 다음 복사본의 데이터를 불러온 뒤, 힙과 화면을 가리키는 포인터 세 개를 갱신하고 스택을 바꾼다. 데이터 스냅샷에 포함되지 않는 코드 패치도 복사본별로 저장하고 복원한다.

각 복사본은 자기 화면 버퍼에 렌더링하며, 레벨의 벽 텍스처는 다음 복사본의 화면을 보여준다. 마지막 복사본은 첫 번째 복사본의 화면을 가리켜 고리를 만든다. 실행이 멈춰 있는 복사본은 렌더링하지 않으므로 이웃 화면에는 마지막 프레임이 나타난다. 모니터에는 한 번에 한 버퍼만 표시되며, y 키로 보는 복사본을 바꿀 수 있다. 보는 복사본은 다른 복사본보다 두 배 자주 실행돼 화면은 초당 30프레임, 나머지 복사본은 초당 15프레임으로 실행된다.

프로젝트는 저장소에서 확인할 수 있다. kgsws의 doom_ace를 포크했으며, 엔진은 저장소 루트에, 전환 코드는 nested/에 있다. 관련 README는 각 부분의 구현 과정과 문제를 설명한다.

브라우저 과제 페이지에서는 64KiB 크기의 가상 컴퓨터와 C 컴파일러, 코드 패치가 포함된 Doom 유사 게임을 대상으로 여러 복사본을 관리하는 스케줄러를 작성한다. 검사기는 각 레벨을 단독 실행한 결과와 복사본별 상태를 프레임마다 비교한다. 스케줄러가 검사를 통과하면 전환에 드는 사이클과 바이트를 기준으로 점수를 매긴다. 페이지에서는 스케줄러를 컴파일하고 검사하며 기계를 명령어 단위로 실행할 수 있다. 컴파일러와 기계, 검사기는 키트 자체의 C 코드를 WebAssembly로 컴파일한 것이며, 결과는 sandbox/에서 make check를 실행한 결과와 같다.