요청: 에덴고-렌더러-한선씨화
- 날짜: 2026-06-28 02:25:55
- 작업 경로: /Users/ef/crowny-edengo/play
요청 본문
os.crowny.org 크라우니월드 보고 랜더러를 한선씨로 구현한 부분이 있는지 다시 체크하면서 추진.
관련 산출
(클로드가 작업 결과를 이어 기록)
산출 (2026-06-28)
체크 결과 — os.crowny.org 크라우니월드 렌더 아키텍처 (LIVE)
- 모델/파츠 = 한선씨 정본:
라이온27.한선(캐릭터모델러.한선 파츠/구체/대칭X/후광링) →모델JSON스트림→raion27.js(window.RAION27) → village.js(JS)가 렌더. 부가 OBJ/STL 3D프린팅 출력. - 행동 로직 = 한선씨→WASM:
액터.한선→액터.wasm+액터-wasm.js글루(NPC 원형배회를 트릿 기계어 한 프레임 계산, ×1000 정수 직렬화, JS 폴백 내장).이동.wasm·지구셀.wasm동일. - 결론: 픽셀 드로잉 자체는 JS(브라우저 플랫폼락), 그러나 캐릭터 모델=한선씨 정본 + 행동로직=한선씨 WASM. SSOT+WASM 하이브리드가 이미 검증 라이브.
추진 1차 증분 — 에덴고 27라이온 로스터 한선씨 정본화
- 신규:
play/에덴라이온27.한선(한선씨 정본) →play/edengo-lions27.js(window.EDENLIONS27) 자동생성. os의라이온27.한선→raion27.js패턴 그대로. - 배선: ①index.html 스크립트 순서(lion.js 앞) ②랜딩.한선 라우트 ③edengo-lion.js가
window.EDENLIONS27우선 소비(JS 배열=폴백) ④sw.js v10. - 검증: 컴파일 OK · 27마리 [0]·[26] 원본 일치 · 로컬/공개 200 · end-to-end
ES.LIONS27===window.EDENLIONS27 true. - 효과: 손코딩 JS 배열 → 한선씨 SSOT(드리프트 차단). 렌더(fillRect)는 JS 유지(플랫폼락 정상).
잔여 (다음 증분)
- 라이온/소울 도트 파츠 지오메트리도 한선씨 정본화(2D 도트모델러) — 현재는 로스터 데이터만.
- 소울/라이온 배회 로직을 os
액터.한선/액터.wasm재사용(crowny-wasm 경로). - 81/729 다문화 소울 로스터(edengo-souls.js NAMES81)도 동일 패턴 정본화.
추진 2차 증분 — 소울/라이온 배회 로직을 한선씨 WASM 재사용 (완료)
- 재사용: os.crowny.org
액터.한선(정본, crownyc/libs) →액터.wasm(63.7KB, 결정적 원형배회·삼각도 Bhaskara·×1000 정수). 에덴고에actor.wasm+actor-wasm.js(ASCII명, 한글URL인코딩 회피)로 복사. - 신규 어댑터
play/edengo-actor.js:EdengoActor.tick(souls,lions,npcs,frame)→ ActorEngine.wander 호출(WASM, 로드전/실패 JS폴백 내장) → 각 엔티티.sx/.sy(타일오프셋) 기입. 깨어난(awake)/만난(met)/밝은(lit) 것만 살아 흔들림, 잠든 것은 정지. 3프레임마다(가벼움), 반경 0.13타일. - game.js 최소수정(+187B, 31788/32768): update() 틱 1줄 + drawSouls/drawLions/drawNPCs ox/oy에
(.sx||0). sway는 시각 전용(.sx/.sy) — 상호작용 히트박스(.tx/.ty) 불변 → 충돌/멈춤 리스크 0. - 배선: 랜딩.한선 라우트 3개(/actor.wasm=파일서빙 application/wasm · /actor-wasm.js · /edengo-actor.js), index.html 스크립트(actor-wasm→edengo-actor→game), sw v11.
- 검증: actor.wasm 로컬/공개 200·byte-identical·instantiate 7exports / end-to-end tick→sx·sy 기입(awake만, 반경준수) / 공개 도메인 라이브.
- 효과: NPC idle 모션이 한선씨 트릿 기계어로 계산(브라우저=WASM, 폴백=JS). os 크라우니월드와 동일 코어 공유.
누적 한선씨화 현황 (에덴고 렌더)
- 모델 데이터: 27라이온 로스터 = 한선씨 정본(에덴라이온27.한선). ← 1차
- 행동 로직: 배회 = 한선씨 WASM(액터.한선/actor.wasm). ← 2차
- 픽셀 드로잉: JS(플랫폼락) 유지. 남은 다음 증분: 도트 지오메트리 정본화 · NAMES81/729 소울 로스터 정본화 · 이동(플레이어/카메라) 로직 이동.wasm 검토.
추진 3차 증분 — 81 다문화 소울 로스터 한선씨 정본화 (완료)
- 신규
play/에덴소울81.한선(정본) →edengo-souls81.js(window.EDENSOULS) 자동생성. 27라이온과 동일 패턴. - 내용: KITS(9결×color/color2/regs/skin/hair) · KIT_ORDER · CULTURES · CULT_SKIN · CULT_HAIR · NAMES81(9결×9문화=81, 다국어 [표기,로마자]). 729 세계관(9×9×9) 기반 이름 매트릭스의 SSOT.
- 유니코드 보존: 한·일·중·데바나가리·암하라(ደስታ)·키릴 UTF-8 바이트 그대로. 이중따옴표 방출로 아포스트로피(Lyubov')·이스케이프 회피. STR풀 안전 위해 그룹별 덧쓰기.
- 배선: edengo-souls.js가 window.EDENSOULS 우선 소비(JS배열=폴백), index.html(souls81→souls), 랜딩.한선 라우트, sw v12.
- 검증: 컴파일·실행 OK / 원본 전수 대조 byte-perfect(NAMES81 81/81·KITS·KIT_ORDER·CULTURES 일치) / end-to-end
ES.NAMES81===window.EDENSOULS.NAMES81/ 로컬·공개 200.
누적 (3차까지)
- 1차 모델데이터(27라이온) · 2차 행동로직(배회 WASM) · 3차 로스터(81소울) = 한선씨 정본/WASM. 픽셀 드로잉만 JS 유지.
- 다음: 도트 지오메트리 정본화(2D 도트모델러) · 729 확장 로스터 · 이동.wasm 카메라.
추진 4·5·6차 — 지오메트리·729·이동 (완료)
4차(#1) 도트 지오메트리 정본화
도트모델.한선→edengo-body.js(window.EDENBODY=16파츠[x,y,w,h,역할]). edengo-sprites.js draw()가 EDENBODY 우선 소비(역할 cl/cl2/skin/hair/accent/ink/eye→색 치환), 폴백 인라인.- 무회귀 검증: 정본경로 vs 폴백경로 fillRect 호출 시퀀스 21/21 완전 일치(normal+dim 둘 다). 픽셀 동일.
- 의미: 픽셀 드로잉의 형상 규칙까지 한선씨 SSOT. os 캐릭터모델러.한선(3D)의 2D 도트판.
5차(#2) 729 세계관 3번째 축
에덴변주9.한선→edengo-729data.js(window.EDEN729={VARS9,PH,DG}). edengo-729.js가 우선 소비(NAMES729는 규칙생성 유지).- 검증: ES.VARS===정본, NAMES729=729 생성, verseFmt(5,5,5)=OO·OO·OO(절대중심), centerId(5,5,5)=0, verseAddr(1,1,1)=AAAAAA. 균형3진 축math 정합.
6차(#3) 이동 가속 — 적합도 평가 후 대체
- os 이동.wasm 부적합 판정: box/circle 연속충돌 모델 ↔ 에덴고 타일격자 WALK 충돌. 강제재사용=움직임 회귀. 직접재사용 안 함(분별).
- 대신
에덴이동.한선(정본) →edengo-move.js(window.EDENMOVE.SPEEDMUL[0..48], 협동 스트릭 가속 ×1000). game.js가 LUT 소비(JS 폴백). 타일 보행판정은 데이터라 JS 유지. - 검증: LUT [0]1000/[24]1350/[48]1700, JS공식 대비 최대오차1(자연반올림). game.js 31895B/32768.
누적 한선씨화 (6증분) — 라우트/스크립트/sw v13
모델데이터(27라이온)·로스터(81소울)·지오메트리(바디파츠)·세계관축(9변주+verse)·가속(이동LUT)=한선씨 정본 / 배회=한선씨 WASM / 픽셀 드로잉·타일충돌=JS(플랫폼락).Track B(병렬) — 에덴고 미니맵 (완료)
- 신규
play/edengo-minimap.js(window.EdengoMinimap.render(ctx,st)) — 우상단 코너 미니맵: 풀밭 베이스·깨어난 영역(빛, step3 샘플링)·굽이진 본길(pathY)·동녘 빛기둥(목표)·플레이어 점·지역 진행(점7). 스크린 좌표(vignette 이후, 카메라 밖). - 한선씨 동반
play/미니맵.한선(정본) — 맵→미니맵 좌표변환(바닥나눗셈). 검증: 미니맵X(0,200)=798·(200,200)=948·(100,200)=873, 미니맵Y(0,150)=12·(150,150)=124·(75,150)=68 전부 기대치 일치. - game.js 훅 1줄(render vignette 이후, +127B):
if(window.EdengoMinimap)EdengoMinimap.render(ctx,{PL,map,awake,RG_IDX,COLS,ROWS,pathY}). game.js 32022B/32768(헤드룸 746). - 배선: index.html(game 앞), 랜딩.한선 라우트 /edengo-minimap.js, sw v14.
- 검증: node --check OK / render() 예외없음 + 빈 st 가드 / 로컬·공개 /edengo-minimap.js·/play 200.
Track A — 한선씨 군집 결속도구 (crowny-bind, 2026-06-28)
질문: 한선씨를 셀코어 로직으로 파일별 결속강화, 거의 실시간 한파일처럼 실행 가능한가? → 가능, 그리고 이미 그러함.- 발견: hanseonc_high
가져오기는 컴파일타임 인라인 전처리기(파일내용 치환, basename 중복제거, CROWNY_STD→pkg/libs→crownyc 검색). 즉 .toau 기계어 레벨에선 이미 "한 파일처럼" 실행(파일별 런타임 오버헤드 0). 결속은 구조적으로 이미 존재. - 결속도구(
/Users/ef/crowny-bind/, 한선씨 정본결속도구.한선+ CLI결속.sh): 그 결속을 소스 레벨에서 명시화 — 가져오기 의존그래프를 DFS(의존먼저)로 펼쳐 외부의존0 자족 단일 .한선 생성, 가져오기줄 제거, 다이아몬드 dedup, 셀코어식 결속맵(셀=파일/셀연결=가져오기) 동봉. SLM/CrownyOS 이식·검증·배포용. - 검증: 라이온27.한선 군집4(다이아몬드)→단일번들 실행출력이 원본과 byte-identical(raion27.js 3738B)=한파일화=동일실행 입증. 에덴고 랜딩.한선→네트워크→{문자열,HTTP클라이언트} 4파일→47.5KB 자족번들 단독컴파일 OK.
- 한선씨 함정 실측: high
;주석=라인시작만·한줄 다중statement 불가·분리/치환 high미노출(포함인덱스+부분으로 라인스캔)·전역변수 비호이스팅(함수보다 먼저 선언). 상세=[[project_hanseon_bind_tool]].
Track B — 에덴고 미니맵 (병렬, 포크)
랜딩.한선 라우트+sw v14. play/edengo-minimap.js(우상단 미니맵: 맵축소·플레이어·본길·깨어난영역·동녘빛기둥·지역진행)+미니맵.한선 동반. game.js 32022B/32768(헤드룸746). 로컬/공개 200.효율 처방 P0/P1 구현 (울트라분석 후속, 2026-06-28)
근본원인(분석): ①정적 타일맵 매프레임 ~2,823 fillRect 재페인트 ②패널 중 루프 미정지 ③비네트 그래디언트 매프레임 할당.구현 (신규/수정)
- 신규
play/edengo-tilecache.js: 정적 타일맵 오프스크린 캐시. 카메라 타일원점(tox=floor(camX/TS)-1) 변화/dirty 시에만 재빌드, 매프레임 drawImage 1회 blit. game.js가window.__eden(ctx 스왑/drawTile/상수) 노출 → drawTile 재사용(코드중복0). - 신규
play/edengo-bench.js: draw-call/프레임시간 계측(?bench=1, 평상시 무오버헤드). EdengoBench.report(). - 신규
play/타일캐시.한선(한선씨 정본 동반): tox/blit/재빌드 규칙(바닥나눗셈). 컴파일+자체검증 통과. - 수정
edengo-game.js( 32560B/32768, 헤드룸 208B): ①loop() 패널 게이팅(questOpen/codexOpen 시 render 스킵)+bench훅 ②render() 타일캐시 blit+폴백 ③비네트 createRadialGradient 모듈상수 1회 캐시 ④loadRegion/wakeArea dirty 훅.window.__eden노출. - 배선: index.html(bench/tilecache), 랜딩.한선 라우트 2, sw v15. 재컴파일+재기동.
픽셀 동일성 (검증)
캐시 렌더 윈도 [9,32,6,24] == 직접 컬링 윈도 (동일 414타일), blit@(432,288)=(tox·TS,toy·TS) 정확. drawImage 정수좌표+imageSmoothingEnabled=false → 보간0 byte-identical. 정지 시 재빌드0(blit만), 이동/dirty 시 재빌드414. 로드순서 sprites→souls 유지(데드코드 가드 회귀0).before/after draw-call (414타일·6.82fillRect/타일·재빌드 cadence 기반)
| 시나리오 | 타일 draw-call/frame BEFORE | AFTER | 배수 |
|---|---|---|---|
| 정지(개활지) | ~2,823 fillRect | 1 drawImage | ~2,823× |
| 이동 | ~2,823 fillRect (매프레임) | ~260~400 amortized(7~11프레임당 1회 재빌드) | ~7~11× |
| 패널 열림 | ~3,024 (풀렌더) | 0 (render 스킵) | ∞ |
| 비네트 그래디언트 | 1 createRadialGradient/frame | 0 (캐시) | ∞ |
?bench=1 → EdengoBench.report().잔여
- game.js 헤드룸 208B — 다음 처방(P2 스프라이트 오프스크린 캐시·엔티티 뷰포트 컬링)은 별도파일 필수.
- 정지 시 물/엠버 애니 동결(효율 우선, 정본 분석 허용). 애니 유지하며 60× 목표는 정적/애니 레이어 분리 필요(차기).