웹게임 실행 원리: URL을 입력하면 WebGL·WASM은 어떻게 실행될까?

댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.

댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
웹 게임을 개발해봤다면 이미 웹 기술 위에서 게임을 만들고 있다.
엔진과 빌드 도구가 많은 부분을 대신 처리해주고 있을 뿐이다.
Unity WebGL 같은 웹 게임을 만들다 보면 보통 이런 흐름으로 개발한다.
게임 개발
→ WebGL 빌드
→ 서버 업로드
→ URL 접속
→ 게임 실행
개발할 때는 이 정도로 이해해도 큰 문제가 없다.
그런데 어느 날 이런 문제가 생긴다.
로컬에서는 잘 되는데 배포하면 실행되지 않는다.
게임은 뜨는데 로딩이 너무 길다.
새 버전을 올렸는데 예전 게임이 실행된다.
API 요청이 브라우저에서만 실패한다.
WASM 파일을 받아왔는데 실행되지 않는다.
소리가 자동으로 재생되지 않는다.
이때부터는 게임 엔진만 보고 문제를 해결하기 어려워진다.
왜냐하면 웹 게임은 결국 브라우저라는 실행 환경 위에서 동작하기 때문이다.
이번 글에서는 주소창에 URL을 입력한 순간부터 웹 게임의 첫 프레임이 그려질 때까지 어떤 일이 일어나는지 살펴본다.
우선 전체 그림부터 보자.
사용자는 URL 하나를 입력했을 뿐이지만 브라우저 내부에서는 이 정도의 과정이 지나간다.
게임 개발자 입장에서 중요한 것은 모든 단계를 깊게 공부하는 것이 아니다.
게임이 실행되지 않을 때 어느 구간에서 문제가 발생했는지 구분할 수 있는 정도면 충분하다.
브라우저에 다음 주소를 입력했다고 해보자.
https://game.example.com
사람은 game.example.com이라는 이름을 사용하지만 실제 네트워크 통신에서는 서버의 IP 주소가 필요하다.
그래서 DNS를 통해 도메인을 IP 주소로 변환한다.
조금 더 실제 과정에 가깝게 표현하면 다음과 같다.
여기서 중요한 것은 단순하다.
DNS 단계에서 실패하면 게임 파일은 아직 하나도 다운로드되지 않았다.
게임 화면이 안 뜬다고 해서 항상 Unity나 JavaScript 문제인 것은 아니다.
예를 들어 다음 문제들은 게임 코드 이전 단계에서 발생한다.
도메인이 잘못 연결됨
DNS 레코드가 잘못 설정됨
CDN 도메인 연결 실패
도메인이 아직 전파되지 않음
서버 IP를 알아냈으면 이제 브라우저와 서버가 통신할 준비를 한다.
HTTP/1.1이나 HTTP/2에서는 대략 다음 흐름으로 생각할 수 있다.
주소창의
https://
에는 이 과정이 숨어 있다.
최근에는 HTTP/3처럼 TCP 대신 QUIC을 사용하는 경우도 있지만 핵심은 같다.
서버 위치 확인
→ 안전한 연결 준비
→ HTTP 요청 시작
웹 게임에서는 HTTPS가 단순 보안 문제로 끝나지 않는다.
브라우저의 여러 기능이 HTTPS 기반의 Secure Context를 요구한다.
따라서 로컬 개발 환경에서는 잘 되는데 실제 배포 환경에서는 브라우저 정책 때문에 기능이 달라질 수도 있다.
서버와 연결되면 브라우저가 HTTP 요청을 보낸다.
GET / HTTP/2
Host: game.example.com
서버는 보통 HTML을 반환한다.
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>My Web Game</title>
</head>
<body>
<div id="game-container"></div>
<script src="/Build/game.loader.js"></script>
</body>
</html>
여기서 중요한 포인트가 있다.
브라우저가 처음부터 .wasm 파일을 알고 요청하는 것이 아니다.
HTML을 읽다가 필요한 파일을 발견하고 추가 요청을 시작한다.
HTML 안에는 게임을 실행하기 위한 여러 리소스가 연결되어 있다.
Unity WebGL 빌드를 단순화하면 다음과 비슷하다.
index.html
Build/
├── game.loader.js
├── game.framework.js
├── game.wasm
└── game.data
각 파일의 역할을 대략 나누면 다음과 같다.
| 파일 | 역할 |
|---|---|
index.html | 게임을 실행할 웹 페이지 |
*.loader.js | 게임 빌드를 불러오고 초기화 |
*.framework.js | JavaScript와 Unity 런타임 연결 |
*.wasm | 브라우저에서 실행할 WebAssembly 코드 |
*.data | 게임 실행에 필요한 데이터와 에셋 |
브라우저에서는 대략 다음 흐름으로 로드된다.
즉 주소창에서는 요청 하나처럼 보였지만 실제 Network 탭을 열면 여러 요청을 볼 수 있다.
웹 게임에서 로딩 화면이 길다고 해보자.
처음에는 이렇게 생각하기 쉽다.
서버가 느린가?
하지만 실제 로딩은 여러 단계로 구성된다.
그래서 로딩이 느릴 때는 어디가 느린지 나눠서 보는 것이 중요하다.
예를 들어 .data 파일 다운로드가 대부분을 차지한다면 게임 에셋 크기나 CDN을 봐야 한다.
반대로 다운로드는 금방 끝났는데 게임 시작이 늦다면 초기화나 메모리, WASM 실행 준비를 확인해야 한다.
Network가 느림
→ 파일 크기 / CDN / Cache / Compression 확인
다운로드 후 실행이 느림
→ WASM / 런타임 초기화 / 에셋 처리 확인
이 차이를 모르면 모든 문제를 단순히 "WebGL 빌드가 느리다"라고 묶어버리게 된다.
Unity로 게임을 만들었다면 대부분의 게임 코드는 C#으로 작성했을 것이다.
웹에서는 이 코드가 그대로 실행되는 것이 아니다.
Unity WebGL을 매우 단순화해서 보면 다음 흐름으로 이해할 수 있다.
WebAssembly는 보통 WASM이라고 부른다.
브라우저에서 고성능 연산을 수행할 수 있도록 만들어진 바이너리 명령 형식이다.
웹 게임에서는 JavaScript와 WASM이 함께 동작하는 경우가 많다.
대략적인 역할은 이렇게 볼 수 있다.
JavaScript
- 브라우저 API와 연결
- 페이지와 게임 런타임 연결
- 게임 로딩 제어
WebAssembly
- 컴파일된 게임 코드 실행
- 비교적 무거운 연산 수행
즉 웹 게임이라고 해서 게임 코드 전체가 JavaScript로 바뀌는 것은 아니다.
PC 게임을 생각해보자.
웹 게임은 구조가 하나 더 들어간다.
이 Browser 계층 때문에 여러 제약이 생긴다.
게임 엔진에서는 아무 문제가 없더라도 브라우저 정책 때문에 다르게 동작할 수 있다.
대표적인 것이 자동 재생이다.
게임 개발자 입장에서는 이런 상황이 생긴다.
Unity Editor
✅ 정상 재생
WebGL
❌ 브라우저에서 자동 재생 안 됨
이 문제를 계속 AudioSource 설정에서만 찾으면 해결하기 어렵다.
원인은 게임 엔진이 아니라 Browser Autoplay Policy에 있기 때문이다.
웹 게임 개발 중 자주 만나는 문제를 웹 기술과 연결하면 다음처럼 볼 수 있다.
실제 현상으로 보면 더 이해하기 쉽다.
| 현상 | 확인할 웹 영역 |
|---|---|
| 새 빌드를 올렸는데 예전 버전이 실행된다 | Cache / CDN |
| API가 로컬에서는 되는데 배포하면 실패한다 | CORS / HTTPS |
| WASM 파일 다운로드 후 실행 실패 | MIME Type / Compression |
| 초기 로딩이 너무 길다 | Network / CDN / Asset Size |
| 소리가 자동으로 안 나온다 | Autoplay Policy |
| 외부 리소스를 가져오지 못한다 | CORS / CSP |
| 특정 브라우저에서만 문제가 난다 | Browser API / 호환성 |
| 대용량 게임에서 크래시가 발생한다 | Browser Memory |
웹 게임에서는 이런 문제가 게임 문제와 웹 문제 사이에 걸쳐 있다.
Chrome DevTools의 Network 탭을 열고 웹 게임에 접속하면 우리가 지금까지 본 흐름을 실제로 확인할 수 있다.
예를 들면 다음과 같은 요청이 나타날 수 있다.
Name Status Type
------------------------------------------------
/ 200 document
game.loader.js 200 script
game.framework.js 200 script
game.wasm 200 wasm
game.data 200 fetch
api/user 200 fetch
여기서 특정 파일 하나가 실패한다면 게임이 실행되지 않을 수 있다.
game.loader.js 200
game.framework.js 200
game.wasm 404 ← 문제
game.data 200
이 경우 게임 코드를 디버깅하기 전에 먼저 생각해야 한다.
WASM 파일이 서버에 올라갔는가?
빌드 경로가 맞는가?
CDN이 파일을 가지고 있는가?
요청 URL이 잘못된 것은 아닌가?
반대로 상태 코드는 200인데 실행되지 않는다면 다음 단계로 넘어간다.
HTTP Response Header는 정상인가?
MIME Type은 맞는가?
Compression 설정은 맞는가?
Console에 JavaScript 오류가 있는가?
WASM 초기화가 실패했는가?
문제를 단계별로 좁히는 것이다.
웹의 실행 흐름을 알고 있으면 장애를 다음처럼 볼 수 있다.
이 흐름 하나만 머릿속에 있어도 디버깅 방식이 달라진다.
기존에는
게임 안 됨
→ Unity 확인
이었다면 이제는
게임 안 됨
→ 어느 단계까지 성공했는가?
로 바뀐다.
이 차이가 중요하다.
웹 게임을 만든다고 해서 프론트엔드 개발자 수준으로 모든 웹 기술을 공부할 필요는 없다.
React를 알아야 하는 것도 아니고 CSS를 잘 작성해야 하는 것도 아니다.
우선 이 정도부터 알아도 충분하다.
특히 다음 5가지는 실무에서 바로 도움이 된다.
1. Network 탭 읽기
2. HTTP Status Code 이해하기
3. Cache와 CDN 이해하기
4. CORS 이해하기
5. JavaScript와 WASM이 어떤 관계인지 이해하기
처음에는 웹 게임 실행을 이렇게 생각했다.
빌드
→ 서버 업로드
→ 게임 실행
이제는 그 사이가 조금 더 보인다.
엔진은 이 과정의 많은 부분을 대신 처리해준다.
그래서 평소에는 몰라도 된다.
문제는 엔진이 가려주던 부분에서 문제가 생겼을 때다.
그 순간부터 DNS, HTTP, 캐시, CORS, MIME Type, WASM 같은 단어들이 갑자기 게임 개발 문제 안으로 들어온다.
웹 게임을 개발해봤다면 이미 웹 기술을 사용해본 것이다.
다만 많은 부분을 브라우저와 게임 엔진이 대신 처리해줬기 때문에 직접 마주칠 일이 적었을 뿐이다.
웹 게임은 게임인 동시에 웹 위에서 실행되는 프로그램이다.
그래서 게임 로직만큼 웹의 모든 기술을 깊게 알아야 한다는 이야기는 아니다.
다만 최소한
URL을 입력하면
어떤 파일이
어떤 순서로 내려오고
브라우저가 어떤 과정을 거쳐
게임을 실행하는지
정도는 알고 있는 것이 좋다.
이 흐름을 알고 있으면 다음번에 WebGL 게임이 실행되지 않을 때
"왜 안 되지?"
에서 끝나지 않고,
"어느 단계까지는 정상이지?"
라고 질문할 수 있게 된다.
그리고 웹 게임 개발에서는 그 질문이 문제 해결의 시작이다.
안녕하세요. 게임을 공부하다 보면 한 번쯤은 만들어보고 싶은 프로젝트가 있습니다. 바로 인터넷 연결이 없을 때 크롬 브라우저에서 즐길 수 있는 런게임입니다. 단순한 조작과 쉬운 규칙을 가지고 있지만, 게임 개발에서는 캐릭터 이동, 점프, 충돌 판정, 장애물 생성, 무한 스크롤, 점수 시스템 등 다양한 핵심 기능을 경험할 수 있는 좋은 예제이기도 합니다. 이

우리들의 게임 발매 이야기

안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
안녕하세요. 게임을 공부하다 보면 한 번쯤은 만들어보고 싶은 프로젝트가 있습니다. 바로 인터넷 연결이 없을 때 크롬 브라우저에서 즐길 수 있는 런게임입니다. 단순한 조작과 쉬운 규칙을 가지고 있지만, 게임 개발에서는 캐릭터 이동, 점프, 충돌 판정, 장애물 생성, 무한 스크롤, 점수 시스템 등 다양한 핵심 기능을 경험할 수 있는 좋은 예제이기도 합니다. 이


안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.