48 lines
4.4 KiB
Markdown
48 lines
4.4 KiB
Markdown
---
|
||
kind: contracts
|
||
title: 게임별 WebGL 화면 크기 계약
|
||
owner: bibimbap
|
||
stability: living
|
||
last_reviewed: 2026-10-14
|
||
---
|
||
|
||
# 게임별 WebGL 화면 크기
|
||
|
||
게임의 기준 폭·높이를 등록 정보에 저장하고 플레이어 iframe을 같은 비율로 가용 폭·높이 안에 표시한다. 게임명·ZIP 파일명에 따른 특별 처리는 없다. 이 값은 빌드에 선언된 화면 크기이며 Unity 내부 UI 재배치를 보장하지 않는다.
|
||
|
||
## 감지와 검증
|
||
|
||
작성자의 직접 지정이 우선한다. 자동 감지는 선택된 `index.html`과 같은 디렉터리의 `build-info.json` top-level `width`/`height` → 명확한 canvas 또는 그 조상 `#unity-container`의 정수 pixel CSS → canvas의 명시 `width`/`height` 속성 순이다.
|
||
|
||
Canvas는 `#unity-canvas`가 하나이면 선택하고, 해당 ID가 없으면 canvas가 정확히 하나인 경우 선택한다. CSS는 inline 또는 `style` 블록의 정확한 단일 ID selector만 지원한다. `@` 규칙이 포함된 style 블록, 상대 단위·동적 표현식·외부 CSS·JavaScript style 대입은 감지하지 않는다. JS 실행이나 외부 요청은 하지 않는다. CSS cascade 전체를 계산하는 브라우저가 아니므로 감지된 선언값이 실제 게임과 다르면 직접 지정한다.
|
||
|
||
폭·높이는 둘 다 정수 1~16384, 비율은 1:32~32:1이다. 숫자 문자열도 허용하되 분수·부호·공백은 허용하지 않는다. 자동 감지의 300×150은 브라우저 기본값으로 취급해 제외하며 직접 지정은 허용한다. HTML 읽기 상한은 1MiB, JSON은 64KiB다. 손상된 선택 메타는 다음 신호로 넘어가고, 알 수 없는 크기는 정상 업로드를 유지한다. 저장 경로는 업로드 저장루트 내부의 regular file만 분석한다.
|
||
|
||
```json
|
||
{"width": 1280, "height": 720}
|
||
```
|
||
|
||
메타 파일은 진입점 옆에 선택적으로 넣는다. 하위 또는 다른 빌드의 파일을 재귀 탐색해서 섞지 않는다.
|
||
|
||
## API와 저장
|
||
|
||
| 경계 | 필드 / 동작 |
|
||
| --- | --- |
|
||
| `POST /api/game-files/webgl-zip` | 기존 응답에 `displayWidth`, `displayHeight`, `displaySource` 추가. 크기 미확인은 null/null/unknown이며 HTTP 200 |
|
||
| `POST /game/new`, `POST /game/{id}/edit` | 선택 필드 `displayMode=auto\|custom`, `displayWidth`, `displayHeight` |
|
||
| 자동 저장 | 클라이언트 크기 값을 신뢰하지 않고 서버 저장 진입점을 재감지 |
|
||
| 직접 지정 저장 | 두 숫자 검증 후 source=manual. 불완전 pair/범위 밖/알 수 없는 mode는 HTTP 400 |
|
||
| 구 클라이언트 등록 | mode 누락은 auto |
|
||
| 구 클라이언트 수정 | mode 누락과 같은 경로는 기존 메타 유지, 경로 교체는 재감지 |
|
||
| 상세 / 수정 읽기 | 유효 저장값 우선, 기존 null 값은 파일에서 읽기 전용 감지. 조회 중 DB 백필 없음 |
|
||
|
||
기존 인증·CSRF·소유권 검증이 크기 필드 검증보다 먼저 적용된다. Source enum은 `build-info`, `css`, `canvas`, `manual`, `unknown`이다. DB 컬럼은 nullable `games.display_width integer`, `display_height integer`, `display_source varchar(16)`이며 pair/범위/비율/source CHECK가 있다. Source는 legacy 호환을 위해 null도 허용한다. Ratio는 별도 저장하지 않는다. `GameData`를 반환하는 모든 7개 mapper 조회와 INSERT/UPDATE가 세 필드를 전달한다.
|
||
|
||
## 표시와 fallback
|
||
|
||
상세 SSR은 검증한 `webglDisplayWidth/Height`, source/known을 전달한다. 미확인 빌드는 16:9 화면으로 표시하며 작성자가 직접 교정할 수 있다. 특정 세로 게임 크기로 기존 행을 일괄 변경하지 않는다.
|
||
|
||
`scale = min(availableWidth / referenceWidth, availableHeight / referenceHeight)`로 iframe 두 축을 맞춘다. 일반 화면 높이 budget은 `min(70dvh, 720px)`이며 vh fallback이 있다. 여백은 중앙 정렬한다. 확대/전체화면은 safe area와 툴바를 뺀 stage의 실제 크기를 사용한다. ResizeObserver·window/visualViewport resize·fullscreenchange를 RAF로 묶어 반영한다. iframe DOM과 src를 유지하여 게임을 다시 로드하지 않는다. 별도 asset origin에서도 부모는 iframe 박스만 조정하며 canvas DOM 접근을 요구하지 않는다.
|
||
|
||
전체화면 API가 없거나 거절되면 크게 보기로 전환하고 안내한다. 닫기/Esc·스크롤·포커스 복귀를 지원한다. [사용 절차](../usage/webgl-display.md), [검증 등록](../development/verification-strategies.md)을 함께 참고한다.
|