The Legend of Zelda: Breath of the Wild의 물리 + 화학/상태 상호작용 시스템에서 영감을 받아, 그 토대가 될 **커스텀 게임 엔진 기반(foundation)**을 직접 만드는 프로젝트입니다.
- 무엇인가: 객체가 월드에 존재하고, 움직이고, 서로의 접촉(contact)을 감지하는 최소한의 2D 게임 엔진 토대.
- 왜 만드는가: 다음 단계인 화학/상태 반응 시스템(불 + 나무 = 연소, 물 + 불 = 소화 등)을 올릴 수 있는 구조를 먼저 안정적으로 마련하기 위함.
- 무엇이 아닌가: Unity/Unreal급 엔진이 아니며, 아직 화학 규칙이나 플레이 가능한 퍼즐 데모도 아님. 포트폴리오용으로 작고 이해하기 쉬운 토대가 목표.
- 기술 스택: C++17 + CMake. 별도의 창/그래픽 의존성 없는 콘솔(헤드리스) 실행 (Codespaces 친화적, ASCII 출력 + 로그로 동작 증명).
단계: 화학 시스템 직전(pre-chemistry) 토대 — 완료. 객체는 존재/이동/접촉 감지가 되며, placeholder 재질·상태 데이터를 가집니다. 화학 규칙은 아직 구현되지 않았습니다.
| 영역 | 위치 | 설명 |
|---|---|---|
| 2D 벡터 수학 | include/engine/Vec2.h |
위치·크기·속도 |
| 재질/상태 placeholder | include/engine/Material.h |
Material + ObjectState enum (데이터만, 규칙 없음) |
| 월드 객체 | include/engine/GameObject.h |
id, name, AABB 위치/크기, 속도, static 여부, material, state |
| 월드 + 접촉 시스템 | include/engine/World.{h,cpp} |
적분(이동) + AABB 접촉 감지 + begin/end 이벤트 |
| 애플리케이션/게임 루프 | include/engine/Engine.{h,cpp} |
고정 timestep, update/render 분리, 스크립트 입력, 정상 종료 |
| 샌드박스 씬 | src/main.cpp |
player, wall, crate, water puddle |
| 결정론적 테스트 | tests/tests.cpp |
ctest로 실행 |
- Player — 조작 가능,
Material::None,State::Normal - Wall — 정적 장애물,
Material::Stone - Crate — 이동 가능한 테스트 객체,
Material::Wood - Puddle — 향후 상호작용 테스트용으로 예약,
Material::Water,State::Wet
CMake ≥ 3.16, C++17 컴파일러(g++/clang++) 필요.
cmake -S . -B build
cmake --build build# 샌드박스 데모 (콘솔 / ASCII, 창 불필요)
./build/engine_demo
# 결정론적 토대 테스트
ctest --test-dir build --output-on-failure플레이어가 오른쪽으로 이동하며 크레이트 → 물웅덩이 → 돌벽을 통과합니다 (충돌은 감지만 하고 아직 반응시키지 않음). 실행 시 출력:
- 각 객체의 material/state placeholder가 담긴 객체 목록.
- 10프레임마다 ASCII 그리드 (
P=player,#=wall,B=crate,~=water). CONTACT BEGIN/contact end로그 — 양쪽 객체의 material+state 포함 (예:Player (None/Normal) <-> Puddle (Water/Wet)).- 실행 전체에 걸쳐 접촉 기록이 유지됨을 보여주는 최종 요약.
→ 객체 존재, 업데이트 루프, 이동, 접촉 감지, 재질/상태 데이터 흐름이 모두 동작한다는 증거.
World::detectContacts()가 내보내는ContactEvent스트림을 소비하는ReactionSystem추가.Material+ObjectState에 대한 규칙 적용. (예: 불꽃이Wood에 닿음 →Burning;Burning이Water에 닿음 →Normal등.)- 충돌 반응(collision response) 추가 — 객체가 서로 막거나 밀도록.
- 이 토대 위에 작은 플레이 가능 퍼즐 씬 구축.
- 공간 분할(spatial partitioning)로 접촉 감지 최적화 (현재 O(n²)).
- 실시간 창/렌더링 백엔드(SDL 등)로 교체 옵션.
- 상태 전파(예: 화염/전기 확산), 지속 시간/타이머, 재질별 속성.
이 프로젝트가 단계별로 “토대 → 화학 → 퍼즐” 순서를 지키기 위한 규칙.
- 현재 단계에서 화학 규칙을 구현하지 않는다.
Material/ObjectState는 순수 데이터(placeholder)로만 유지한다. - 오버엔지니어링 금지. ECS, 에셋 파이프라인, 스크립팅, 대형 UI 등은 필요해지기 전까지 추가하지 않는다.
- 한 번에 한 단계만 진행한다. 다음 단계로 넘어가기 전 현재 단계가 빌드/테스트/데모로 증명되어야 한다.
- AABB 규약: 객체는 축 정렬 바운딩 박스.
position은 박스 중심,size는 전체 너비/높이. - 접촉 판정은 포함(inclusive): 모서리가 맞닿기만 해도 접촉으로 본다 (향후 화학 시스템이 밀착 객체끼리 반응시키길 원하기 때문).
- 접촉 기록: 객체 쌍은 정렬된
(작은 id, 큰 id)키의ContactRecord로 관리.touching(이번 프레임),framesTouching(지속 시간),totalContacts(접촉이 새로 시작된 횟수)를 추적. - 이벤트 훅: 접촉 시작/종료 프레임에 begin/end 이벤트를 내보낸다 — 이것이 향후 반응 시스템이 연결될 지점.
- ID는 명시적·안정적으로 부여(배열 인덱스에 의존하지 않음).
update(시뮬레이션)와render(표현)를 분리하고, 물리/접촉 로직이 렌더 해상도에 의존하지 않게 한다.- 결정론 유지: 입력은 프레임 기반 스크립트로, 같은 실행은 같은 결과를 낸다.
- 컴파일 경고 활성화(
-Wall -Wextra -Wpedantic), 경고 없이 빌드. - 핵심 불변식(AABB, 접촉 카운팅, static 미적분)은
tests/의 결정론적 테스트로 보장하고ctest로 검증. - 빌드 산출물(
build/)은 커밋하지 않는다(.gitignore).
- 화학/반응 규칙 (Fire+Wood 등) — 데이터만 존재.
- 충돌 반응 — 접촉 감지만, 밀어내기 없음.
- 실시간 창/렌더링 — 헤드리스 ASCII 출력.
- ECS / 에셋 파이프라인 / 스크립팅.