아무도 내 포트폴리오에 관심을 보이지 않아서, 대신 모두에게 그것을 플레이하게 만들었다.
Source: Dev.to
새해, 새로운 당신 포트폴리오 챌린지
Google AI 제공
조작법
키보드 및 마우스
| 동작 | 키 / 입력 |
|---|---|
| 이동 | A/D 또는 ←/→ 키 |
| 점프 | Space 키 |
| 이모지 창 | Q 키 |
| 줌 인/아웃 | 마우스 스크롤 |
웹사이트:
🎮 챌린지: 지도 곳곳에 흩어져 있는 모든 수집 카드를 찾아보세요. 모두 모았을 때 스크린샷을 댓글에 올리세요!
왜 만들었는가
“다음 5분 안에, 왜 내가 포트폴리오를 더 기이하게 만들기 위해 3년 동안 직접 네트워킹 스택을 구축했는지 알게 될 것입니다.”
창의적인 분야에서 일하면서, 지루한 스크롤 페이지는 전혀 맞지 않았습니다. 나는 내가 할 수 있는 것을 보여주고 싶었지, 단순히 나열하고 싶지는 않았습니다. 그래서 기존 포트폴리오 사이트를 온라인 멀티플레이어 게임 세계로 바꾸어 거의 무엇이든 할 수 있게 만들었습니다.
나는 기술이 몰입감 있고, 인터랙티브하며, 한계를 뛰어넘어야 한다고 믿는 게임 개발자입니다. 이 포트폴리오는 단순 백엔드부터 복잡한 멀티플레이어 시스템까지, 수년간의 실험, 실패, 그리고 구축을 나타냅니다.
게임 내에서 보게 될 내용
위에 삽입된 애플리케이션은 완전한 기능을 갖춘 크로스‑플랫폼 멀티플레이어 게임으로, 나의 인터랙티브 포트폴리오 역할을 합니다. 기존 웹사이트를 스크롤하는 대신, 방문자는 게임을 플레이하면서 다음과 같은 실시간 업데이트를 확인할 수 있습니다:
- 최신 YouTube 동영상
- GitHub 활동 및 기여
- 인디 게임 프로젝트
- 오픈소스 프로젝트
- 무작위 “오늘의 Dan 사실”
수집 가능한 카드가 지도 곳곳에 배치되어 있으며, 각각은 나와 내 경력에 대한 사진과 정보를 보여줍니다. 또한 특별한 버튼이 있어 내가 가능한 경우 나를 세상으로 부를 수 있게 합니다—전통적인 포트폴리오에서는 할 수 없는 일입니다.
기술 사양
| 구성 요소 | 세부 정보 |
|---|---|
| Game Engine (client‑side) | Unity 6 (WebGL 빌드, 모바일 지원 포함) |
| Networking | Dan.Net – 내가 만든 Go + WebSockets 스택 |
| Deployment | Google Cloud Run (메모리 2 GB, vCPU 2 개) |
| AI Assistant | 워크플로 최적화를 위한 Google Antigravity |
| APIs | YouTube Data API, GitHub API |
| Server | gzip 처리를 지원하는 커스텀 Node.js HTTP 서버 |
Note: 나는 기성 멀티플레이어 솔루션을 사용하지 않았다. 핵심 게임 로직과 통계 표시부터 네트워킹 레이어까지 모든 것을 Dan.Net이라는 전체 네트워킹 스택을 포함해 직접 구축했다.
재미있는 사실
저는 Aseprite를 사용해 대부분의 아트 에셋을 직접 그렸습니다 (스킨과 타일용 무작위 PNG는 제외하고). 음악은 Toyota Corolla 2008 테마입니다—음악 선택에 대해 의문을 제기하지 마세요! 😉
여정 타임라인 (4 년)
| 연도 | 주요 사건 |
|---|---|
| 2021 | Photon Engine으로 시작해 몇몇 게임을 만들었지만, 기본 메커니즘을 이해하지 못한 채 함수만 호출하고 있다는 느낌이 들었습니다. |
| 2022 | 토끼굴에 빠짐: Python/Flask를 실험하고, Leaderboard Creator 툴을 제작했습니다(현재 itch.io에서 가장 높은 평점을 받은 툴 중 하나). PHP를 시도하고, Node.js와 WebSockets로 전환했습니다. 2022년 말에 Dan.Net 아이디어가 탄생했습니다. |
| 2023 | 고된 작업. 멀티스레드 레이스 컨디션 디버깅에 연속 3일을 보냈습니다. 결국 작동했을 때, 그 3일은 제 인생에서 가장 보람된 순간 중 하나가 되었습니다. |
| 2025 | Dan.Net을 안정적이고 프로덕션 준비가 된 상태로 끌어올려 실제 프로젝트에 사용할 수 있게 했습니다. |
멀티플레이어 아키텍처 (간소화)
- Room System – 플레이어는 방 이름을 사용해 방을 만들거나 참여할 수 있습니다. 방은 “플레이어 풀” 또는 “매치”와 같습니다.
- Event‑based Networking – 중요한 행동(플레이어 입장, 카드 획득, 스킨 변경)은 버퍼링된 이벤트로 서버에 전송됩니다. 이모지 반응은 직접 이벤트로 전송됩니다. 서버는 이를 해당 플레이어들에게 브로드캐스트합니다.
- Stream‑based Networking – 몇 밀리초마다 각 플레이어는 현재 위치를 전송합니다. 서버는 모든 위치를 집계하고 다른 플레이어들의 위치 업데이트를 다시 전송합니다.
그 뒤에서는 보간, 지연 보상, 대역폭 최적화 등—모두가 세계에 대한 뷰를 동기화하게 하는 재미있는 요소들이 작동합니다.
Unity WebGL을 Gzip으로 Cloud Run에 배포하기
Unity의 WebGL 빌드는 gzip 압축을 사용합니다. 이는 배포하려고 할 때 문제가 될 수 있습니다. 브라우저는 이러한 파일을 올바르게 압축 해제하기 위해 특정 HTTP 헤더가 필요하며, Cloud Run은 기본적으로 이를 설정하지 않습니다.
해결책: 나는 다음과 같은 맞춤형 Node.js HTTP 서버를 만들었습니다:
.gz파일을 감지하고Content‑Encoding: gzip헤더를 설정합니다- WebAssembly, JavaScript 및 데이터 파일에 대한 올바른 MIME 타입을 유지합니다
- 교차 출처 요청에 대해 CORS를 올바르게 처리합니다
- 적절한 캐싱을 통해 36 MB 빌드를 효율적으로 제공합니다
Google Antigravity가 여기서 많은 시간을 절약해 주었으며, 헤더 설정을 디버그하고 서버 구성을 최적화하는 데 도움을 주었습니다.
Antigravity가 도움이 된 방법
- Dan.Net 개선: Unity 클라이언트가 Go 백엔드와 통신하는 방식을 다듬었으며, 특히 WebSocket 연결 처리와 상태 동기화에 중점을 두었습니다.
- Cloud Run 디버깅: Unity 빌드가 로드되지 않는 이유를 조사했습니다(헤더 때문이었습니다). Antigravity를 통해 Unity의 압축, HTTP 헤더, 브라우저 요구사항 간의 관계를 이해할 수 있었습니다.
- API 통합: YouTube와 GitHub API를 키를 노출하거나 취약점을 만들지 않도록 안전하게 구현했습니다. 최신 동영상과 기여도를 보여주는 동적 보드는 적절한 API 설정 없이는 작동하지 않았습니다.
요약
Go 기반 네트워킹 솔루션을 직접 만들고 이를 Unity와 성공적으로 통합하여 크로스‑플랫폼 멀티플레이어를 구현함으로써 full‑stack capabilities를 보여줍니다. 이는 저수준 네트워킹 프로토콜부터 고수준 게임 개발까지 아우릅니다.
Dan.Net을 확인하여 코드를 살펴보고 이 인터랙티브 포트폴리오 뒤에 있는 스택에 대해 더 알아보세요.
포트폴리오 비전
이것은 내가 지금까지 한 일을 보여주는 것만이 아니라, 내가 할 수 있는 일을 보여주는 것입니다. 진정한 포트폴리오는 정적인 페이지가 아니라, 당신의 기술과 개성을 반영하는 경험이어야 합니다. 여기서 ANYTHING을 할 수 있다고 말한 것은 진심이었습니다.
동적 기능
- Live Boards – 내 활동(최신 YouTube 동영상, 최근 GitHub 커밋)을 기반으로 자동 업데이트됩니다. 세상이 언제나 살아있고 최신 상태처럼 느껴집니다.
- “Dan Fact of the Day” – 매일 바뀌어 방문자는 수동 업데이트 없이도 항상 새로운 콘텐츠를 볼 수 있습니다.
- Collectible Cards – 탐색하면서 정보를 드러내어 인터랙티브한 레이어를 추가합니다.
- Call‑to‑Action Button – 버튼을 누르면 내가 가능할 경우 세상에 합류합니다. 😉
기술 하이라이트
- Unity 6 Web Support – 게임이 데스크톱, 모바일, 웹 브라우저에서 원활하게 실행됩니다.
- Powered by Dan.Net – 프론트‑엔드 기술뿐 아니라 다음 분야에 대한 탄탄한 이해를 보여줍니다:
- 네트워킹 프로토콜
- 상태 관리
- 분산 시스템
- 백엔드 아키텍처
창작자를 위한 조언
“당신의 작업을 공유하고, 여정을 기록하세요.”
- 당신이 만든 것과 아직 만들고 있는 것 모두에 자부심을 가지세요 그리고.
- 주저하지 말고 자신을 내보이세요.
공유가 중요한 이유
- 보면서 배우기: 공유할 때—지저분한 부분까지—다른 사람들에게 시도할 수 있는 허가를 줍니다.
- 영감: 당신의 이야기가 누군가가 첫 발을 내딛는 데 정확히 필요한 것일 수 있습니다.
- 모멘텀: 누군가가 해결하는 모습을 보면 “나도 할 수 있겠어”라는 생각이 떠오를 수 있습니다.
배운 것이 헛되이 사라지는 일은 없습니다. 그것은 다음 황당한 아이디어에 나타날 뿐입니다.
내 포트폴리오는 수년간의 실험, 실패한 프로젝트, 그리고 학습 순간들의 결실이며—모두가 모여 내가 진심으로 자부하는 무언가가 되었습니다.
참여하기
- 시도해보고 댓글에 의견을 알려 주세요!
- 게임 개발, 네트워킹 시스템, 오픈‑소스 개발에 관심이 있거나 그냥 같이 놀고 싶으신가요?
- 제 Discord 서버를 통해 연락 주세요 – 연결하고 싶어요!
더 보고 싶으신가요?
- 비하인드 씬 콘텐츠, 기이한 프로토타입, 그리고 개발 로그에 대한 내용은 다음에서 확인할 수 있습니다:
- YouTube 채널
- GitHub
제 포트폴리오를 탐색해 주셔서 감사합니다. 여러분의 소식을 기다리고 있겠습니다!