18:21 07/25 토요일
날씨 정보 불러오는 중...

버그&개선요청

Total 13
Today 1
오픈월드 (기술테스트연구실) 개발 히스토리 2 [2026-07-25] 오픈월드 배경 에디터 신설



[2026-07-25] 오픈월드 배경 에디터 신설

 

게임 개발에서 "게임 엔진" 다음으로 중요한게,

게임 에디터 입니다. 쉽게 표현하면,

스타크래프트 커스텀 맵(사용자맵) 만드는 프로그램과 같은 기능이다.

생각하시면 됩니다.


사실.. 에디터 개발은

또 하나의 게임을 개발한것과

거의 흡사할만큼의 개발력 노력이 들어가는 일 입니다.

 

지금 만든건 "배경,오브젝트,지도.테마지형" 등을 에딧하는 기능이라.

이게 완성되면, 각종 테마 배경을 쉽고 빠르게 만들수 있습니다.

 

예를 들면 : 할로윈!, 크리스마스, 여름휴가, 우주, 해저, 환타지,중세,무협,고전, 등등... 다양한 테마를 빠르게 만들 수 있는것이지요.



20260725163222_0668182f5282bc46f30666e8921d7220_8ngo.png

20260725163507_0668182f5282bc46f30666e8921d7220_do20.png

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). 이 시점 이후 작업은 이 문서에 아직 반영 안 됨 — 다시 요청 시 추가.

댓글목록

등록된 댓글이 없습니다.

Total 13 1 페이지
번호
제목
글쓴이
날짜
조회