15 KiB
구현과 검사에서 확인한 문제
입력 대상과 가려진 구
- 모바일 회전 검사에서 시작 화면으로 튀는 현상은 투영 좌표가 UI 영역에 들어가 버튼을 누른 경우였다. 구 위치와 카메라만 보고 탭하지 말고 현재 화면의 UI 안전 영역과 앞쪽 구를 먼저 확인한다. 화면 밖이면 실제 핀치·빈 공간 회전으로 시점을 바꾼 뒤 다시 투영한다.
- 마지막 구의 계수가 수십 번 실패해도 구 ID가 남아 있을 수 있다. 구름 아치 뒤의 구를 좌우 회전만 반복해 찾지 못한 실제 사례는 상하 회전 한 번으로 해결됐다. 시점 탐색에 두 회전 방향을 사용하고 변경 전후 같은 구·위치를 대조한다. 모든 구가 한 시점에 보여야 한다는 조건을 추가하면 자유로운 3D 배치와 충돌한다.
- 화면의 ‘나누기’와 ‘취소’ 버튼을 위치만으로 구분하면 분리 모드에 들어가지 않은 채 구를 누를 수 있다. 고정 AVD에서 확인한 실제 라벨과 캡처로 상태를 확인하고 일반 모드·선택 모드의 부정 대조군도 함께 확인한다. 이 픽셀 판정은 다른 해상도에 그대로 적용할 수 없다.
- 소품에 가려진 선택은 요청한 ID와 다른 구를 누를 수 있다. 이미 목표 2+3으로 완료된 실제 상태를 다시 합치려 하면 미완료 보드가 없어 실패한다. 현재 화면·전체 ID·목표 구성으로 실제 완료를 확인하고, 요청 ID와의 일치가 검증되지 않았다는 사실은 그대로 기록한다. 정확한 선택 경계 검사는 별도 구성이 필요하다.
저장 관찰과 PowerShell
- 숫자 마지막 입력 직후 파일을 읽으면 계수가 9인 이전 저장이 보이고 수십 ms 뒤 자유 놀이 상태가 보일 수 있다. 즉시 읽기 한 번으로 실패 판정하지 말고 짧은 한도 안에서 실제 저장을 반복 관찰하며 각 JSON과 UTC를 보존한다. 마지막 발화가 끝난 뒤까지 기다리면 ‘성공이 소리 완료를 기다리지 않는다’는 조건을 검증할 수 없다.
- 구 ID 하나를 PowerShell scalar 문자열로 받은 뒤
[0]을 적용하면 첫 문자만 전달된다. 네이티브 입력에 ID 배열이 필요한 경계에서는@(...)로 감싸고 투영 전에 해당 ID가 실제 보드에 정확히 하나 존재하는지 확인한다. - PowerShell AST 파싱 성공은 named argument나 실제 데이터의 의미를 보장하지 않는다.
Where-Object의 연산자와 인수를 분리해 쓰고 동일 실제 상태로 호출까지 확인한다. - 퍼즐 DTO에는 수집·계수 목록이 있지만 자유 놀이 DTO에는 없다. 빠른 계수 시험을 자유 놀이 저장에 계수 필드를 붙여 준비하면 퍼즐 준비가 되지 않는다. 실제 완료·수집 원문에서 출처를 남기고 별도의 퍼즐 상태를 준비한다. 이러한 주입은 정상 순차 진행 증거가 아니다.
음성과 APK 증거
- incremental Unity BuildReport의 packed-assets 목록이 비어 있어도 실제 APK에 음성이 들어 있을 수 있다. 이번 빌드의 직렬화 파일을 풀어 AudioClip과 실제 PCM을 확인한다.
.split0..N파일은 이어 붙여 읽고 다른 빌드의 UUID 결과를 재사용하지 않는다. - 같은 제품 소스라도 다른 디렉터리에서 만든 APK의 SHA가 달랐다. 검사에 사용한 빌드·표준 사본·설치 후 가져온 APK는 해당 실행의 실제 해시로 연결한다. 이전 빌드 파일 이름이나 소스 동일성만으로 바이트 동일성을 주장하지 않는다.
- 짧은 파형 일부의 높은 상관은 전체 숫자가 잘리지 않았다는 증거가 아니다. 전체 발화 비교와 순서·중복·꼬리 무음을 함께 보고 앞/뒤/중간 잘림·중복·잡음·다른 발화 대조군이 실제 거부되는지 확인한다. PCM 검사도 발음에 대한 사용자 청취 승인을 대신하지 않는다.
- 녹음 완료 뒤 PID로 프로세스를 다시 찾으면 재사용된 브라우저 PID를 기다릴 수 있다. 준비 시 확인한 이름·시작 시각과 원래 process handle을 유지하고 자기 녹음 프로세스의 종료만 기다린다. 무관한 브라우저를 종료해 해결하지 않는다.
- JSON에서 UTC 시각이 이미 DateTime으로 읽혔는데 다시 지역 문자열로 변환·파싱하면 Kind가 사라질 수 있다. 원래 UTC 값을 직접 사용하고 녹음·성공 관찰의 시간 순서를 원문으로 확인한다.
- ADB daemon 재시작은 이전 파이프를 물려받아 wrapper를 붙잡을 수 있다. 분리된 숨김 프로세스로 실행하고 실제 device·boot 상태를 확인한 뒤 앱 검사를 시작한다. 오프라인 전환과 녹음 후에는 speaker·remote_submix·default 세 음량 및 네트워크 상태 모두를 원래 값으로 복원한다.
Unity 자산
-
배치 Edit/Play 검사에서 URP의 Editor 생성 runtime 참조 목록이 비워지고 설정이 LF로 재작성됐다. 검사 전 Git 원문과 다른 모든 바이트가 같고 알려진 목록 변환만 존재하는지 확인한 경우에만 정리했다. 실제 설정 변경을 같은 처리로 숨기면 안 된다.
-
Blender FBX의 root 회전을 제거하면 소품이 눕는다. 승인 몸체의 실제 import root X는 약 89.98도, 자연 소품은 90도이며 장비는 0도다. 제작 원본 m·Z-up, 내보내기 -Z forward·Y-up, Unity import scale 1·bakeAxisConversion을 유지하고 wrapper 아래 원래 root를 보존한다. 얼굴 평면을 장비 중심으로 쓰면 장비가 구 앞에 뜨므로 대표 구 중심으로 되돌려 배치한다.
-
아치 전체를 BoxCollider로 감싸면 보이는 구멍도 Raycast를 막는다. 실제 아치 메시의 MeshCollider로 구멍을 보존하고 뒤쪽 자석을 선택할 수 있는지 확인한다.
-
투명 얼굴 PNG는 일부 뷰어에서 alpha 0 픽셀의 RGB가 파란 배경처럼 보인다. 원본 alpha와 실제 Unity 구 표면의 가장자리를 함께 확인한다. 현재 v2는 도구 편집 결과 자체를 채택했고 별도 래스터 변환 없이 런타임 파일과 같은 바이트를 유지한다.
-
글꼴 이름의
FirstSlice는 과거 이름이며 현재 실제 UI에서 사용하는 한국어 glyph를 포함한다. 이름만 보고 다시 만들면 승인된 화면과 자산 GUID가 달라질 수 있다. 실제 glyph와 static atlas를 검사하고 새 문구의 누락만 보완한다. -
Blender 재질 기록의
linearBaseColor를 Unity_BaseColor에 그대로 넣으면 의도한 팔레트와 달라진다. 실제 채택은baseColorSrgb/authoredSRGB를 사용하고 URP의 색 공간 변환에 맡겼다. 거칠기는 smoothness=1−roughness, 금속성은 원본 값을 사용하며 승인 메시·팔레트를 다시 제작하지 않는다. -
Light의 Soft 설정만 바꿔도 URP의 soft 지원이 꺼져 있으면 실제 그림자가 나오지 않는다. 현재 Sun은 따뜻한 색 (1, .97, .91), 강도 1.3·Soft strength .55이며 URP는 1024·1 cascade·Low soft·거리 30이다. 실제 같은 보드의 shadow-off/soft-shadow 화면 대조로 확인했다. 설정 존재만으로 렌더 결과를 통과로 쓰지 않는다.
-
넓은 새 지면과 보존된 바닥 Collider는 가림 범위가 다르다. yaw 210도·pitch −45도·거리 15의 지면 아래 시점에서 여섯 Raycast의 첫 바닥 hit가 동일해도 새 지면 뒷면은 보드를 더 많이 가린다. 실제 원본/새 지면 A/B와 카메라 값은
artifacts/verification/VisualUpgrade/FinalProduct/EditorCapture/belowground-raycast-comparison.txt및 같은 폴더의 두 PNG에 남겼다. -
Editor 자원 기록의 active MeshFilter 합계에는 Renderer가 꺼진 원래 바닥도 포함된다. 제출 GPU 삼각형 수가 아니며 Editor 전체 texture memory에는 폰트·RenderTexture도 포함된다. Camera.Render의 CPU wall time을 Android FPS나 실기기 성능으로 환산하지 않는다.
-
유한한 원경 메시의 경계와 지면 가장자리가 충분히 겹치지 않으면 실제 하늘 틈이 생긴다. 실제 가져온 sharedMesh를 별도 LocalPhysics3D Scene에서 탐색하고 같은 카메라의 원래/새 배치를 대조했다. 반경 35→28→27에서 중앙 24m 표본 누락 366→6→0을 확인했다. ±12m·횡단 2m/방사 .25m의 표본이며 전체 폭 약 ±15.35m나 모든 각도를 검사한 것은 아니다. 근접 비교 FOV14를 실제 게임 FOV62 변경으로 해석하지 않는다. 원문은
artifacts/verification/VisualUpgrade/HorizonFix/result.json과HorizonFix/final에 있다.
제작 도구의 수명
초기 자산 builder는 현재 완성된 씬·스테이지·얼굴·음성 참조를 재작성할 수 있다. ProjectBootstrap.Prepare/ConnectApp, CompositionAssets.Build, PersistenceAssets.Build, ContentAssets.Build, PresentationAssets.Build를 정상 프로젝트 열기·검사 전 준비 작업으로 실행하지 않는다. 변경 대상과 생성 diff를 먼저 확인하고 승인된 기존 자산을 보존할 수 있을 때만 사용한다.
로컬 Qwen 환경의 설치·import, GPU 연산, 모델 로딩, 실제 생성, 파일 검수, 청취 승인은 각각 다른 확인이었다. 이미 승인된 44개는 재생성할 이유가 없으며 같은 seed가 다른 환경에서 같은 WAV 바이트를 보장하지 않는다. 새 후보는 원본 이력과 입력 snapshot을 유지하고 승인 파일과 혼합하지 않는다.
새 지형·끌기와 실제 입력 관찰
- 승인 FBX는 런타임에서 정점 읽기가 꺼져 있다. Read/Write나 import root를 바꾸면 승인 메타데이터 경계를 깨뜨리므로 Editor의 읽기 전용 메시 접근으로 정점·삼각형을 추출하고 원본·meta 해시와 함께 복원 판정 자산에 저장했다. 메시 자체를 다시 제작하지 않는다.
- 얇은 지면 테두리가 화면에서 틈처럼 보일 수 있다. 실제 형상 검사에서는 약 3mm의 연결된 측벽과 인접 면의 12mm 겹침이었다. 그림이나 한 픽셀만으로 공중 틈이라 단정하지 않고 실제 메시·같은 시점 확대 화면을 대조한다.
- 터치가 다른 장치의
MakeCurrent보다 먼저 시작했을 때 첫 Began 소유자를 놓치면 앱은 끌기를 받지 못한다. 활성 접점을 소유자 기준으로 처리하고 외부 장치 입력을 먼저 거부했다. 구 중심이 아니라 첫 hit의 잡은 표면을 유지하며 매 이동을 현재 카메라에 재투영해야 보조 회전이 구의 깊이 점프로 바뀌지 않는다. - 네이티브 저장은 Unity float32가 JSON 숫자로 직렬화된 결과다. 더 높은 정밀도의 fixture quaternion이나 속성 순서를 그대로 비교하면 의미가 같은 시점도 실패한다. 실제 저장 정밀도·필드 순서로 준비하고 1 ULP 변이·ID·소속·계수 변화의 부정 대조는 계속 거부한다.
- Editor가 내보낸 native fixture의
sourceDirty는 문자열False다. PowerShell에서 비어 있지 않은 문자열을[bool]로 변환하면 true가 되므로 명시적으로 문자열을 대조하거나 boolean 파싱을 사용한다. 복원 fixture의editorEntryMilliseconds는 입력 상태가 아니라 실행마다 달라지는 측정 출력이므로 입력 동일성 검사는 그 값만 제외하고 원래 측정값은 별도로 보존한다. - 저장 파일이 준비돼도 앱 화면이 아직 시작되지 않았을 수 있다. 앱 PID와 실제 금색 버튼 화면까지 확인하고 제한 시간 내 화면이 준비되지 않으면 실패한다. 같은 저장을 읽었다는 사실만으로 입력 준비 완료를 주장하지 않는다.
- 파란 자석을 찾는 연결 픽셀 검사는 청록색 먼 언덕까지 붙일 수 있었다. 색 범위·연결 성분과 실제 PNG를 대조했고, 정수 인수를 받는
Math.Min에 소수 비율을 넣어 0이 되는 문제는1.0같은 부동 소수 한도로 고쳤다. PowerShell 좌표 배열에서 쉼표와 산술식을 섞을 때는 각 좌표를 괄호로 감싼다. - 새 시점 보조 중 500ms의 보간 swipe는 오래된 화면 좌표를 계속 사용할 수 있다. 현재 투영으로 DOWN·한 MOVE·700ms 정지·UP을 보내 실제 저장과 접촉을 검사했다. 원래 낮은 구의 직선 경로가 큰 장식에 막히면 실제 위쪽 우회와 저장 후 재투영을 사용한다. 각도 간격이 큰 회전은 좁은 깊이 접촉 창을 건너뛰므로 20px로 실제 14px 끌기 문턱을 넘은 뒤 같은 접점을 8px 최종 이동량으로 되돌리는 작은 수동 회전을 사용했다. Stage18의 약 1.9846도 실제 저장 변화는 별도 경계 재현이며 정상 30개 진행을 대신하지 않는다.
- 다른 구의 구체만 확인하는 투영 검사는 앞 소품의 첫 hit를 알 수 없다. 실제 자석 위치가 그대로이고 수동 시점만 바뀐 시도는 성공한 끌기로 세지 않는다. 현재 저장·화면으로 실제 입력 종류를 구분하고 다시 찾으며, 구가 이동한 결과에는 정확한 ID·묶음의 동일 이동·다른 구 불변·수동 시점 보존·실제 3D 접촉 검사를 유지한다.
- 정확히 같은 보드로 끝난 놓기는 합체가 아니다. 전체 저장도 변하지 않았음을 확인한 뒤 실제 상승 우회를 재시도하고 새 저장으로 투영을 갱신한다. 우회에서도 계수·다른 슬롯·완료·시범 기록, 원래 ID·묶음 모양·상대 위치·수동 시점과 실제 접촉 검사를 유지한다. 탐색 상한이나 접촉 허용 오차를 늘려 실패를 합격으로 바꾸지 않는다. 원문 실패 배치를 주입한 부분 재현과 새 저장으로 수행한 정상 30개 진행은 별도 증거다.
- 새 나무를 360도 둘레에 놓은 첫 배치는 일부 초기 자석·숫자·상단 UI를 가렸다. 초기 배치를 바꾸지 않고 뒤·옆으로 나무를 옮겼다. 30개 보드·두 가로 비율에서 구 346개·숫자 174개·상단 UI 표본 720개의 새 나무 첫 hit 가림이 330건에서 0건으로 줄었다. 원래 자석끼리의 겹침이나 아치의 탐색 역할을 모든 시점 무가림으로 확대하지 않는다.
- 최대 10개 자석의 자원 비교는 같은 AVD·카메라·수량·개별/한 묶음 상태, 8초 예열 뒤 20초 요청한 조용한 화면에서 수행했다. FPS와 PSS는 실제 화면 프레임·메모리 원문을 파싱한다. P90/P99는 histogram 구간 상한의 추정이며 입력 지연이 아니다. Editor Render 시간·전체 로드 texture memory를 Android FPS로 환산하지 않는다.
- 정적 폰트는 전체 한글 유니코드를 담는 것이 아니다. 새 안내 ‘친구를 놀이터로 다시 보냈어요.’, ‘친구가 놀이터에 들어가지 못해서 처음부터 다시 시작해요.’, ‘지금은 시작하지 못했어요. 다시 해볼게요.’를 포함해 실제 사용하는 132 glyph가 승인 atlas에 있는지 확인했다. 안내 음성을 새로 생성하지 않았다.
식생을 모든 둘레 지점에 반복하면 승인 원본을 바꾸지 않아도 메시 인스턴스 비용이 커진다. 46개 경계 지점의 수평 위치·회전·크기를 유지하면서 일부 꽃·풀을 승인 자갈로 바꾸고 내부 식생 반복 수만 줄였다. 대표 여섯 번호의 환경 FBX 삼각형 합계는 이전 개선 배치 대비22~47% 줄었다. 제출 GPU 삼각형이나 FPS가 아니다. 서로 다른 날짜·호스트 부하에서 얻은 여섯 Editor Camera.Render CPU 중앙값 중 하나는 상승했으므로 전체 성능 향상이나 인과효과로 일반화하지 않는다.