GameDesign/design/character/README.md 최종 업데이트 2026-08-02

08. 캐릭터 (Character)

상위 문서: 게임기획코어.md · 전제: 작업슬롯 최종 업데이트: 2026-08-02 · 상태: 적성·장비·시작 캐릭터 확정 · 성장/획득 미정 바뀌면 갱신: 거래 · 게임기획코어 · 산업레벨 · 아이템 · 자원채취 · 작업슬롯 진행 및 성장 · 특성

슬롯에 배치되어 실제로 일하는 주체다. 섬 컨셉에서는 섬에서 일하는 일꾼이며, 플레이어 자신(섬주인)은 캐릭터가 아니다 → 3장.

캐릭터가 정해지지 않으면 작업슬롯의 속도를 계산할 수 없다. 이 문서는 구현이 이미 끝난 부분을 확정으로 옮겨 적고, 남은 미정을 명시한다.


1. 확정 사항

# 항목 확정 내용
1 캐릭터 스탯 = 산업 적성 별도 스탯을 두지 않는다. 5개 산업 각각에 대한 적성(0~10)이 전부다
2 적성 = 기본 작업속도 적성을 WorkSpeedTable로 변환한 값이 속도 계산의 출발점이다
3 적성 0 = 배치 불가 그 산업을 다루지 못한다. 배치 요청을 서버가 거절한다 → 2.2
4 적성은 TID별 고정값 개체가 스탯을 들고 있지 않다. CharacterTable에서 읽는다
5 슬롯당 1명 여러 명을 한 슬롯에 넣지 않는다
6 장비 부위 = 무기1 · 장신구2 · 보석1 4칸. 효과는 속도식의 가산 항으로 붙는다 (일감 T-002)
7 계정(섬주인)과 분리 섬주인은 캐릭터가 아니다. 배치되지 않는다 → 3장
8 종족을 여러 개 둔다 사람·몬스터 등. 외형과 적성 분포의 차이로만 표현한다 → 4장

적성이 있어서 배치가 퍼즐이 된다. 슬롯 3개에 캐릭터 5명이면 "누구를 어디에"가 실제 선택이 된다. 적성이 없으면 스탯 높은 순으로 채우면 끝이라 배치에 의사결정이 없다.

1.1 개체와 정의를 구분한다

같은 캐릭터(TID)를 여러 장 가질 수 있다.

무엇 어디
CharacterTID 캐릭터 종류 — 이름·적성·종족 엑셀 Character.xlsx
character_id 캐릭터 개체 — DB 발급 PK t_character
개체가 갖는 것 성장의 입력(레벨·경험치)뿐 t_character

적성을 DB에 저장하지 않는다. 저장하면 엑셀에서 밸런스를 조정해도 DB가 낡은 값을 붙든다.

구현: Server/WSGameServer/User/Character/Character.cs


2. 적성 → 작업속도

2.1 변환은 테이블이 한다

적성(0~10)을 WorkSpeedTable.BaseWorkSpeedPermille(천분율)로 변환한다. 변환식을 코드에 두지 않는다 — 이 값이 재화 생성량에 직접 곱해지므로, 엑셀 수정만으로 밸런스가 조정돼야 한다.

적성 기본 작업속도 실효 주기 (보정 없을 때)
0 0 배치 불가
1 1000 (1.0배) 30.0초 — 기준
5 2100 (2.1배) 14.3초
10 4000 (4.0배) 7.5초 — 상한

여기에 특성·장비·부스트가 가산으로 붙는다: 속도 = 적성기본값 × (1 + Σ가산) × Π승산작업슬롯 3.4

2.3 적성은 산업 레벨 해금 조건도 겸한다 (2026-08-01)

보유 캐릭터 중 그 산업 적성의 최댓값이 산업 레벨 해금 조건 ①이다 (② 계정 레벨과 함께 충족해야 한다) → 산업 레벨 3장.

  • 배치하지 않아도 된다. 갖고 있기만 하면 조건을 만족한다.
  • 그래서 적성은 "이 슬롯이 얼마나 빠른가"에 더해 "어떤 콘텐츠가 열리는가" 를 함께 정한다.

⚠️ 이 결정으로 캐릭터 획득 경로(5장 미정)가 콘텐츠 해금의 병목이 됐다. 적성 N짜리 캐릭터를 얻는 길이 가챠뿐이고 천장이 없으면, 운이 나쁜 유저는 산업 레벨이 영영 열리지 않는다. 획득 경로를 정할 때 보조 경로(상점 구매·퀘스트 확정 지급)를 함께 본다.

2.2 적성 0 = 배치 불가 (2026-08-01 재확정)

적성 0인 산업에는 캐릭터를 배치할 수 없다. 서버가 배치 요청 자체를 거절한다.

⚠️ 2026-07-30에 문서상 "배치는 되고 매우 느리다"로 바꿨다가 2026-08-01에 원복했다. 그 변경은 문서에만 적혔고 구현된 적이 없다 — 코드(Character.CanWork)와 엑셀(WorkSpeedTable TID 0 = 0)은 처음부터 "배치 불가"였다. 이번 결정으로 문서가 코드·데이터와 다시 일치한다. 엑셀 수정은 필요 없다.

왜 되돌렸는가 — "할 수는 있는데 손해다"는 선택지를 늘리는 것처럼 보이지만, 실제로는 적성이라는 축을 무의미하게 만든다. 아무 캐릭터나 아무 데나 놓을 수 있으면 배치 퍼즐이 "속도 순 정렬"로 수렴한다. 못 하는 것이 있어야 누구를 어디에 둘지가 문제가 된다.

  • 속도 0은 TimeUntilNextJudge에서 0으로 나누게 된다. "정지"는 배치를 비우는 것으로 표현한다.
  • 슬롯이 남는데 적성 맞는 캐릭터가 없는 상황은 캐릭터 획득(4장)이 푸는 문제이지, 적성 규칙을 느슨하게 해서 풀 문제가 아니다.

3. 계정(섬주인)과의 분리 (2026-08-01 확정)

플레이어 자신은 캐릭터가 아니다. 섬주인은 일하지 않는다 — 일은 캐릭터가 한다.

캐릭터 계정(섬주인)
슬롯 배치 된다 안 된다
성장 축 캐릭터 레벨 계정 레벨
효과 그 슬롯의 작업속도 전역 특성 — 모든 슬롯에 기여 → 특성
획득 4장 (미정) 계정 그 자체

3.1 계정 경험치는 작업으로만 오른다 (확정)

캐릭터가 작업 → 캐릭터 경험치 ↑ ─(일정 비율)→ 계정(섬주인) 경험치 ↑ → 전역 특성

자원을 먹여서는 계정 레벨이 오르지 않는다. 먹이기로도 오르면 골드로 계정 레벨을 사는 길이 열린다. 계정 레벨은 "캐릭터를 굴린 시간"에만 묶어 둔다.

항목 상태
계정 레벨의 존재 · 전역 특성 담당 ✅ 확정
계정 경험치 = 작업 경험치의 일부만 ✅ 확정
전달 비율 · 계정 레벨 곡선 ❌ 미정

3.2 ⚠️ 자기가속 루프를 조심한다

계정 레벨 ↑ → 슬롯 상한 ↑ → 캐릭터 경험치 총량 ↑ → 계정 레벨 ↑ → …

게임기획코어 4장의 경고("총량 = 접속 시간 × 슬롯 수 × 속도 배수")에 레벨이 슬롯을 늘리는 되먹임이 붙는다. 계정 레벨 곡선과 슬롯 해금 곡선은 반드시 함께 잡는다 → 일감 T-012.

슬롯 확장을 레벨(상한) × 골드(구매)의 이중 게이트로 둔 것이 이 루프의 1차 제동 장치다. → 거래 3.3

3.3 CharacterTID 1 폐기 · 영구 결번 ✅ 실행 완료 (2026-08-02)

TID 1 '유저 캐릭터'(전 산업 적성 1, 기본 지급)는 섬주인 개념이 들어오면서 자리를 잃는다. 섬주인은 배치되지 않으므로 캐릭터 테이블에 있을 이유가 없다.

  • TID 1은 폐기하고 영구 결번으로 둔다. 다른 캐릭터에 1번을 다시 붙이지 않는다 (게임기획코어 4장 식별자 규칙).
  • 2026-08-02 실행. 일반 캐릭터 1001~1006 입력과 함께 CharacterTable에서 행을 삭제했다. 현재 테이블은 1001~1006 6행이다.
  • 시작 캐릭터 = 1001 램볼 ✅ 확정(2026-08-02). User.DefaultCharacterTid가 이 값을 쓴다.
    • 전 산업 적성 1로 둔다. 적성 0인 산업은 배치가 막히므로, 시작 캐릭터에 0이 섞이면 신규 유저가 그 산업을 아예 시작하지 못한다.

기존 계정은 다음 로그인에 스스로 복구된다. DB에 남은 TID 1 개체는 LoadCharacters가 경고를 남기고 건너뛰므로 보유 캐릭터가 0이 되고, OnLoginDataLoaded가 그때 1001을 지급한다 — 신규 유저 전용 경로가 아니라 "캐릭터가 0명이면 지급" 이라 이관이 자동으로 끝난다.

⚠️ 다만 고아가 된 t_character 행 자체는 남는다. 지우지 않으면 그 계정은 로그인할 때마다 경고 한 줄을 남긴다(동작에는 지장 없다).


4. 종족

항목 내용
표현 범위 외형 + 산업 적성 분포의 차이로만. 예: 몬스터 계열은 사냥 적성이 높고 농사가 낮다
금지 종족 상성 · 종족 전용 스킬을 두지 않는다

종족을 별도 시스템 축으로 만들면 적성·장비·특성 위에 네 번째 밸런스 항이 생긴다. 종족 차이는 가챠 풀 안의 적성 분포로만 표현한다.

데이터 영향: Character.xlsxRace 컬럼 추가 · Enum.xlsxCharacterRace enum 신설. enum은 뒤에만 추가한다.

Race 컬럼은 아직 넣지 않았다(2026-08-02 보류). 종족의 유일한 기능이 "적성 분포의 차이"인데, 현재 1001~1006의 적성은 테스트용 임의값이라 종족과 이어지지 않는다. 외형 리소스가 붙고 적성을 손으로 설계할 때 함께 넣는다.


5. ❌ 미정 — 이 문서에서 결정하지 않은 것

Agent는 아래를 임의로 정하지 않는다. 구현이 필요하면 사용자에게 확인한다.

# 미정 항목 무엇이 막히나
1 캐릭터 레벨이 무엇을 올리는가 속도 가산? 산출량? 적성? — 성장 체감의 정체
2 캐릭터 경험치 획득식 작업으로 얼마, 먹이기로 얼마. 희귀도별로 다른가
3 캐릭터 레벨업 곡선 · 상한
4 획득 경로 가챠가 유력하나 확정하지 않았다. 시작 캐릭터도 미정시작 캐릭터는 확정(3.3, 1001 램볼)
⚠️ 산업 레벨 해금이 여기 걸렸다 (2.3) — 우선순위가 올라갔다
5 계정 경험치 전달 비율 · 계정 레벨 곡선 3.1
6 캐릭터 정원 · 중복 캐릭터 처리 같은 TID를 여러 장 가질 수 있으므로

⚠️ 1~4가 비어 있는 동안 일감 T-003(캐릭터 성장)은 보류를 유지한다. 적성 기여식은 확정됐지만(2장), 레벨 기여식이 없다.

⚠️ 적성을 레벨로 올릴 수 있게 만들지 여부는 1번에 포함된다. 올릴 수 있게 하면 결국 전 캐릭터가 전 산업을 잘하게 되어 배치 퍼즐이 무너진다 — 결정 시 이 점을 반드시 함께 본다.


6. 데이터 · 구현 접점

대상 내용
Character.xlsx CharacterTID · Name · 산업 적성 5열 · Description (Race는 보류 → 4장)
WorkSpeedTable 적성 → 기본 작업속도(천분율). Ref로 적성값을 검증한다
t_character 개체 PK · TID · 레벨 · 경험치
서버 User/Character/Character.cs · User.Character.cs · User.WorkStation.cs(ResolveSlotSpeed)

밸런스 수치는 코드 상수가 아니라 엑셀에 둔다. 수정 후 GameDesign/generate-tables.ps1 실행.


7. 서버 / 클라이언트 책임

책임 주체
적성 조회 · 배치 가능 판정(CanWork) 서버
기본 작업속도 변환 · 보정 합성 서버
경험치 누적 · 레벨업 판정 서버
캐릭터 목록·적성 표시, 배치 UI 클라이언트

클라이언트는 CurrentWorkSpeed(결과값)만 받는다. 보정 내역을 받지 않으므로 계산할 것이 없다.