배경
산업 레벨을 실제로 굴리려면
엑셀·DB·패킷·서버 로직이 전부 한 칸씩 늘어난다.
슬롯 배치가 (산업, 캐릭터)에서 (산업, 레벨, 캐릭터)가 되고,
드롭 롤의 대상이 시트 전체가 아니라 (산업, 레벨)로 걸러진 행 목록이 된다.
해금 조건이 정해지기 전에는 시작할 수 없다 →
✅ 2026-08-01에 조건이 확정됐다 — 적성 N + 계정 레벨 M (AND).
컬럼은 RequiredAptitude + RequiredAccountLevel 정수 2개로 끝난다.
범용 조건 시스템(ConditionType enum 등)을 만들지 않는다.
✅ 2026-08-01에 레벨 개수(5개)와 판정 비용 구조도 확정됐다.
판정 1회 비용이 전역 상수에서 (산업, 레벨)의 필요 점수가 된다 —
Lv1 30,000에서 레벨당 ×3. 점수는 작업속도로 쌓인다(적성 1 = 1000점/초).
⚠️ 남은 선행 조건: 요구치 값(N·M) — 엑셀에 임시값이 들어가 있다 (T-016).
🔴 지금 서버가 잘못 동작하고 있다 (2026-08-02 확인 → 드롭은 2026-08-10 해소)
엑셀만 먼저 레벨별로 갈라져서, 레벨을 모르는 옛 코드가 새 데이터를 읽고 있다. 이건 "아직 안 됨"이 아니라 "틀리게 됨" 이다.
| 증상 | 원인 | 상태 |
|---|---|---|
DropTableCatalog.LoadAll이 38행을 통째로 등록했다 |
✅ 해소 (2026-08-10) — 키를 (ItemType, Level)로 갈라 25개 테이블로 등록 |
|
| 5개 레벨의 가중치가 한 통에 합산돼 총합이 부풀었다 | ✅ 해소 — DropSheetTest가 (산업, 레벨)별 분포를 검증한다 |
|
WorkStationSlot.JudgeCost가 상수 30_000_000 |
✅ 해소 (2026-08-10) — IndustryLevelCatalog가 RequiredScore × 1000(초→ms 환산)을 준다 |
WorkStationSlot에IndustryLevel·JudgeCostUnits필드가 생겼다 (2026-08-10 · 기본 Lv1 · 30초). 다만 DB·패킷이 없어 항상 Lv1로 적재된다 — 현재 해금이 Lv1뿐이라 기획과는 맞는다.- 레벨 선택 수단(DB·패킷·해금)이 없어 상위 레벨은 아직 돌 수 없다. T-009(회당 산출)의 레벨별 실측은 그것이 붙어야 가능하다. (Lv1 실측·T-008 분포는 가능해졌다)
할 일
엑셀 — ✅ 완료 (2026-08-01)
- [x]
IndustryLevelTable시트 신설 (GameDesign/Excel/Industry.xlsx· 25행) —IndustryLevelTID(키) ·IndustryType·Level·Name·RequiredScore·RequiredAptitude(0~10) ·RequiredAccountLevel·Description - [x]
<산업>BasicTable5종에IndustryLevel컬럼 추가 + 레벨별 행 확장 (산업당 38행 · 총 190행) - [x]
IndustryLevel의Ref검사 방식 →IndustryLevelTable.Level로 그대로 걸린다.ReferenceValidator는 참조 대상이 키가 아니어도 값 집합을 만들어 검사한다 - [x] 신규 아이템 120종 추가 (Lv2~5 × 희귀도 6 × 산업 5) —
ItemTable총 150행 (가챠 전용 6종을 더해 시트는 156행) - [x]
generate-tables.ps1실행 —.bytes·DataLog·Unity 미러까지 생성 완료
2026-08-08 엑셀 재편 (레벨 30~40 확장 대비).
Drop.xlsx→ 산업별 5개 파일(파일 안은 레벨별 시트),Industry.xlsx는 산업별 시트로 분리 — 제너레이터가 병합하므로 테이블명· 생성물·서버 코드 영향 없음.DropTID는산업×100000+레벨×100+순번으로 재채번 (산업 자리 =ItemTypeenum 값 — 농사 1 · 낚시 2 …). DropTID는 DB 미저장이라 안전하다.
DB — ✅ 완료 (2026-08-10)
- [x]
t_user_workstation_slot에industry_level컬럼 추가 (NOT NULL DEFAULT 1) - [x]
t_user_industry_level신설 — 유저 × 산업 → 최대 해금 레벨 (STRICT· PK(user_id, industry)) - [x] 기존 슬롯 행의 마이그레이션 —
DEFAULT 1이 채운다. 기존 4행 보존 확인
⚠️ 이 저장소는 스키마 파일이 없다.
Server/Shared/game.sqlite3의 DDL 텍스트가 곧 문서라,ALTER TABLE ADD COLUMN이 컬럼을 주석 앞에 끼워 넣어 주석이 어긋난 뒤 테이블을 새로 만들어 데이터를 이관했다(컬럼 순서·주석 정합). 다음에 컬럼을 더할 때도 같은 절차를 쓴다.
패킷 · 서버
- [x]
WorkStationSlotInfo에IndustryLevel추가 — ✅ 완료 (2026-08-10) · Unity 미러까지 반영 - [x] 슬롯 배치 요청에 레벨 추가 · 서버가 해금 여부를 검증한다 — ✅ 완료 (2026-08-10).
C_WorkStationAssignRequest.IndustryLevel(byte) 추가 ·EResultCode.IndustryLevelLocked = 203신설. 저장된 해금 레벨(t_user_industry_level)과 대조하고 하한(1 미만)도 막는다. ⚠️ 레벨을 올려 주는 판정 로직이 아직 없어 모두 Lv1이다 — 상위 레벨은 지금 전부 거절된다 > 구 클라이언트 호환: 레벨 필드를 안 채우면0이 오는데, 핸들러가 이를 "미지정"으로 보고 > 기본 레벨로 돌린다. 기본 레벨은 항상 열려 있어 우회가 아니다 - [x] 적성 0 캐릭터 배치를 거절하는 응답을 함께 넣는다 — ✅
EResultCode.NoAptitude(미보유는CharacterNotOwned로 구분). 테스트적성_0인_산업_배치는_NoAptitude로_거절한다 - [x]
WorkStationSlot.JudgeCost상수를(산업, 레벨)조회로 바꾼다 — ✅ 완료 (2026-08-10).IndustryLevelCatalog신설(RequiredScore × 1000— 엑셀은 초, 서버는 밀리초). 슬롯이 인스턴스JudgeCostUnits를 갖고Assign·로그인 적재가 테이블 값을 넣는다 - [x]
WorkStationSlotInfo.JudgeCostUnits를 그 값으로 채운다 — ✅ToInfo()가 인스턴스 값을 보낸다 - [x] 🔴 드롭 롤을
(산업, 레벨)인덱스 기준으로 변경 — ✅ 완료 (2026-08-10).DropTableCatalog키를(ItemType, Level)로 확장, 로드 시IndustryLevel로 갈라 25개 테이블 등록.WorkStationSlot.IndustryLevel추가(기본 Lv1 · DB 미저장),WorkStation.Settle이 슬롯의 레벨로 조회. 검증:DropSheetTest(25조합 등급·분포) - [x] 레벨 변경 시 변경 직전에 정산 — ✅ 산업 변경과 같은 경로(
AssignWorkStation)를 탄다. 테스트레벨을_바꾸기_전_구간은_이전_레벨의_비용으로_정산된다가 잠갔다 (Lv1 60초 = 2판정 / 새 Lv2 비용으로 계산하면 0판정이라 어긋나면 즉시 빨개진다) - [x] 테스트 — 해금하지 않은 레벨 배치 거절 · 레벨 변경 시 소급 없음 ✅
(전체 186건 통과.
DropSheetTest25조합 ·IndustryLevelCatalogTest· 배치 검증 7건)
해금 판정은 T-021로 분리했다 (2026-08-10).
t_user_industry_level을 올려 주는 로직(적성 N + 계정 레벨 M 비교)과 그 시점 연결, "캐릭터를 잃어도 열린 레벨 유지" 테스트가 그쪽으로 갔다. 요구치N·M이 임시값(T-016 미완)이라 지금 만들어도 밸런스 검증이 안 되기 때문이다.
완료 조건
해금하지 않은 레벨로는 배치가 거절되고, 레벨을 바꾸면 그 시점 이전 구간이
이전 레벨의 필요 점수·드롭 테이블로 정산되며, 레벨마다 판정 주기와 나오는 아이템이 실제로 다른 상태.
→ ✅ 달성 (2026-08-10). 셋 다 테스트로 잠갔다.
⚠️ 단, "실제로 다르다"는 구조까지만 확인했다. 상위 레벨을 열 수단(해금 판정)이 없어 Lv2 이상을 실제로 돌려 보지는 못했다 — 실물 확인은 T-021의 완료 조건이다.
막고 있는 것 / 선행 일감
T-016 해금 조건✅ 풀렸다레벨 개수✅ 5개로 확정엑셀 작업✅ 완료 (2026-08-01)T-016의 남은 것(요구치→ T-021로 넘어갔다. 이 일감은 요구치와 무관하게 끝난다N·M)T-005와 같은 시트를 건드린다— 시트 작업이 끝나 충돌 없음이 일감이 T-008·T-009를 막고 있다→ T-008(Lv1 분포)은 풀렸다. T-009의 레벨별 실측은 T-021로 넘어갔다
관련 커밋
- 없음 (미커밋 — 커밋 후 해시를 여기에 적는다)