bibimbap/.atp/work-session/20261014-091658/research/research.md

91 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
phase: research
agent: research-advisor
agent_version: 4
report_invocation_id: inv-001
concerns_checked: true
source_confidence: mixed
workers_spawned: 0
concerns:
- Unity 씬 소스 미포함으로 실제 UI anchor/Canvas Scaler 설정 확인 불가
- 브라우저 실행 전이므로 화면 잘림 및 입력 이상은 아직 런타임 확인하지 않음
- 분리 asset origin 사용 시 부모의 iframe DOM 직접 접근 불가
---
# WebGL 해상도 대응 조사
## 결론
원인 후보는 플랫폼의 고정 가로 플레이 영역과 빌드 HTML의 세로 영역 계산이다. “Unity가 390×844 해상도만 렌더한다”는 가정은 자료와 맞지 않는다. 이 ZIP은 이미 CSS 크기에 맞춰 Unity 렌더 타깃을 동기화하는 설정이며, 게임 내부 UI가 새 크기에 맞춰 배치되는지는 별개의 문제다.
기본 정책은 **원본 390:844 비율을 유지하면서 가능한 영역 안에 전체 화면을 표시(contain)**하는 것을 추천한다. README가 PC에서도 세로 화면 유지한다고 명시하므로 화면을 늘리거나 자르는 cover/fill 정책은 이 게임의 안전한 기본값이 아니다. 여백 없이 모든 화면을 채우려면 Unity 소스에서 다양한 비율의 UI와 카메라를 검증·수정하여 재빌드해야 한다.
## ZIP 근거 (원본 변경 없음)
ZIP: `/Users/wemadeplay/Downloads/GoraniCoin-WebGLTest.zip`; zipfile로 읽기만 수행.
- `GoraniCoin-WebGLTest/build-info.json:5`: Unity `6000.0.74f1`.
- `build-info.json:8,13–14`: `Assets/Scenes/UITestScene_Final.unity`, 기준 `390×844`.
- `README.txt:3`: PC에서도 세로 화면 유지. `README.txt:5`: Toss 결제 및 호스트 safe-area 호출 비활성화. 실제 프로젝트 소스는 ZIP에 없다.
- `index.html:9–15`: html/body 100%, overflow hidden; container 폭 `min(100vw, calc(100svh * 390 / 844))`, 높이 `100svh`; canvas CSS 폭/높이 100%.
- `index.html:27`: canvas 초기 HTML 버퍼 속성 390×844. 이 속성만으로 실행 중 렌더 타깃이 고정이라고 판단하면 안 된다.
- `index.html:46–61`: config에 `devicePixelRatio: Math.min(window.devicePixelRatio || 1, 2)` 설정. `matchWebGLToCanvasSize`는 미설정.
- `Build/GoraniCoin-WebGLTest.framework.js:7575–7580`: `matchWebGLToCanvasSize`가 undefined면 true를 반환. `:7592–7594`: preferred DPR은 match false면 1, 그 외 Module DPR/window DPR 사용.
- `index.html:69–71`: `window.unityInstance`, 준비 상태 `data-unity-ready`를 제공하여 브라우저 검사에 활용 가능.
**HTML의 비율 결함:** 컨테이너 폭이 viewport 폭 때문에 제한되더라도 높이는 viewport 전체 높이를 유지한다. 예를 들어 iframe 320×844라면 canvas CSS가 320×844가 되어 원래 390:844보다 좁다. Unity는 이 비율에서 새 렌더링을 할 가능성이 높으며, UI가 잘리는지 여부는 내부 레이아웃에 달렸다. 적절한 contain 계산은 `scale=min(availableWidth/390, availableHeight/844)`, 폭 `390*scale`, 높이 `844*scale`이다. 이미지 CSS stretch와 Unity UI 재배치를 혼동하지 않아야 한다.
## 플랫폼 근거
- `src/main/webapp/WEB-INF/views/game-detail.jsp:365–384`: frame wrap 폭 100%, `aspect-ratio:16/9`, `max-height:min(70vh,520px)`, overflow hidden; iframe absolute inset 0, 폭/높이 100%. 비율과 최대 높이가 동시에 걸려 실제 frame 비율이 16:9보다 넓어질 수도 있다.
- `game-detail.jsp:1259–1264`: 업로드 빌드 URL iframe에 그대로 연결. sandbox scripts/same-origin/pointer-lock 허용; fullscreen/autoplay 권한 허용. 전체화면 제어 UI는 없음.
- 이 빌드가 800×450 iframe에 들어가면 자체 portrait 계산에 의해 canvas 약 208×450이 되어 큰 좌우 여백과 작은 세로 화면이 생긴다. 모바일 상세 페이지의 가로 iframe은 더 낮아질 수 있다. 이는 계산상 예상이며 아직 실화면 재현은 아니다.
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameUploadController.java:198–225`: ZIP 압축 해제, index 탐색, Unity 파일 검증, 디렉터리 이동, 빌드 index URL 반환. 별도 템플릿 정규화나 responsive wrapper는 없다.
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameAssetController.java:57–68`: CSP 헤더 설정 뒤 파일 바이트 그대로 복사. CSP는 self/inline script와 self/inline style을 허용한다. CSP 변경 자체는 해상도 지원에 필요하지 않다.
- `src/main/java/com/pandoli365/bibimbap/controller/api/GameController.java:348–357`: `app.webgl.asset-origin`이 있으면 iframe을 별도 origin에 연결. 따라서 “부모 페이지 JS가 모든 게임의 canvas를 직접 고친다”는 구현은 일반화 불가. 호스트는 iframe 박스 크기는 변경 가능하나 내부 문서는 same-origin에서만 직접 접근 가능하다.
- `src/main/java/com/pandoli365/bibimbap/data/GameData.java` 및 game-register 입력에 게임 해상도/비율 메타 필드는 발견되지 않았다.
- `docs/graph/index.md` 알려진 한계와 `docs/development/verification-strategies.md:260–262`: JSP/CSS 정적 프론트 코드는 직접 탐색 대상. graph lookup skip은 타당.
- contracts index는 아직 비어 있고 해상도 계약 문서는 없음. usage index 일부 링크는 파일이 존재하지 않아 해당 문서에 의존하지 않음.
## 외부 근거 — Unity 공식 문서 확인
[Unity 6.0 Web Canvas size](https://docs.unity3d.com/6000.0/Documentation/Manual/webgl-canvas-size.html): CSS 표시 크기와 GPU 렌더 타깃을 구분하며 기본 자동 동기화를 설명한다. `matchWebGLToCanvasSize=false`는 자동 동기화를 끄고 버퍼를 수동 관리할 때 사용하는 설정이다. 이 게임의 config와 framework 근거가 기본 동기화와 일치한다.
[Unity uGUI 2.0 Canvas Scaler](https://docs.unity3d.com/Packages/com.unity.ugui@2.0/manual/script-CanvasScaler.html): Scale With Screen Size/Reference Resolution/Screen Match Mode가 UI 크기와 서로 다른 비율의 레이아웃을 결정한다. HTML에서 렌더 해상도를 바꾸는 것만으로 게임 내부 레이아웃 적응을 보장할 수 없다. 현재 게임이 uGUI인지 UI Toolkit인지도 ZIP만으로 확정하지 않는다.
[MDN postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage): 다른 origin의 iframe과 통신하려면 협력하는 child 측 프로토콜이 필요하며 sender origin/source와 message 값을 검증해야 한다. 부모에서 iframe src만 넣는 현행 구조로는 임의 ZIP의 내부 비율 자동 감지/수정 계약이 없다.
## 권장 구현 계획 (구현하지 않음)
1. 빌드 원본과 플레이어를 로컬 HTTP로 실행해 기준 390×844 화면, 창 축소, 모바일 세로·가로에서 재현한다. 준비 상태/실제 canvas client size와 width·height를 기록한다.
2. bibimbap 플레이 영역에 사용자 조절 가능한 비율(현재 가로/세로/원본 또는 사용자 지정)과 확대/전체화면 기능을 도입한다. 390:844 같은 정확 비율을 유지하면서 부모 가용 폭과 높이 양쪽에 맞게 계산한다. 앱의 iframe 전체를 390:844로 맞추면 이 ZIP의 자체 CSS를 수정하지 않고도 양쪽 계산이 일치하게 만들 수 있다. “세로”를 일반 9:16으로만 맞추면 이 게임 원본과 다르므로 원본 정확 비율 옵션이 필요하다.
3. 최소 변경안은 상세 JSP/CSS/전용 JS와 플레이어 테스트를 수정하고, 기존 게임은 현재 정책으로 fallback하면서 이번 게임은 사용자가 원본 비율을 선택할 수 있도록 한다. 화면 비율 추론을 hardcode하거나 특정 ZIP 이름을 앱에 박지 않는다.
4. 모든 게임에 자동 대응이 필요하면 작성자 해상도/비율 메타 입력 또는 협력하는 표준 빌드 메타/resize message 계약을 추가한다. 메타 저장은 GameData/Mapper/API/등록 JSP/DB migration 및 계약 테스트로 영향이 커진다. 업로드 HTML 임의 주입/정규식 개조는 범용 보장과 원본 보존 측면에서 우선안으로 추천하지 않는다.
5. 이 게임 HTML 자체도 개선하려면 원본 ZIP을 보존하고 복사본 index 컨테이너만 양축 contain 방식으로 보정한다. 재빌드 없이 가능한 웹 wrapper 수정이지만, 내부 UI 재설계와는 다르다. matchWebGLToCanvasSize=false나 고정 버퍼는 픽셀 기준 UI 문제가 실제 확인됐을 때 개발자와 함께 검토한다.
## 영향 파일 후보
최소 플랫폼안: `src/main/webapp/WEB-INF/views/game-detail.jsp`, 신규 전용 WebGL player JS/CSS, 동작 회귀 테스트, `docs/changes/...`, 해상도 사용 계약 문서. 공용 `.player` CSS(`bibimbap.css:343`)는 현재 상세 페이지 실제 iframe class와 다르므로 그 줄만 바꾸어도 해결되지 않는다.
자동 메타 영속화안: 위 + `GameData.java`, `GamesMapper.java`, `GameController.java`, 등록 폼, upload metadata parser(채택 시), DB migration, 컨트롤러/매퍼 테스트. 이는 이번 조사에서 확정한 구현 요구사항이 아니라 별도 범위 선택이다.
## 검증 기준
- 원본 390:844와 좁은 320×844, desktop 1440×900, 가로 844×390, 작은 높이 창에서 플레이 영역 양축이 가용 공간을 넘지 않음.
- contain 모드 canvas/iframe 비율 390:844, 화면 잘림 없이 중앙 정렬. 여백은 의도대로 남음. ResizeObserver/viewport resize 후 갱신되고 Unity instance가 재생성되지 않아 플레이 상태가 유지됨.
- Unity 준비 후 CSS 크기와 drawing buffer 크기를 각각 기록; DPR 1/2에서 실제 동기화를 확인. initial width/height attribute만 검사하지 않음.
- 게임 로딩/상하단 UI/버튼 클릭/터치/포인터 위치/다시 축소/전체화면 진입과 해제를 실제 빌드로 확인. 화면만 보기 좋은데 입력이 틀어지는 회귀를 방지.
- 기존 가로 게임과 별도 asset-origin 구성에서 iframe 재생이 유지됨. cross-origin 접근 실패를 정상 지원 여부와 구분.
- `docs/development/verification-strategies.md`에 따라 수정 전 실패→수정 후 통과하는 회귀 포함, JSP 변경은 WAR 빌드 외 HTTP 200 런타임 스모크가 의무.
## 미해결
- 사용자가 원하는 대응 범위: 원본 콘텐츠를 전체 표시하며 확대하는 플레이어인가, 게임 UI가 가로·세로 전체 화면에서 재배치되는 것인가? 후자는 Unity 소스 또는 담당 개발자의 재빌드가 필요할 수 있다.
- 각 게임 비율의 자동 감지/저장까지 이번 범위인지 여부.
- 실제 Unity UI 컴포넌트와 픽셀 단위 레이아웃, 카메라 viewport, safe-area 대응 설정.
- 현행 플레이어와 ZIP의 런타임 실화면은 아직 미실행.
## 실행 계약
Parent instruction에 따라 nested children 0건. update_plan은 callable tools에 없어 bind 호출을 만들지 않았으며 parent에 명시 고지했다. 제품 코드/원본 ZIP/credential 미변경. 파일 산출은 이 research.md 1건만이다.