[2026-07-25] 오픈월드 배경 에디터 신설
게임 개발에서 "게임 엔진" 다음으로 중요한게,
게임 에디터 입니다. 쉽게 표현하면,
스타크래프트 커스텀 맵(사용자맵) 만드는 프로그램과 같은 기능이다.
생각하시면 됩니다.
사실.. 에디터 개발은
또 하나의 게임을 개발한것과
거의 흡사할만큼의 개발력 노력이 들어가는 일 입니다.
지금 만든건 "배경,오브젝트,지도.테마지형" 등을 에딧하는 기능이라.
이게 완성되면, 각종 테마 배경을 쉽고 빠르게 만들수 있습니다.
예를 들면 : 할로윈!, 크리스마스, 여름휴가, 우주, 해저, 환타지,중세,무협,고전, 등등... 다양한 테마를 빠르게 만들 수 있는것이지요.
F. [2026-07-25] 오픈월드 배경 에디터 신설 — 관리자 인게임 오버레이 (
152cb0b
)
기존 A~E 구간은 전부 "이미 존재하는 씬을 고치는" 작업이었다면, 이 세션은 tech-lab 안에 완전히 새로운 관리자 전용 도구(배경 에디터)를 처음부터 만든 것 — 별도 페이지가 아니라 라이브 씬 위에 얹는 오버레이로, 나무/조명 편집에서 시작해 몬스터 종합 관리까지 확장됐다. 새 파일
client_editor.js
(클라이언트, DOM 전용/THREE 미의존 유지)와
openworld_routes.js
(서버 REST API) 신설,
scene_nature.js
/
scene_monster.js
에 대규모 편집 API 추가.F-1. 데이터 모델 — DB가 유일한 소스
새 테이블
openworld_bg_configs
(테마 이름/JSONB config/활성화 플래그)와
openworld_editor_groups
(그룹 저장). 마이그레이션 044/045.나무:
nature.overrides
(절차적 생성물 중 편집된 것만, id로 식별) +
nature.added
(관리자가 새로 배치한 것, 전체 스펙 저장) 2단 구조 — 저장 용량을 최소화하면서도 절차적 생성 로직이 나중에 바뀌어도 "편집 안 한 나머지"는 항상 최신 절차적 결과를 따름.몬스터도 동일 패턴을 그대로 재사용:
monsters.overrides
(seed로 식별)/
monsters.added
.몬스터는 나무와 달리 서버 authoritative 데이터(전투/HP가 서버에서 돎)라, 클라이언트 눈속임이 아니라 서버(
monster_spawn.js
)가 실제로 이 config를 절차적 기본값에 병합해서
monster_spawn_list
로 내려준다. 저장/활성화 시 서버 메모리 캐시(
invalidateMonsterOverrideCache
)를 같이 비워서 다음 접속자부터 즉시 반영되게 함.관리자가 새로 배치한 몬스터는
ADDED_MONSTER_SEED_OFFSET=1000
부터 합성 seed를 받는데, 기존
MAX_MONSTER_INDEX=300
(에픽/보스 확장 때 200→300으로 이미 한 번 늘렸던 값)에 걸리면 그 몬스터들의 모든 전투 패킷이 조용히 버려지는 사고가 재발할 뻔했음 — 2000으로 선제적으로 확장(에픽/보스 때와 같은 클래스의 버그를 배포 전에 미리 잡음).F-2. 나무/자연 오브젝트 편집
InstancedMesh는 배치 직후 개별 식별이 안 되던 구조라, 배치 시점에 순번 id(
n0, n1...
)를 부여하고 살아있는 레지스트리(
_natureRegistry
)를 신설 — 이 세션의 가장 리스크 컸던 기반 작업.재색칠은 InstancedMesh 인스턴스 하나를 숨기고(스케일 0) 개별 Object3D로 "승격"시켜 독립 재질을 입히는 방식(인스턴스별 vertexColors는 검은 화면 회귀를 냈다가 되돌림).
위치(X/Z, 드래그 이동)/회전/스케일/Y높이 보정/기울기(X·Z, Shift+드래그로도 조작) 전부 지원.
선택 시 보라색 링 표시 — 처음엔 고정 반지름이라 큰 오브젝트에 파묻히던 버그를, 오브젝트의 실제 바닥 반경(바운딩박스 기반) 비례로 고침.
화초/풀 드래그 이동 실패 버그: 얇고 작은 지오메트리는 재클릭(드래그 진입) 시 정밀 레이캐스트가 삼각형을 못 맞히는 경우가 잦아, 빗나간 클릭이 "빈 땅 클릭"으로 취급돼 선택이 풀려버렸음(드래그 자체가 안 되는 게 아니라 재선택 실패) — 정밀 레이캐스트가 실패했을 때 화면 좌표 20px 반경 안에서 가장 가까운 오브젝트를 대신 골라주는 폴백 추가.
F-3. 색상(부위별 틴트)
재질 clone +
onBeforeCompile
로 프래그먼트 셰이더에 HSV 색조(Hue)만 치환 — 텍스처의 원래 명암/디테일은 그대로 유지(곱연산·emissive 가산 둘 다 시도했다가 기각했던 이전 세션의 결론을 그대로 재사용). 채도/명도는 안 바뀌므로 네이티브 색상피커의 사각형을 드래그해도 변화가 작을 수 있음 — 오해 방지용 안내 문구 추가.버그: "원래대로" 눌러도 색이 안 돌아옴 —
clone()
이 항상 "지금 재질"에서 파생돼서 진짜 원본으로 되돌아갈 방법이 아예 없었음(hex=null을 그냥 무시했었음). 최초 틴트 적용 시점의 재질을 메시에 별도로 기억해뒀다가 완전히 복원하는
_clearTint
로 수정.부위별 색상: "나무는 줄기/잎, 몬스터는 몸통/눈 따로 칠하고 싶다" 요청으로 GLB 재질 이름을 직접 확인(
tree_c.glb
는 Bark/Leaves 2개, 오크는 11개, 고양이는 5개 — 반면 꽃/풀은 전부 재질 1개뿐이라 애초에 부위 분리가 불가능한 에셋임을 확인) → 선택된 오브젝트가 실제로 가진 재질 이름을 그대로 읽어와 그 개수만큼 색상 피커를 자동 생성(하드코딩된 카테고리 매핑 없음).F-4. 그룹 기능
Shift+클릭 다중 선택 → 이름 붙여 서버 DB에 저장/불러오기(
openworld_editor_groups
).그룹 일괄 조정 4종(색조 회전/크기/회전/기울기 X·Z) — 슬라이더를 잡는 순간 멤버 각자의 기준값을 스냅샷해서, 그 기준값에 상대적으로(크기는 배율, 나머지는 델타) 적용 — 멤버마다 원래 갖고 있던 개별 차이가 유지된 채 다 같이 움직임.
그룹 회전 버그: 처음엔 각 멤버가 제자리에서 스스로 도는 구현이었으나, "그룹 전체가 통째로 회전해야 한다"는 지적으로 그룹 중심(centroid) 기준 위치 궤도 회전 + 각자 방향 회전을 함께 적용하도록 수정(사진을 돌리듯).
"그룹 복제 배치" 신설 — 클릭 지점을 그룹 중심으로 삼아 멤버 전원을 상대 오프셋 그대로 유지한 채 통째로 복제(원본은 남음). 복제본은 자동으로 새 이름(
_사본
, 겹치면
_사본2
...)을 받아 서버에 즉시 저장 — "그룹 복제는 계속 그룹으로 지정돼야 한다"는 요청으로, 화면을 벗어나도 나중에 다시 그룹으로 불러올 수 있게 함.그룹 이동(드래그): 2개 이상 선택 상태에서 멤버 하나를 다시 눌러 끌면 선택된 전원이 상대 위치를 유지한 채 같이 이동(회전과 동일한 "그룹은 하나의 덩어리" 원칙).
F-5. 몬스터 에디터
나무와 대칭적인 CRUD: 생성(팔레트에서 배치)/삭제/이동/활동반경/부위별 색상.
활동반경은 원래 티어(소형/중형/대형/에픽/보스) 5종 공용값이었는데, "개별 몬스터마다 다르게" 요청으로 인스턴스별 override 필드 추가(서버 페이로드에도
wanderRadius
실어보냄).선택 시 보라색 링을 활동반경 그 자체 크기로 그려서, 선택 표시와 반경 시각화를 겸용.
재색칠은 나무의 검증된
_applyTint
/
_clearTint
를 그대로 재사용(스켈레톤 애니메이션과 무관하게 프래그먼트 셰이더 단에서만 동작해 안전).F-6. 팔레트/썸네일/패널 UX
나무·몬스터 둘 다 팔레트가 파일명 텍스트뿐이라 뭔지 안 보인다는 지적 → 메인 게임 렌더러와 별개인 작은 오프스크린 렌더러로 실제 모델을 미리 그려 썸네일 캐싱.
버그: 몬스터 썸네일이 안 보임 — 스킨드 메시를 일반
버그: 몬스터 썸네일이 안 보임 — 스킨드 메시를 일반
clone(true)
로 복제해서 스켈레톤 바인딩이 깨졌던 것(예전 "고스트 몬스터" 버그와 동일 클래스) —
_spawnMonster
가 쓰는 스켈레톤 전용 클론으로 교체."최근 사용" 셸프(로컬 저장, 배치할 때마다 자동 갱신), 서버 폴더 실시간 스캔 기반 에셋 찾아보기(하드코딩 카탈로그 아님).
패널이 탭 내용과 무관하게 항상 풀스크린이던 문제 —
bottom:0
고정을 없애 내용 크기만큼만 차지하게, 아이콘 탭 레일도 텍스트 라벨을 없애 압축, 접기 토글 추가.모든 슬라이더에 숫자 직접입력(+/-) 병기, 저장/되돌리기(직전 선택 시점으로 한 단계)/원래대로(세션 시작 시점) 3종 세트를 인스펙터에 상시 노출.
방어 코드: 에디터 초기화가
#sceneOverlay
미준비 등으로 실패해도 예외가
initSceneOverlay()
나머지(존/몬스터 스폰 등)까지 끊어먹지 않도록 null 가드 추가.📌 참고
• 이 문서는 소스코드 주석을 있는 그대로 옮긴 것이라, 실제로는 되돌려지거나 다시 조정된 값(예: 경직시간 0.5→1→1.5초처럼 여러 번 바뀐 것)도 전부 등장 순서대로 남아있습니다 — A~D 구간의 최종값은 D-5/A-8/B-4의 "오늘 세션" 항목, E~F 구간(리팩토링 이후)의 최종값은 각 소절의 마지막 커밋 기준입니다.
•
ws_client.js
의 나머지 132건(오픈월드 외 범용 채팅/SFU/게임엔진 이력)은 요청 시 별도로 정리해드릴 수 있습니다.•현재 최신 커밋:
152cb0b
(2026-07-25). 이 시점 이후 작업은 이 문서에 아직 반영 안 됨 — 다시 요청 시 추가.
댓글목록
등록된 댓글이 없습니다.