대표 게임 장르 51종을 각각 하나의 데모로 구현한 시연용 쇼룸입니다. 카드를 누르면 해당 장르가 즉시 실행되고, 내장된 자율 플레이 AI가 알아서 게임을 진행합니다. 발표 중에 켜두면 조작 없이 계속 돌아갑니다.
라이브 데모: https://cherry-company.github.io/game-dev-demo/
git clone https://github.com/Cherry-Company/game-dev-demo.git
open index.html # 그냥 브라우저로 열면 끝
빌드 도구도, npm install도, 개발 서버도 필요 없습니다.
번들러 없이 순수 HTML/CSS/Canvas 2D로만 만들었고 ES 모듈도 쓰지 않았기 때문에
file:// 로 바로 열립니다. 발표 직전에 무언가를 설치해야 하는 상황을 만들지 않는 것이 목적입니다.
정적 서버로 띄우고 싶다면:
python3 -m http.server 8000 # http://localhost:8000
| 키 | 동작 |
|---|---|
R |
자동 순회 — 45초마다 다음 장르로 자동 전환 |
F |
전체화면 |
1–9, 0 |
해당 번호 장르 바로 실행 |
← → |
이전 / 다음 장르 |
N |
오른쪽 발표 포인트 패널 접기/펴기 |
Esc |
목록으로 |
index.html?rotate로 열면 처음부터 자동 순회 상태로 시작합니다. 무인 시연용.index.html#stealth처럼 해시를 붙이면 해당 장르가 바로 실행됩니다. 특정 장르를 즐겨찾기 해두고 쓸 수 있습니다.- 각 장르 화면 오른쪽에는 발표 포인트가 함께 뜹니다. 앞에서 설명할 때 그대로 읽으면 되도록 써 두었습니다.
각 장르는 “그럴듯하게 움직이는 척”이 아니라 실제로 동작하는 알고리즘으로 플레이합니다. 아래 표의 마지막 열이 각 데모에서 실제로 보여줄 수 있는 기술 포인트입니다.
| # | 장르 | 자율 플레이 방식 |
|---|---|---|
| 1 | 플랫포머 | 현재 발판 끝 ~ 다음 발판 간격을 계산해 점프 시점 결정 |
| 2 | 슈팅 | 탄의 미래 위치로 위험도 필드를 만들어 가장 안전한 지점 선택 |
| 3 | 벽돌깨기 | 벽 반사를 나머지 연산으로 접어 낙하 지점을 O(1)로 예측 |
| 4 | 스네이크 | 먹이까지 BFS → 먹은 뒤 꼬리 도달 가능성 재검사 (자멸 방지) |
| 5 | 블록 퍼즐 | 회전×열 전수 시뮬레이션 + 4항 평가(높이·줄·구멍·굴곡) |
| 6 | 레이싱 | 전방 곡률 미리보기로 감속, 라인 오프셋으로 추월 |
| 7 | 타워 디펜스 | 빈 칸별 경로 커버리지 점수 + 간격 페널티로 자동 건설 |
| 8 | 로그라이크 | 우선순위 사다리(전투→회복→수집→탐색→하강) + 다중목표 BFS |
| 9 | 리듬 | 가우시안 타이밍 오차(σ≈22ms)로 사람처럼 판정이 갈리게 연주 |
| 10 | 턴제 RPG | ATB 게이지 + 역할별 판단(힐러/딜러/마법사가 다르게 행동) |
| 11 | 대전 격투 | 발생·지속·경직 프레임 구현, 거리 기반 상태 기계 두 개가 대전 |
| 12 | 스텔스 | 시야원뿔을 이동 비용 ×20으로 환산한 다익스트라 경로 |
| 13 | 매치 3 | 인접 교환 112가지 전수 평가 + 연쇄 1수 예측 |
| 14 | 덱빌딩 | 적 의도를 읽고 "죽지 않을 만큼만" 방어, 나머지는 전부 화력 |
| 15 | 방치형 | 회수 기간(비용÷수익증가) 최소 항목 구매, 자동 환생 |
| 16 | 경영 시뮬 | 주거·상업·공업 수요 순환 + 도로 인접 제약, 도로 선행 확장 |
| 17 | 생존 액션 | 16방향 몬스터 밀도 채점 + 보석 방향 보너스로 카이팅 |
| 18 | 트윈스틱 슈터 | 이동은 반발력 필드, 조준은 예측 사격 — 두 벡터를 분리 |
| 19 | 소울라이크 | 보스 텔레그래프 판독 + 무적 프레임 타이밍 + 스태미나 관리 |
| 20 | 벨트스크롤 액션 | Y축(깊이) 정렬 → X축 접근 → 콤보, 포위 시 무적 기상기 |
| 21 | 실시간 전략 | 경제 루프 + "내 병력 > 상대×1.25" 진격, 절대 상한으로 교착 해소 |
| 22 | 미로 추격 | 유령 넷이 서로 다른 목표 칸(추격·매복·협공·거리유지)을 사용 |
| 23 | 미사일 방어 | 요격점 해석 + 폭발 반경 겹치는 연쇄 유도 |
| 24 | 원버튼 러너 | 도약 고도 v²/2g로 진동 구간을 통로에 정렬 |
| 25 | 오토배틀러 | 시너지 임계치를 넘기는 유닛 우선 드래프트 + 3장 합체 |
| 26 | 포병 대전 | 각도 이분 탐색 20회, 지형 높이맵 실제 파괴 |
| 27 | 축구 | 팀당 추격자 1명, 나머지는 역할 포지션 + 시야 검사 패스 |
| 28 | 물리 파괴 | 임펄스 강체 + 각도24×힘6 격자 탐색(144발 사전 시뮬) |
| 29 | 배틀로얄 | 40인 동일 AI — 생존(자기장) > 성장(전리품) > 교전(우위 판단) |
| 30 | 공장 자동화 | 대기열이 가장 긴 공정을 병목으로 판정해 증설 |
| 31 | 복셀 샌드박스 | 아이소메트릭 투영 + x+y+z 페인터 정렬, 채굴/건축 모드 전환 |
| 32 | 그래플링 액션 | 진자 구속 + 착지점이 최대가 되는 순간 릴리스 |
| 33 | 퍼즐 RPG | 속성별 필요도 가중치로 매치 선택 (회복/방어/공격 전환) |
| 34 | 메트로배니아 | 능력 보유 여부를 간선 조건으로 넣은 방 그래프 BFS |
| 35 | 함대 전투 | "가장 먼저 격침 가능한 적"에 화력 집중 (란체스터 법칙) |
| 36 | 비주얼 노벨 | 호감도 기댓값 선택 + 임계값 3분기 엔딩 |
| 37 | 1인칭 레이캐스트 | 화면 열마다 광선 1개 + DDA + 어안 보정 — 픽셀 3D 연산 없음 |
| 38 | 체스 | 미니맥스 + 알파베타 가지치기, 기물가치 + 위치표 평가 |
| 39 | 핀볼 | 법선 반사 v′=v−2(v·n)n, 낙하 시간 예측 플리퍼 |
| 40 | 레인 디펜스 | 레인별 "적 체력 ÷ 아군 DPS"로 돌파 시각 예측 |
| 41 | 달 착륙선 | PID 2축 제어, P·I·D 항이 실시간 게이지로 표시 |
| 42 | 군집 생존 | 분리·정렬·응집 3규칙 + 포식자 회피에서 나오는 창발 |
| 43 | 힐클라임 레이싱 | 스프링 서스펜션 2륜, 전방 경사로 스로틀 분배 |
| 44 | 턴제 택틱스 | 엄폐·측면·사거리 위치 점수 + 명중 기댓값 표적 선정 |
| 45 | 타이핑 디펜스 | WPM 모델 + 오타율, 남은 글자 ÷ 타속 vs 낙하 시간 |
| 46 | 오목 | 열린4/막힌4 패턴 점수를 공격·방어 양방향으로 합산 |
| 47 | 페그 드롭 | 발사각 48개 몬테카를로 롤아웃 (카오스라 해석 불가) |
| 48 | 슬라이딩 퍼즐 | A* + 맨해튼 휴리스틱, 전개 노드 수 실시간 표시 |
| 49 | 낚시 | 장력 히스테리시스 밴드 제어 (상한 풀고 하한 감기) |
| 50 | 노선 설계 | 혼잡도 최대 역 + 최소 삽입 비용 (TSP 삽입 휴리스틱) |
| 51 | 레스토랑 경영 | EDF 스케줄링 — 인내심 ÷ (작업시간 + 이동시간) |
게임 51개를 각각 예쁘게 칠하는 대신, 엔진에 공통 레이어를 넣어 전부를 한 번에 끌어올렸습니다.
FX 레이어 (js/engine/fx.js)
- 카메라 — 트라우마 기반 흔들림. 누적값을 제곱해서 쓰기 때문에 큰 타격이 작은 타격보다 훨씬 무겁게 느껴집니다.
- 히트스톱 — 강한 충돌 시 시뮬레이션을 몇 프레임 멈춥니다. 격투 게임의 손맛이 여기서 나옵니다.
- 이펙트 풀 — 스파크·충격파·파편·연기·광선·데미지 텍스트. 고정 용량 링버퍼라 장시간 실행에도 할당이 없습니다.
- 블룸 — 완성된 프레임을 1/4로 축소했다가 다시 더합니다. 브라우저의 이중선형 필터가 블러를 공짜로 해주기 때문에 드로우콜 2번이면 끝입니다. 셰이더 없이 얻는 가장 큰 시각적 상승입니다.
- 필름 그레인 / 스캔라인 / 비네트 — 미리 렌더한 노이즈 타일과 캐시된 그라디언트로 처리합니다.
배경 라이브러리 (Scenes)
nebula 성운 · grid 신스웨이브 · city 야경 스카이라인 · dungeon 횃불 던전 · arena 스포트라이트 경기장 · aurora 오로라 — 전부 시간 기반 애니메이션이고, 게임마다 한 줄로 갈아끼웁니다.
이 구조 덕분에 새 장르를 추가하면 카메라·히트스톱·블룸·배경을 자동으로 물려받습니다.
css/tokens.css 가 단일 원천입니다. 3계층으로 나눠 두었습니다.
PRIMITIVE 원시 스케일 (중립 램프, 색상, 타입, 간격, 반경, 모션)
↓
SEMANTIC 역할 별칭 (--yj-bg-surface, --yj-fg-muted, --yj-accent …)
↓
PLAY 캔버스 팔레트 (--yj-play-hero, --yj-play-foe, --yj-play-ramp-1…8)
Canvas는 CSS 변수를 직접 읽지 못하기 때문에 js/engine/palette.js 가 부팅 시 한 번
--yj-play-* 를 해석해 동결된 팔레트 객체로 모든 게임에 넘겨줍니다.
그래서 51개 게임 파일 어디에도 색상 리터럴이 없습니다. 테마 교체는 순수 CSS 수정입니다.
tokens.css 의 PRIMITIVE 블록과 --yj-play-* 색상만 교체하면 됩니다.
SEMANTIC 계층과 모든 소비 코드는 그대로 둡니다.
이 저장소의 토큰 값은 쇼룸의 어두운 발표 환경과 캔버스 가독성에 맞춘 프로젝트 전용 값입니다. 프리미티브 → 시맨틱 → 플레이 팔레트 구조를 유지하면 소비 코드를 바꾸지 않고 리테마할 수 있습니다.
index.html 쇼룸 셸 (게임 스크립트 로드 순서 = 쇼룸 표시 순서)
css/tokens.css 디자인 토큰 3계층
css/showroom.css 쇼룸 크롬 (시맨틱 토큰만 소비)
js/engine/palette.js CSS 토큰 → 캔버스 팔레트 브리지
js/engine/fx.js 카메라·히트스톱·이펙트 풀·블룸·그레인·배경 라이브러리
js/engine/core.js RNG, 드로잉 파사드, 레지스트리, 러너(포스트 체인 포함)
js/showroom.js 그리드·스테이지·순회·키보드
js/games/*.js 장르 51종
무인 상태로 오래 켜두는 용도라서, 흔한 실패 지점을 미리 막아 두었습니다.
- 고정 타임스텝 + 백로그 클램프 — 탭이 백그라운드로 갔다 돌아와도 밀린 프레임을 한꺼번에 돌리지 않고 버립니다. 방치형 데모가 죽는 가장 흔한 원인입니다.
- 탭 비가시 시 정지/재시작 — 백그라운드 rAF 스로틀링으로 인한 급발진을 막습니다.
- 고정 용량 파티클 풀 — 워밍업 이후 할당이 없어 장시간 실행에도 누수가 없습니다.
- 모든 게임이 스스로 재시작 — 사망·전멸·교착 시 배너를 띄우고 자동 리셋합니다. 영원히 멈춰 있는 화면이 나오지 않습니다.
검증: 51개 전 장르 실행 + 자동 순회 약 110초 연속 구동에서 콘솔 오류 0건, JS 힙 10.0MB → 10.0MB (증가 없음).
js/games/ 에 파일을 만들고 index.html 에 <script> 한 줄을 추가하면 끝입니다.
Games.define({
id: 'my-genre', name: '표시 이름', genre: 'Genre Label',
hue: 1, // --yj-play-ramp-1 … 8
desc: '카드에 들어갈 한 줄 설명',
notes: ['발표 포인트 1', '발표 포인트 2'],
spec: { '항목': '값' },
width: 640, height: 400,
poster(g, hue, rng) { /* 카드 썸네일 1프레임 */ },
create(env) { // env = { W, H, rng, P, g, fx, cam, shake, freeze, flash }
return {
update(dt) { /* 고정 1/60 스텝 */ },
draw(g) { /* 월드 — 카메라 변환 안에서 그려짐 */ },
hud(g) { /* 선택 — 화면 고정, 블룸 위에 그려짐 */ },
};
},
});