TECH 으로 돌아가기
TECH HACKER NEWS 6분 읽기 29 READS

16MHz로 도시 하나를 굴린 심시티, 그 비밀은 '프레임 분산'

16MHz로 도시 하나를 굴린 심시티, 그 비밀은 '프레임 분산'
SOURCE IMAGE · HACKER NEWS

요즘은 가장 저렴한 CPU조차 코어가 네 개 이상이고 초당 수십억 번의 연산을 처리한다. 1GHz도 안 되는 환경에서 제대로 된 소프트웨어가 돌아갔다는 사실이 비현실적으로 느껴질 정도다. 그런데 과거에는 그 수천 분의 일 수준의 하드웨어에서 게임 한 편이 통째로 돌아갔다. 레트로 게임의 기술적 성취라고 하면 보통 둠이나 퀘이크 같은 액션 게임의 그래픽 이정표를 떠올리지만, 경제 전체를 대규모로 시뮬레이션해야 하는 도시 건설 장르의 초기 사례야말로 더 놀랍다. 현대식 도시 건설 게임이 최신 PC에서도 버거워하는 것을 떠올리면 더욱 그렇다.

대표적인 사례가 초기 심시티다. 맥시스의 오리지널 심시티는 시스템 요구사항에 인텔 386SX를 명시했는데, 이 CPU는 출시 당시 16MHz로 작동했다. (원 글쓴이는 처음에 12.5MHz로 잘못 적었다가 바로잡았는데, 12.5MHz는 SX가 아닌 기본 버전의 클럭이었다.) 전통적으로 CPU 부담이 큰 도시 시뮬레이션 게임을, 요즘 단순한 방치형 게임조차 수 기가헤르츠를 요구하는 것과 비교하면, 이 고대의 하드웨어에서 돌렸다는 사실은 분명 흥미로운 질문을 남긴다.

모든 프레임에 모든 걸 계산하지 않는다

이 질문에 답할 수 있는 이유는 심시티의 소스 코드가 2008년 GPL 라이선스로 공개됐기 때문이다. 상표권은 포함되지 않아 코드는 '마이크로폴리스(Micropolis)'라는 다른 이름으로 배포됐지만, 내용은 원작 그대로다. 성능을 분석할 때 흔히 그렇듯 코드의 90퍼센트는 무시해도 되고, 핵심은 교통·화재·전력·범죄 같은 시스템을 갱신하는 도시 시뮬레이션의 중심부다. 그리고 이 모든 것을 담당하는 단 하나의 함수가 있다. s_sim.c에 있는 Simulate() 함수다.

주석대로 이 함수는 매 프레임 호출되며, 내부에서 CrimeScan(), FireAnalysis(), CollectTax 같은 각 게임 시스템의 갱신 함수를 불러온다. 문제는 이 모든 함수를 매 프레임 호출하면 1989년의 빈약한 CPU가 감당하지 못한다는 점이다. 해법은 단순하다. 모든 함수를 매 프레임 호출하지 않는 것이다. 심시티는 사실상 시뮬레이션의 대부분을 건너뛴다. Simulate 함수에서 보통 deltaTime이 들어갈 자리에 있는 mod16 파라미터가 그 열쇠다. 이 값은 0부터 15까지 순환하며, 해당 프레임에서 시뮬레이션의 어느 부분을 실제로 돌릴지 결정한다.

게임플레이에는 거의 영향이 없다

이렇게 하면 계산량은 크게 줄어드는데, 플레이 감각에는 어떤 영향을 줄까. 심시티의 경우 체감상 거의 영향이 없다고 볼 수 있다. 특정 요소의 시뮬레이션이 플레이어의 행동에 반응하기까지 평균 8프레임, 최악의 경우 15프레임이 걸린다. 슈팅 게임의 입력 지연이라면 재앙이겠지만, 도시 시뮬레이션에서는 오히려 즉각 반응하는 것보다 자연스럽게 느껴질 수도 있다. 처리해야 할 작업을 고정 크기로 잘라 여러 프레임에 분산시키는 이 발상은 특정 장르에만 통하는 꼼수처럼 보이지만, 사실은 수많은 최적화의 출발점이다.

2014년작 레이싱 게임 아세토 코르사도 비슷한 기법을 쓴다. 차체의 반짝이는 반사를 표현하려면 주기적으로 갱신되는 큐브맵을 쓰는데, 큐브맵의 여섯 면을 매 프레임 전부 갱신하는 것은 너무 비싸다. 그래서 반사 품질 설정에 따라 일부 면만 갱신한다. 설정 UI에는 드러나지 않지만 .ini 파일을 열면 FACES_PER_FRAME이라는 변수에서 이 효과를 확인할 수 있다. 여기서 한 걸음 더 나아가, 작업을 고정 크기가 아니라 런타임에 그 크기와 내용을 결정하는 방식도 있다. 렌더링에서는 화면 크기나 마지막 갱신 이후 경과 시간 같은 요소로 이를 조절할 수 있다. 언리얼의 루멘(Lumen)이 좋은 결과를 내는 것도, 매 프레임 모든 조명을 다시 계산하지 않기 때문이다. 동시에 반사가 완전히 갱신되지 않아 가끔 결과가 어색해 보이는 것도 같은 이유다.

실무자가 가져갈 교훈

이런 프레임 분산 최적화는 렌더링 코드에서 가장 흔하지만, 심시티 사례가 보여주듯 게임플레이 로직 등 다른 영역에서도 충분히 통한다. 핵심 통찰은 하드웨어 사양이 아니라 사고방식에 있다. 과거 개발자들이 빈약한 하드웨어에서 도시 시뮬레이션을 돌릴 수 있었던 데에는 OS 생태계 같은 외부 요인도 많이 작용했지만, 게임 코드 자체의 영리한 최적화 역시 분명한 몫을 했다. 다만 이 기법은 공짜가 아니라는 점도 기억할 필요가 있다. 반응이 수 프레임 늦어지는 것을 허용할 수 있는 작업에만 적용할 수 있으며, 즉각적인 피드백이 생명인 입력 처리 같은 영역에는 맞지 않는다. 자신이 다루는 시스템이 지연을 얼마나 견딜 수 있는지 먼저 판단하는 것이 전제다. 다음에 게임플레이 코드를 짤 때 스스로에게 이렇게 물어볼 만하다. '이 코드를 정말 매 프레임 다 돌려야 하는가?'

SOURCE · HACKER NEWS
원문 전체 보기 → https://larstofus.com/2025/11/16/how-to-run-a-city-builder-o...
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기 →
처리 중...