본문으로 건너뛰기

구조 ​

패키지 ​

패키지하는 일기대는 것
@isora/core씬 모델·검증, 투영·깊이 정렬, 배치·쌓기, 앉기, 길 찾기, 행동 계획, 움직임, 그릴 파츠 계산없음 (순수 TS, DOM 없음)
@isora/react<IsoScene>, 그리기 레이어, 재생 훅(시계·행동·타임라인·씬 변화)core, React 18·19
@isora/assets공식 에셋 팩 10종 (공용·오피스·공장·도시·의료·군·학교·리테일·공항·사람, CC0)core
@isora/pack팩 매니페스트·검증·빌드, SVG 정제, 정적 SVG 내보내기core
@isora/cliisora init·studio(로컬 서버)·pack·exportcore, pack
apps/studioGUI 편집기 (MUI)react, assets
example/*프레임워크를 앱처럼 쓰는 예제 (claude-office·nullus-login·showcase: 코드로 지은 대형 씬 열)react, assets

core 모듈과 흐름 ​

 types · asset(defineAsset) · scene(검증·parse)
          │
 projection(iso·회전·projectPoint) ── geometry(볼록 껍질·SAT) ── shape(파츠 상자)
          │                                                        │
 placement(쌓기·바닥 높이·floorPointAt) ── seating(자리·SITTING·앉는 길 검사·describeRig)
          │                                                        │
 navigation(격자·A*·시간 예약)                                      │
          │                                                        │
 activities(활동·기본 루틴) ── behavior(계획·명령·frameAt) ── motion(걸음·자세 섞기·transitionClear)
                                          │                        │
                                    depth(앞뒤 그래프) ── render(prepareRender·composeRender·buildRenderList)
 timeline(경로·키프레임) ──────────────────────────────────────────┘
 builder(코드로 씬 쌓기) · lint(배치 검사) · motionLint(움직임 물리 검사) ─ 위 층을 읽기만 하는 도구
  • 데이터 → 계획 → 모습 → 그림 순서로만 기댄다. 아래 층은 위 층을 모른다.
  • 계획(behavior)은 시각의 함수다. 사람 id·seed 로 난수를 정하고, 결정 시각 순서로만 계획을 늘려 간다.
  • 모습(motion)은 계획이 준 한 시각의 값(자리·자세·전환 진행도·걸은 거리)을 파츠 상자로 바꾼다. 상태가 없다.
  • 그림(render)은 상자를 화면 면으로 바꾸고 앞뒤를 정한다. 정지한 것과 움직이는 것을 나눠 매 프레임 비용을 줄인다.

react ​

층무엇
시계 createTimelineClock틱(80ms) 알림 + 프레임 시각 timeAt. 행동·타임라인이 같이 쓸 수 있다
재생 훅useBehaviorPlayback(루틴·명령) · useTimelinePlayback(화물·키프레임) · useObjectMotion(씬 데이터 변화)
매 프레임 sourceLiveSource { ids, sample(wall), until? } — 훅들이 내놓고, 앱이 직접 만들 수도 있다
레이어LiveSceneLayer(prepared + sources → 매 프레임) · SceneLayer(파츠 → SVG) · GroundGrid · HullOutline · ActivityBubbles
뷰어<IsoScene> — 위를 조립한 것. behavior·clock·renderOverlay·onSceneClick 으로 앱이 끼어든다

틱과 프레임 ​

틱 (80ms)프레임 (rAF)
무엇이 바뀌나활동·단계(people), 기기·문 상태, 하루 시각, 타임라인 화물걷고 앉는 사람의 파츠
어디서clock.subscribe → 훅 → React 리렌더LiveSceneLayer 의 저장소 → 그 레이어만 리렌더
왜 나눴나전체 리렌더·정지 그림 다시 만들기는 비싸다걷는 모습은 틱으로 끊으면 떨린다

확장 지점 ​

하고 싶은 것쓰는 것
사람을 앱 이벤트로 움직이기useBehaviorPlayback().command / BehaviorWorld.command
계속 바뀌는 데이터를 사람 움직임으로useActorCommands
씬을 코드로 짓기createSceneBuilder
루틴·시간표 정의씬 routines, clock
새 활동 (예: charge)가구 seats[].activity·spots[].activity 에 이름을 적고 루틴에서 그 이름을 쓴다
사람이 아닌 것을 매 프레임 움직이기 (지게차·AGV 실시간 위치)LiveSource 를 만들어 LiveSceneLayer 에 넣는다
머리 위 표시·핀·경로선<IsoScene renderOverlay> 또는 LiveSceneLayer children
클릭으로 위치 고르기<IsoScene onSceneClick>, floorPointAt
새 사람 에셋사람 에셋 만들기, describeRig
다른 렌더러 (Canvas·WebGL·서버 이미지)prepareRender·composeRender 의 면, actorPartBoxes·objectPartBoxes 의 상자
설비 상태 바인딩<IsoScene states> — 에셋 states 이름
이름·메시지를 다른 언어로영어 글 옆의 names·labels, assetName·stateLabel·localize, 검사의 { locale } (언어)

점검: 프레임워크로 쓸 만한가 ​

영역상태비고
씬·에셋 데이터 모델✅스키마 검증(parseScene·validateScene·defineAsset), 팩 id 규칙, 결정적 JSON
좌표·투영·클릭 좌표✅projectPoint·unprojectPoint·floorPointAt, onSceneClick
배치·쌓기·충돌✅placeAt·surfaceHeightAt·findCollisions
사람 자동 행동✅루틴·시간표·비켜 가기·출입, 결정적
사람 명령✅go·do·idle·leave·routine, 대신 할 명령(orElse), 서서 하는 일, 둘러서기, 끊기·자리 내놓기·결과 보고, 기록 재적용
데이터 → 움직임✅useActorCommands 로 사람마다 할 일을 선언 (example/claude-office)
코드로 씬 쌓기✅createSceneBuilder (add·sit·floor)
위치·활동 읽기✅people·overrides·frameAt(t), 매 프레임 renderOverlay
재생 제어✅공유 시계 clock, seek·setSpeed, 동작 줄이기
움직임 품질✅매 프레임 월드 공간, 앉는 길 충돌 검사
사람 에셋 확장✅파츠 이름 약속 + describeRig
렌더러 교체✅core 가 DOM 없이 면·상자를 준다
언어✅기본 영어, 한국어 내장. 번역은 영어 글 옆에 둔다
명령 완료 이벤트△콜백 대신 people 을 틱마다 비교한다 (사람 움직이기)
사람이 아닌 이동체의 길 찾기 명령△지게차·AGV 는 LiveSource 로 앱이 위치를 댄다. 길 찾기·비켜 가기는 사람만 한다
층·계단✗한 층만. 층 이동은 아직 없다
연속 회전✗방향은 90° 단위로 바로 돈다
리그 이름 바꾸기✗파츠 이름 규칙(leg-l 등)이 고정이다. 다른 이름을 쓰려면 이름을 맞춘다
긴 건너뛰기△1시간 앞으로 seek 하면 계획에 수백 ms 걸린다

테스트가 지키는 것 ​

  • packages/core/src/behavior.test.ts — 계획·비켜 가기·시간표·명령(끊기·자리 내놓기·출입·실패), 결정성, 명령과 루틴이 섞여도 겹치지 않음
  • packages/assets/src/motion.test.ts — 네 방향 책상 의자·소파에서 모든 사람의 앉는 길이 가구를 뚫지 않음, 전환 연속성, 걸음, 깊이 순서, 리그 약속, 문서 예제 에셋
  • apps/studio/src/editor/samples.test.ts — 샘플 씬의 모든 책상·소파·벤치 자리가 앉는 길 검사를 통과함
  • packages/react/src/IsoScene.test.tsx — 앱이 쥔 행동 재생·오버레이
  • example/claude-office/src/office.test.ts — 세션 → 책상 배정, 모습별 명령(코드·커피·Zz)이 자리가 모자라도 겹치지 않고 해내짐

MIT 라이선스로 배포합니다.