Echo of Mana : 컨셉 플레이 개발기
게임 링크 : https://echo-of-mana-readonly.vercel.app/
Echo of Mana
📦 플레이어 인벤토리 나무: 0 철광석: 0 가루시간: 0 열쇠: 0 삽: 없음
echo-of-mana-readonly.vercel.app

총 개발 시간 12시간
- 시간 루프 메커닉 기반 퍼즐 게임 컨셉 플레이 개발 완료
- Next.js + PixiJS 조합으로 웹 프로토타입 제작
Echo of Mana는 타임루프 컨셉의 퍼즐 게임이다.
그 컨셉을 이해할 수 있는 분량만큼을 간단히 제작한 것이다.
우리 에오마는요
Echo of Mana 세계에서는 시간이 반복된다.
플레이어는 매 루프마다:
- 재료를 모으고
- 아이템을 만들고
- 사람들과 상호작용한다
그러면 다음 루프에서 이 행동을 재현하는 ‘정령(spirit)’이 등장해 플레이어와 협력한다.
플레이어는 과거·현재·미래의 행동을 설계하며 퍼즐을 풀어나가야 한다.
노란색 동그라미가 기억을 재생해주는 정령 친구다. UI는 아직 원시적이지만, 돌아갈 건 다 돌아간다.

에코 오브 마나 정보
- 예상 플레이 타임 : 약 1시간
- 장르 : 타임루프 2D 퍼즐
조작법
- 이동 : W / A / S / D
- 상호작용 : E
- 기다리기(시간 보내기) : 스페이스바
플레이 규칙
- 처음에는 60턴이 지나면 처음으로 되돌아온다. 가루시간과 삽을 제외한 아이템과 문의 상태도 초기화된다.
- spirit은 당신의 행동을 따라 한다. 이동, 상호작용, 재료 줍기, 문 열기 등을 복제한다. 단, 닫힌 문은 통과할 수 없다.
- 가루시간(노란색 네모)을 60개 모아 모래시계와 상호작용해보자.
- 철광석이나 목재를 들고 솥과 상호작용하면 재료가 솥으로 옮겨간다. spirit들을 잘 활용하자.
- 새로고침 시 처음부터 다시 시작된다.
- 좌상단에 Echo of Mana 로고가 보이면 클리어다.
아키텍처
- 프론트엔드 : Next.js
- 상태 관리 : Zustand
- 스타일 : Tailwind
- 2D 캔버스 : PixiJS
게임 엔진에 해당하는 core는 순수 상태 머신 구조다.
흐름은 다음과 같다.
- core가 GameState와 userAction을 받아 다음 상태를 계산
- 계산 결과를 Zustand store에 반영
- UI는 React hook으로 store를 구독하여 렌더링
- 사용자 입력(방향키, 클릭, 스페이스바)은 UI → core로 전달
카드게임에서 사용했던 구조를 그대로 가져왔다. 이번에는 WebSocket도 없고 프론트/서버 분리도 없다. UI와 core가 밀착된 단순 구조라 훨씬 수월했다.
성과 우선 vs 개발 공부
바이브 코딩 vs 근본 코딩
회사에 다닐 때부터 고민이 있었다.
코드를 어디까지 직접 다뤄야 하는가.
GPT와 Cursor를 적극 활용하면서 직접 코드를 작성하는 비중은 많이 줄었다. 점점 많은 것을 위임하다 보면 어느 순간 ‘해줘’라고 외치고 있는 자신을 발견하게 된다. 그러면 Cursor는 스파게티를 뽑아내기 시작한다.
개발계의 원로 분들이 보면 혀를 찰 수도 있겠다.
기초를 탄탄히 쌓으라는 말도 당연히 맞다.
그럼에도 내 나름의 기준은 있다.
1. 나는 정체성을 개발자에만 두지 않는다
나에게 개발은 목적이라기보다 수단에 가깝다.
한 줄 한 줄의 코드 이해보다는 기획을 현실화하고 문제를 해결하는 것에 더 초점을 두고 있다.
궁극적으로는 ‘내가 하고 싶은 일로 돈을 버는 것’이 목표다.
그러려면 개발 외에도 마케팅, 기획 등 챙길 것이 많다.
2. 개발 패러다임은 분명 변하고 있다
AI를 활용한 개발 생산성 향상은 이미 체감되는 수준이다.
앞으로는 AI를 개발 프로세스 전반에 활용하는 흐름이 더 강해질 가능성이 높다.
그렇다면 전통적인 개발 역량과 AI 활용 능력을 함께 익히는 방향이 현실적이라고 보고 있다.
그리고 남은 숙제
다만 이번에도 교훈은 분명했다.
Zustand 스키마 설계와 UI–core 분리 같은 거시 구조까지는 깔끔했다.
문제는 core 로직이었다.
로직을 한 번에 몰아 넣었더니 Cursor가 깊은 들여쓰기를 반복하더니 결국 1500줄짜리 함수를 만들어냈다. 그 상태에서 버그가 터지니 Cursor도 난색을 표했다.
다행히 버그 자체는 단순해서 직접 해결할 수 있었다.
다음부터는:
- 더 작은 단위로 설계해서 넘기기
- 함수 단위 자연어 설계 유지하기
이 두 가지를 지켜볼 생각이다.
앞으로 바이브 코딩과 근본 코딩, 그 사이에서 중용을 찾도록 하자.