최종 갱신 (KST)

← 일감 목록
T-003

캐릭터 레벨·경험치를 성장에 반영

진우 Closed 우선순위 보통 목표 261010 · 보관됨

2026-10-06 — ✅ 완료. 클라가 슬롯 설정 효율 줄 "속도 가산"에 레벨 항을 따로 표시했고(레벨 +64% · 특성 · 장비), 사용자 실측으로 서버 CurrentWorkSpeed와 맞는 것을 확인했다 — 이슈 #35 닫음.

2026-10-06 — 재정의: 레벨 효과 = 작업속도 자동 가산 (이슈 #35 기획·서버·클라 동의) — 서버·엑셀·문서 구현 완료. 적성 포인트(수동 찍기 · 산업별 상한 150칸)는 철거했다. 적성은 CharacterTable 값으로 고정되고, 레벨은 CharacterLevelTable.SpeedAddPermille만큼 속도에 가산된다 — 아래 "2026-10-06 재정의" 절.

2026-10-05 — 태웅: 자동 가산 방향에 동의한다. 이슈 #35에 코멘트로 남겼다 — 서버 구현 대기. 클라는 먼저 슬롯 설정(캐릭터 줄·배치 카드)과 슬롯 목록에 캐릭터 레벨을 표시했다(이름 Lv27). 가산이 들어오면 슬롯 설정의 효율 줄 "속도 가산"(T-095가 만든 특성·장비 내역)에 레벨 항을 따로 더한다 — 장비 가산에 섞지 않는다. 2026-09-24 — ⏸ 기획 간소화를 요청했다 → 이슈 #35. 적성 포인트(수동 찍기 · 캐릭터·산업별 상한 150칸)가 방치형에 과하다고 보고 레벨 자동 가산을 제안했다. 답을 받기 전까지 클라 화면을 만들지 않는다 — 동의되면 화면 자체가 사라진다. 2026-09-17 — 레벨 효과가 적성 포인트로 확정됐고 서버 구현까지 끝났다 → 캐릭터 5.4. 남은 것은 클라 화면뿐이다. 2026-09-13 — 경험치 획득식·레벨 곡선을 확정하고 서버 누적·레벨업·저장·푸시까지 구현했다.

배경

t_character에 level·exp 컬럼을 만들어 두고 Character 객체까지 싣고 있었지만 아무 데서도 읽지 않았다. 캐릭터 속도는 CharacterTable의 고정 적성값으로만 정해져서, 레벨이 올라도 아무 일도 일어나지 않는다 — 이 부분은 여전히 그렇다(레벨 효과 미정).

2026-09-13 확정 — 경험치 획득식 · 레벨 곡선

→ 캐릭터 5.2

항목 값
획득 시점 판정 1회 성립마다 (WorkStation.Settle이 돌려주는 JudgeCount 단위)
획득량 IndustryLevelTable.ExpPerJudge — Lv1 1 → Lv5 81 (레벨당 ×3, RequiredScore와 같은 등비)
레벨 곡선 CharacterLevelTable.RequiredExp — 그 레벨에 도달하는 데 직전 레벨에서 필요한 양. Lv2 10 → 레벨당 ×1.2 (내림)
만렙 100 (테이블 마지막 행). 만렙에서는 더 쌓지 않는다
레벨업 필요치를 채우면 +1, 남은 경험치는 이월. 한 정산에서 여러 레벨 가능
저장 t_character.exp = 현재 레벨에서 쌓은 양 (누적이 아니다)

2026-09-13 구현 — 서버

조각 위치
레벨 곡선 보관소 (마지막 행 = 만렙) Server/WSGameServer/Common/CharacterLevelCatalog.cs
경험치 가산 · 레벨업 · 이월 · 만렙 처리 Character.GainExp
정산 시 JudgeCount × ExpPerJudge를 배치 캐릭터에 가산 User.WorkStation.cs SettleWorkStation → User.Character.cs GrantWorkExp
확정값 저장 (UPDATE t_character SET level, exp) Repository/CharacterGrowthRepository.cs
바뀐 개체 1건 푸시 S_CharacterSyncResponse(PacketId 21) — Unity ServerPacketHandler.CharacterSynced 이벤트까지
테스트 17건 CharacterGrowthTest · CharacterLevelCatalogTest · UserCharacterGrowthTest

2026-09-17 확정 — 레벨 효과 = 적성 포인트

→ 캐릭터 5.4

항목 값
포인트 10레벨마다 1 (CharacterLevelTable.AptitudePoint) · 만렙까지 10
사용 원할 때 산업 하나 +1 · 안 쓴 건 남는다 · 되돌리기 없음
상한 캐릭터·산업별 CharacterTable FarmingCap…HuntingCap · 0인 산업도 1로
저장 t_character farming_bonus…hunting_bonus — 찍은 양만. 남은 포인트 = 번 총합 − 찍은 합
패킷 AptitudeInfo.Cap · CharacterInfo.AptitudePoints · C_AptitudeUpRequest/S_AptitudeUpResponse · 결과 코드 NoAptitudePoint·AptitudeAtCap
반영 찍으면 정산 → 속도 재계산 → 슬롯 싱크

2026-10-06 재정의 — 레벨 효과 = 작업속도 가산

→ 이슈 #35 · 캐릭터 5.4

속도 = 적성기본값(적성 고정) × (1 + 장비 + 특성 + 레벨) × 전역배수
항목 값
데이터 CharacterLevelTable.SpeedAddPermille — 그 레벨의 가산 총량(누적값). 초안 레벨당 +1% (Lv1 0 → Lv100 990‰)
적성 CharacterTable 기본값 그대로 — 찍기·상한 없음
반영 레벨이 오르면 정산 → 속도 재계산 → 바뀐 슬롯 싱크 (정산 경로 · 치트 경로 둘 다)
클라 가산값은 GameData 미러(CharacterLevelTable)에서 읽는다 — 패킷 추가 없음
조각 위치
레벨 → 가산 CharacterLevelCatalog.SpeedAddAt · User.GetLevelSpeedAdd
속도식 User.WorkStation.cs ResolveSlotSpeed — .Add(GetLevelSpeedAdd(...))
레벨업 시 재계산 SettleWorkStation 끝에서 ApplyWorkStationSpeed · 치트 GiveCharacterExp는 RefreshWorkStationSpeed
테스트 CharacterLevelCatalogTest · UserCharacterGrowthTest 3건 (가산 반영 · 소급 없음 · 배치 시 가산)
DB 마이그레이션 Server/Shared/migrations/2026-10-06-drop-aptitude-bonus.sql — 새 서버는 보너스 컬럼을 읽지 않으므로 돌리기 전에도 동작은 같다

철거한 것 (2026-09-17 적성 포인트)

  • 엑셀 CharacterLevelTable.AptitudePoint · CharacterTable FarmingCap…HuntingCap
  • DB t_character farming_bonus…hunting_bonus (마이그레이션)
  • 패킷 C_AptitudeUpRequest(32)/S_AptitudeUpResponse(33) · AptitudeInfo.Cap · CharacterInfo.AptitudePoints · 결과 코드 700·701 — 번호는 결번
  • 서버 AptitudeBonus · TryRaiseAptitude · RaiseAptitude · CharacterAptitudeRepository · CharacterTableValidator · 우편·경매 캐릭터의 Bonus

할 일 (2026-10-06 재정의)

  • [x] 엑셀 — CharacterLevelTable.AptitudePoint → SpeedAddPermille · CharacterTable 상한 5컬럼 삭제
  • [x] 서버 — 속도식에 레벨 가산 .Add() · 레벨업 시 슬롯 속도 재계산 (테스트)
  • [x] 서버 — 적성 포인트 경로 철거 (위 목록)
  • [x] DB 마이그레이션 파일 — t_character 보너스 5컬럼 삭제 (game.sqlite3 적용은 서버를 끄고)
  • [x] 기획 문서 — 캐릭터 5.4 외 이슈 #35 목록
  • [x] 이슈 #35 → 클라로 공 넘기기 (2026-10-06)
  • [x] 클라 — 슬롯 설정 효율 줄 "속도 가산"에 레벨 항 표시 · 실측 후 #35 닫기 (2026-10-06 · 태웅)

할 일 (2026-09-13 ~ 09-17 — 끝난 것)

  • [x] 경험치 획득 경로 결정 → 판정 1회마다 (2026-09-13)
  • [x] 레벨업 곡선 결정 → CharacterLevelTable 100행 (2026-09-13)
  • [x] 경험치 누적 · 레벨업 구현 + t_character 저장 (2026-09-13)
  • [x] 서버 → 클라 푸시 S_CharacterSyncResponse + Unity 핸들러·이벤트 (2026-09-13)
  • [x] 클라 반영 → T-052로 분리 (담당 클라 · PlayerDataModel 병합 + 레벨·경험치 표시)
  • [x] 레벨 → 적성/속도 기여식 결정 → 적성 포인트 (2026-09-17)
  • [x] CharacterTable과의 관계 정리 → 기본값은 테이블, 찍은 보너스는 DB, 실효 적성 = 합 (2026-09-17)
  • [x] 엑셀 — CharacterTable 상한 5컬럼(초안: 등급표 윗값) · CharacterLevelTable.AptitudePoint (2026-09-17)
  • [x] DB — t_character 보너스 5컬럼 (2026-09-17)
  • [x] 프로토콜 — AptitudeInfo.Cap · CharacterInfo.AptitudePoints · C_AptitudeUpRequest(27)/S_AptitudeUpResponse(28) · 결과 코드 600~ (2026-09-17)
  • [x] 서버 — AptitudeBonus · Character.TryRaiseAptitude · User.RaiseAptitude · SaveCharacterAptitudeRepository · 기동 시 CharacterTableValidator · 테스트 19건 (2026-09-17)
  • [x] 클라 — 포인트 찍기 화면 — 2026-10-06 재정의로 없어졌다

2026-09-17 구현 — 서버

조각 위치
찍은 보너스 값 타입 · 찍기 결과 enum Server/WSGameServer/User/Character/AptitudeBonus.cs
실효 적성 = 기본 + 보너스 · 상한 · 남은 포인트 · 찍기 Character.GetAptitude · GetAptitudeCap · RemainingPoints · TryRaiseAptitude
레벨까지 번 포인트 누적 CharacterLevelCatalog.PointsEarnedBy
검증 → 저장 → 정산·속도 갱신 → 응답 User.Character.cs RaiseAptitude
확정값 5열 저장 · 로그인 조회 Repository/CharacterAptitudeRepository.cs · LoginRepository
기본 ≤ 상한 기동 검사 Common/CharacterTableValidator.cs (GameServer.Run)
Unity 수신 이벤트 ServerPacketHandler.AptitudeUpResponded

완료 조건

레벨이 오르면 찍는 조작 없이 슬롯 속도가 실제로 달라지고, 그 값이 재접속 후에도 유지된다. (서버 ✅ 2026-10-06 — 레벨은 DB에 남으므로 재접속하면 같은 가산이 다시 계산된다.) (경험치·레벨 자체는 이미 재접속 후 유지된다 — LoginRepository가 level·exp를 읽는다.)

막고 있는 것 / 선행 일감

  • 없음. 이슈 #35는 2026-10-06 동의로 풀렸다

관련 커밋

  • 08d8781 — 레벨 효과 = 작업속도 가산 · 적성 포인트 철거 (main 머지 4be6fe6)

  • 이 커밋 — 클라 효율 줄에 레벨 가산 항 (GameDataLoader.GetLevelSpeedAdd)

  • b77bacb — level/exp 컬럼과 Character 객체 도입 (읽지는 않음)

  • 5b8939e — 경험치 곡선 데이터(ExpPerJudge · CharacterLevelTable) + 기획 문서

참고

  • Server/WSGameServer/User/Character/Character.cs — GainExp
  • Server/WSGameServer/User/User.WorkStation.cs — SettleWorkStation · ResolveExpPerJudge
  • GameDesign/Excel/Character.xlsx — CharacterLevelTable · GameDesign/Excel/Industry.xlsx — ExpPerJudge