feat: 실행 중 게임 옵션 변경을 지원

Gateway 관리 화면에서 현재 기수의 장수 생성 제한, 유저 자동턴, 턴 간격을 내구성 action으로 변경한다.

턴 간격 변경은 논리 tick과 현재 게임 시각을 보존하며 DB와 Redis의 tick 기반 시각을 재투영하고 기존 로그 timestamp는 유지한다.
This commit is contained in:
2026-08-17 16:05:07 +00:00
parent 50e7d894e4
commit ca6823d409
26 changed files with 1680 additions and 115 deletions
+5
View File
@@ -10,6 +10,11 @@
남은 턴 수가 보존됩니다. DateTime 필드는 이전 데이터와 화면을 위한 투영값이며
tick 필드가 존재하면 tick이 우선합니다.
운영 중 턴 간격 변경은 Gateway의 내구성 런타임 작업으로만 수행합니다. 같은
transaction에서 `world_state`, 장수·경매·메시지·설문 투영값과 checkpoint를
갱신하며 기존 역사/행동 로그의 `created_at`은 다시 쓰지 않습니다. 토너먼트의
Redis 투영은 DB commit 뒤 action ID로 멱등 적용됩니다.
## 실행 모드
- `GAME_CLOCK_MODE=realtime`: `clock_wall_anchor` 이후의 실제 경과시간을
+11 -1
View File
@@ -30,7 +30,8 @@ Gateway API는 다음 저장 경계를 사용합니다.
- `GatewayProfile`: profile, scenario, port, 상태와 build 결과
- `GatewayOperation`: build/reset/open/close 등 실행 요청과 결과
- `GatewayReleaseOperation`, `GatewayReleaseState`: Gateway 전체 릴리스 queue와 현재·이전 commit
- `GatewayRuntimeAction`: profile별 시간 가속·연기 요청, 부분 적용과 최종 결과
- `GatewayRuntimeAction`: profile별 시간 가속·연기와 현재 기수 설정 변경 요청,
payload, 부분 적용과 최종 결과
- Redis: gateway session, OAuth 임시 상태, KakaoTalk 로그인 challenge, flush channel
Kakao 로그인은 URL 이름만으로 사용자를 연결하지 않습니다. `account_email`
@@ -102,6 +103,15 @@ DB partial unique index로 한 건만 허용합니다. Turn daemon은 자신의
Redis 단계가 실패하면 action은 `PARTIAL`과 backoff 상태로 남고 DB 시간은
다시 이동하지 않습니다.
현재 기수의 턴 간격·장수 생성 제한·유저 자동턴도 같은
`GatewayRuntimeAction`/`InputEvent` 경계를 사용합니다. Turn daemon은 세 값을
한 transaction에서 `world_state.config``meta`에 저장합니다. 턴 간격이
바뀌면 현재 표시 게임 시각과 game tick을 고정한 채 `clock_base_time`, 장수
턴·최근 전쟁, checkpoint, 경매·메시지·설문 DateTime 투영값을 새 간격으로
다시 계산합니다. 기존 `log_entry.created_at`은 갱신하지 않고 변경을 알리는 새
역사 로그만 추가합니다. Redis 토너먼트의 tick 소유 시각도 action ID로 한 번만
재투영하며 실패하면 `PARTIAL`에서 재시도합니다.
Gateway API와 독립 orchestrator의 SIGINT·SIGTERM은
`installGatewayShutdownController()`가 하나의 종료 Promise로 합칩니다.
Gateway API는 Fastify `app.close()`를 통해 orchestrator task를 drain한 뒤