
[simsim-arcade 팀 프로젝트]
오늘 가장 큰 작업은 심심오락실의 네 번째 게임으로 2D 대전 격투 게임인 심심파이터즈를 추가한 것이다.
기존의 간단한 아케이드 게임에서 한 단계 더 나아가, 캐릭터 선택과 기술 사용, 상대방과의 전투, 콤보 및 특수 기술 연출까지 구현하는 것을 목표로 했다.
이번 게임에는 남성 캐릭터 8종과 여성 캐릭터 7종, 총 15종의 캐릭터가 등장한다.
별도의 캐릭터 이미지 파일에 의존하지 않고 Canvas 기반 코드로 캐릭터를 그리도록 구성했다.
이를 통해 캐릭터의 외형과 동작, 전투 상황에 따른 시각 효과를 코드 수준에서 제어할 수 있도록 했다.
주요 구현 내용은 다음과 같다.
게임 조작은 키보드 중심으로 구성했다.
| 키 | 기능 |
|---|---|
| A | 주먹 공격 |
| S | 발차기 |
| D | 방어 |
| ↓ + D | 앉아서 방어 |
| F | 초필살기 |
| 방향키 | 이동, 점프, 숙이기 |
| ↓ → + A/S | 필살기 입력 |
별도의 복잡한 조작 장치 없이 키보드만으로 이동, 공격, 방어 및 특수 기술을 사용할 수 있도록 했다.
전투의 재미를 높이기 위해 3단계 텐션 게이지 시스템을 구현했다.
이와 함께 다음과 같은 전투 효과도 추가했다.
단순히 공격과 체력 감소만 구현하는 것이 아니라, 타격감과 전투의 흐름을 시각적·청각적으로 전달하도록 구성했다.
아케이드 모드에서는 AI 상대 6명을 연속으로 상대하도록 구현했다.
AI 난이도는 1~6단계로 구성했으며, 대전이 종료되면 점수를 공통 결과 화면으로 전달해 랭킹에 등록할 수 있도록 연결했다.
이를 통해 한 번의 대전으로 끝나는 구조가 아니라, 연속 전투를 통해 기록에 도전할 수 있는 플레이 흐름을 만들었다.
심심파이터즈에는 온라인 대전 기능도 포함했다.
주요 구현 내용은 다음과 같다.
온라인 대전은 별도의 친선전으로 구성해 일반 랭킹 기록과 구분했다.
다만 실제 네트워크 환경에 따라 P2P 연결이 제한될 수 있으므로, 모든 네트워크 환경에서 연결이 보장되는 것은 아니다.
신규 게임을 추가하면서 게임 내부 구현뿐 아니라 기존 심심오락실 시스템과의 연결도 함께 작업했다.
주요 변경 파일은 다음과 같다.
apps/web/src/games/simsim-fighters/ — 심심파이터즈 게임 구현apps/web/src/games/registry.ts — 게임 목록 및 썸네일 등록packages/shared/src/game.ts — 게임별 최고 점수 기준 등록apps/api/seeds/simsim-fighters.sql — 게임 데이터 등록CLAUDE.md, README.md — 게임 목록 및 문서 갱신새로운 게임을 독립적으로 만드는 데 그치지 않고, 기존 게임 목록과 점수 관리 및 랭킹 시스템에 연결해 서비스 내에서 일관되게 관리할 수 있도록 했다.
관련 PR: https://github.com/SBS-fullstack-A-team/simsim-arcade/pull/80
신규 게임 추가 이후 실제 실행 과정에서 발견된 중요한 오류도 수정했다.
캐릭터를 선택하고 출격하면 게임 화면이 정상적으로 표시되지 않는 문제가 발생했다.
특히 기본적으로 활성화된 크게 보기 모드에서 문제가 나타났다.
게임을 시작하는 과정 자체는 진행되지만, 정작 전투 화면이 렌더링되지 않아 정상적인 플레이가 불가능한 상태였다.
원인은 크게 보기 모드로 전환될 때 발생하는 Canvas 교체 과정에 있었다.
기존 구현에서는 크게 보기 모드로 전환하면 게임 무대가 document.body로 이동하면서 새로운 <canvas> 요소가 생성됐다.
하지만 게임 엔진은 새롭게 생성된 Canvas가 아니라, 화면에서 분리된 이전 Canvas를 대상으로 계속 그림을 그리고 있었다.
즉, 게임 로직이 실행되더라도 실제 사용자가 보고 있는 화면에는 렌더링 결과가 나타나지 않는 구조적인 문제였다.
이 문제를 해결하기 위해 게임 엔진에 FightEngine.attach(canvas) 기능을 추가했다.
핵심 수정 사항은 다음과 같다.
attach(canvas) 메서드 추가다른 게임인 캣 블레이드의 Canvas 연결 방식도 참고해 기존 게임 시스템과 일관성 있게 처리했다.
수정 이후 개발 서버와 헤드리스 Chrome 환경에서 다음 과정을 확인했다.
테스트 결과 게임 화면이 정상적으로 표시되고 공격 동작에 따라 상대방의 체력이 감소하는 것까지 확인했다.
또한 pnpm typecheck, pnpm lint, pnpm build 검사도 통과했다.
이번 수정은 단순히 화면 크기를 조정하는 문제가 아니라, 화면 요소의 생명주기와 게임 엔진의 렌더링 대상이 일치하도록 연결 구조를 바로잡은 작업이었다.
관련 PR: https://github.com/SBS-fullstack-A-team/simsim-arcade/pull/81
게임 기능과 화면 렌더링 문제를 해결한 뒤에는 캐릭터 그래픽의 완성도를 높이는 작업을 진행했다.
기존 Canvas 기반 캐릭터를 격투 게임에 어울리는 수준으로 다시 그려, 전투 화면에서 캐릭터의 개성과 타격감이 더 잘 드러나도록 개선했다.
중요한 점은 이번 작업에서 캐릭터를 그리는 코드만 변경하고 전투 판정이나 시뮬레이션 로직은 수정하지 않았다는 것이다.
캐릭터가 평면적인 도형처럼 보이지 않도록 셀 셰이딩 기반의 명암 표현을 강화했다.
이를 통해 캐릭터의 신체와 장비가 구분되고, 전투 게임 특유의 입체적인 인상을 표현하도록 개선했다.
캐릭터의 얼굴 표현도 전면적으로 수정했다.
표정은 기본, 기합, 피격, KO 상태로 구분했다.
이러한 변화는 캐릭터가 단순히 움직이는 그래픽 요소에 머무르지 않고, 전투 상황에 따라 감정과 상태를 시각적으로 전달할 수 있도록 하기 위한 작업이다.
15종의 캐릭터가 서로 비슷하게 보이지 않도록 의상과 장식의 디테일을 강화했다.
캐릭터별 특징에 맞춰 재킷, 흉갑, 코르셋, 기모노, 실험 가운, 탄띠 등을 표현했으며, 장갑과 부츠, 어깨 장식도 보완했다.
머리카락과 무기, 망토, 날개, 꼬리, 스카프 등의 등 장식도 다시 작업했다.
특정 캐릭터인 리리스의 인형은 크기와 위치를 조정해 화면에서 더 자연스럽게 보이도록 했다.
이러한 개선을 통해 캐릭터 선택 화면뿐 아니라 실제 전투 중에도 캐릭터별 개성이 잘 드러나도록 했다.
시각적인 개선과 함께 렌더링 비용도 줄였다.
돌진 동작에서는 캐릭터의 색상을 활용한 실루엣 잔상을 표현해 이동 방향과 속도감을 강조했다.
또한 체력 바에 표시되는 캐릭터 아이콘은 매 프레임 새롭게 그리지 않고 한 번 그린 결과를 캐시하도록 수정했다.
기존에는 체력 바의 아이콘을 표현하기 위해 매 프레임 두 캐릭터를 추가로 그리는 비용이 발생했다. 이번 변경에서는 해당 결과를 재사용해 불필요한 반복 렌더링을 줄였다.
즉, 이번 작업은 그래픽의 품질만 높인 것이 아니라, 화면에 표시되는 시각적 요소가 늘어나더라도 렌더링 부담을 불필요하게 증가시키지 않도록 개선한 작업이기도 하다.
캐릭터 디자인을 개선하면서 관련 코드도 역할에 따라 분리했다.
| 파일 | 역할 |
|---|---|
looks.ts | 캐릭터별 의상 데이터 |
paint.ts | 셰이딩 및 그리기 도구 |
pose.ts | 기존 자세 관련 코드 분리 |
renderFighter.ts | 캐릭터 렌더링 로직 전면 재작성 |
ui.ts | 체력 바 캐릭터 아이콘 캐싱 |
반면 sim.ts, fighter.ts, hitbox.ts, characters.ts, ai.ts, netplay.ts, config.ts는 변경하지 않았다.
렌더링과 전투 로직을 분리해 시각적 개선이 실제 전투 판정, AI 행동, 네트워크 대전 등에 영향을 주지 않도록 작업 범위를 명확히 했다.
수정 이후 다음 항목을 확인했다.
pnpm typecheck 통과pnpm lint 통과pnpm build 통과테스트를 통해 디자인 변경 이후에도 전투 로직이 유지되고, 실제 플레이 과정에서 그래픽과 조작이 정상적으로 동작하는지 확인했다.
오늘 작업은 신규 기능 구현, 오류 해결, 그래픽 개선이 서로 연결되어 있다는 점에서 의미가 있었다.
새로운 게임을 등록하는 과정에서는 게임 자체의 구현뿐 아니라 기존 게임 레지스트리, 점수 기준, 데이터 시드 및 랭킹 시스템과의 연결까지 고려해야 했다.
기존 서비스의 구조를 유지하면서 신규 게임을 통합하는 경험을 쌓을 수 있었다.
게임 화면이 나타나지 않는 현상은 단순한 스타일 문제처럼 보일 수 있지만, 실제 원인은 게임 엔진과 Canvas 요소 사이의 연결 관계에 있었다.
겉으로 드러난 현상만 임시로 수정하는 것이 아니라, 문제가 발생하는 실행 흐름과 렌더링 대상을 확인해 해결했다는 점이 중요했다.
캐릭터를 더 정교하게 표현하면 렌더링 작업량이 증가할 수 있다.
이번 작업에서는 명암, 얼굴, 의상, 전투 효과를 개선하는 동시에 체력 바 아이콘 캐싱을 적용해 반복적인 그리기 작업을 줄였다.
시각적인 완성도와 성능을 별개의 문제로 보지 않고 함께 고려했다.
캐릭터 디자인 개선 과정에서 전투 판정, 시뮬레이션, AI, 네트워크 관련 코드를 변경하지 않았다.
이처럼 수정 범위를 명확하게 제한하면 기존 기능에 영향을 줄 가능성을 줄이고, 변경 전후의 동작을 검증하기도 쉬워진다.
오늘은 심심오락실에 새로운 게임인 심심파이터즈를 추가하고, 게임 실행 중 발견된 렌더링 오류를 해결한 뒤 캐릭터 디자인과 성능까지 개선했다.
특히 신규 기능을 구현하는 것만큼이나 실제 사용자가 게임을 정상적으로 실행할 수 있는지 확인하고, 그래픽을 개선하면서도 기존 전투 로직이 유지되는지 검증하는 과정이 중요하다는 점을 다시 확인했다.
앞으로도 단순히 게임의 개수를 늘리는 데 그치지 않고, 각 게임의 조작감과 시각적 완성도, 실행 안정성까지 함께 개선해 나갈 예정이다.
오늘의 핵심은 신규 게임 추가, Canvas 렌더링 오류 해결, 15종 캐릭터 리디자인 및 렌더링 최적화다.