Files
core2026/docs/developer/domain-and-classes.md
T

107 lines
5.9 KiB
Markdown

# 도메인 로직과 핵심 클래스
## 핵심 entity
`packages/logic/src/domain/entities.ts`가 HTTP나 Prisma row에 종속되지 않은 `General`, `City`, `Nation`,
`Troop`, diplomacy와 trigger 상태를 정의합니다. engine 전용 `TurnGeneral`, `TurnWorldState`,
`TurnEvent``app/game-engine/src/turn/types.ts`에서 실행 시간·예약 턴·월간 상태를 더합니다.
| entity | 핵심 책임 |
| ------- | -------------------------------------------------------------------------- |
| General | 능력치, 경험·공헌, 소속·도시·부대, 병력·훈련·사기, 자원, 특기·아이템, meta |
| City | 소유 국가, 규모, 인구·농업·상업·치안, 수비·성벽, 보급·전선 상태 |
| Nation | 수도, 국고·군량, 등급·국가 타입, 기술과 국가 meta |
| Troop | 부대장·구성원과 부대 상태 |
| World | 현재 연·월, 최근 턴 시각, scenario config/meta와 전체 entity collection |
Prisma row를 곧바로 게임 규칙에 넘기지 않습니다. `worldLoader.ts`와 API의 row mapper가 DB 표현을 domain
표현으로 바꾸고, flush 계층이 반대 변환을 담당합니다.
## 명령 정의
`GeneralActionDefinition`은 장수·국가 예약 명령이 공유하는 계약입니다.
- `key`, `name`: 저장 key와 화면 표시명
- `parseArgs`: 외부 입력을 실행 인자로 변환
- `buildPermissionConstraints`: 예약 입력 자체를 허용할지 판단
- `buildMinConstraints`: command table에서 현재 가능한지 사전 판단
- `buildConstraints`: 실행 시점의 전체 조건
- `getPreReqTurn`, `getPostReqTurn`: 연속 실행과 재사용 대기
- `resolve`: domain state와 effect를 계산
각 파일의 `commandSpec`은 category, 인자 필요 여부, schema와 definition factory를 등록합니다.
`GENERAL_TURN_COMMAND_KEYS`, `NATION_TURN_COMMAND_KEYS`가 전체 key 집합이며, `TurnCommandProfile`
profile별 subset을 선택합니다.
## Constraint 시스템
`packages/logic/src/constraints`는 “무엇이 필요한가”와 “현재 view가 무엇을 알고 있는가”를 분리합니다.
`ConstraintContext`에는 actor, city, nation, args, env와 평가 mode가 있고 `StateView`가 entity와 대상
정보를 제공합니다.
평가 결과는 다음 셋입니다.
- `allow`: 현재 정보로 조건을 만족합니다.
- `deny`: 이유가 확정된 실패입니다.
- `unknown`: 대상 입력이나 추가 state가 없어 아직 판정할 수 없습니다.
API command table은 `unknown`의 missing requirement가 대상 입력뿐이면 `needsInput`, 그 밖이면
`unknown`으로 보여 줍니다. 예약 뒤 실제 실행에서는 전체 context로 다시 판단합니다.
## 핵심 클래스와 조립 지점
### TurnDaemonLifecycle
`app/game-engine/src/lifecycle/turnDaemonLifecycle.ts`에 있습니다. clock, control queue, hook과 run budget을
조정하며 pause/resume/manual/scheduled run의 상태 전이를 소유합니다.
### DatabaseTurnDaemonLease
`app/game-engine/src/lifecycle/databaseTurnDaemonLease.ts`에 있습니다. profile별 단일 active owner와 fencing을
관리합니다. daemon 계산이 맞아도 lease를 잃었다면 결과를 저장하면 안 됩니다.
### InMemoryTurnWorld
`app/game-engine/src/turn/inMemoryWorld.ts`에 있습니다. entity map, dirty/create/delete set, log, message,
event, checkpoint와 월 변경을 소유합니다. `peekDirtyState()`는 저장할 변경을 보여 주고 성공한 flush 뒤
정리됩니다.
### EngineStateManager
`app/game-engine/src/turn/engineStateManager.ts`에 있습니다. world와 예약 턴 store 같은 mutable participant를
등록하고 계산 단위의 capture/restore/transaction을 제공합니다. PostgreSQL transaction을 대신하지 않고
실패한 계산의 메모리 rollback을 담당합니다.
### InMemoryReservedTurnStore와 ReservedTurnHandler
`reservedTurnStore.ts`는 장수 30칸·국가 12칸 예약 queue를 메모리에 유지합니다.
`reservedTurnHandler.ts`는 명령 loading, constraint, action context, AI fallback, progress/cooldown,
효과·로그와 queue rotation을 연결합니다.
### GeneralActionPipeline과 trigger module
`packages/logic/src/actions/engine.ts`, `triggers/*`는 명령 본체 전후의 특기·아이템·국가 특성 효과를
일정한 우선순위로 적용합니다. 같은 module 목록이라도 실행 순서가 결과와 RNG 소비를 바꿀 수 있습니다.
### WarEngine
`packages/logic/src/war/engine.ts`가 전투 resolution을, `war/actions.ts`와 trigger module이 확장 효과를,
`war/aftermath.ts`가 피해·점령·외교·후속 state를 계산합니다. `che_출병.ts`가 map, unit set, diplomacy,
time, seed와 aftermath를 조립하는 실제 장수 명령 entry입니다.
### GatewayOrchestrator
`app/gateway-api/src/orchestrator/gatewayOrchestrator.ts`가 DB의 profile desired state를 process state에
맞춥니다. `workspaceManager.ts`, `buildRunner.ts`, `seedProfileDatabase.ts`, `pm2ProcessManager.ts`
commit worktree 준비부터 build, seed, start/stop을 나눕니다.
## 새 명령을 추가할 때
1. 가장 가까운 ref command의 constraint, 실행 순서, RNG, 로그와 DB side effect를 조사합니다.
2. `packages/logic/src/actions/turn/{general,nation}`에 definition과 `commandSpec`을 작성합니다.
3. 해당 `*_TURN_COMMAND_KEYS`와 필요한 `resources/turn-commands` profile에 key를 등록합니다.
4. 인자가 있으면 Zod schema와 `app/game-api/src/turns/commandInput.ts`의 화면 입력 field를 연결합니다.
5. engine action context가 대상 entity·map·unit set·시간·seed를 완전하게 공급하는지 확인합니다.
6. permission/min/full 실패, 성공, 연속 턴, cooldown과 persistence를 테스트합니다.
7. `pnpm docs:generate`로 플레이어 커맨드 목록을 갱신하고 ref 매핑 문서를 함께 수정합니다.