feat: add logical game clock
This commit is contained in:
@@ -94,14 +94,19 @@ model TurnDaemonLease {
|
||||
}
|
||||
|
||||
model WorldState {
|
||||
id Int @id @default(autoincrement())
|
||||
scenarioCode String @map("scenario_code")
|
||||
currentYear Int @map("current_year")
|
||||
currentMonth Int @map("current_month")
|
||||
tickSeconds Int @map("tick_seconds")
|
||||
config Json @default(dbgenerated("'{}'::jsonb"))
|
||||
meta Json @default(dbgenerated("'{}'::jsonb"))
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
id Int @id @default(autoincrement())
|
||||
scenarioCode String @map("scenario_code")
|
||||
currentYear Int @map("current_year")
|
||||
currentMonth Int @map("current_month")
|
||||
tickSeconds Int @map("tick_seconds")
|
||||
clockBaseTime DateTime? @map("clock_base_time")
|
||||
clockTick BigInt? @map("clock_tick")
|
||||
clockMode String @default("realtime") @map("clock_mode")
|
||||
clockWallAnchor DateTime? @map("clock_wall_anchor")
|
||||
lastTurnTick BigInt? @map("last_turn_tick")
|
||||
config Json @default(dbgenerated("'{}'::jsonb"))
|
||||
meta Json @default(dbgenerated("'{}'::jsonb"))
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
trafficPeriods TrafficPeriod[]
|
||||
|
||||
@@ -183,7 +188,9 @@ model General {
|
||||
horseCode String @default("None") @map("horse_code")
|
||||
itemCode String @default("None") @map("item_code")
|
||||
turnTime DateTime @map("turn_time")
|
||||
turnTick BigInt? @map("turn_tick")
|
||||
recentWarTime DateTime? @map("recent_war_time")
|
||||
recentWarTick BigInt? @map("recent_war_tick")
|
||||
age Int @default(20)
|
||||
startAge Int @default(20) @map("start_age")
|
||||
personalCode String @default("None") @map("personal_code")
|
||||
@@ -199,12 +206,13 @@ model General {
|
||||
}
|
||||
|
||||
model SelectPoolEntry {
|
||||
id Int @id @default(autoincrement())
|
||||
uniqueName String @unique @map("unique_name") @db.VarChar(20)
|
||||
ownerUserId String? @map("owner_user_id")
|
||||
generalId Int? @unique @map("general_id")
|
||||
reservedUntil DateTime? @map("reserved_until")
|
||||
info Json
|
||||
id Int @id @default(autoincrement())
|
||||
uniqueName String @unique @map("unique_name") @db.VarChar(20)
|
||||
ownerUserId String? @map("owner_user_id")
|
||||
generalId Int? @unique @map("general_id")
|
||||
reservedUntil DateTime? @map("reserved_until")
|
||||
reservedUntilTick BigInt? @map("reserved_until_tick")
|
||||
info Json
|
||||
|
||||
@@index([ownerUserId])
|
||||
@@index([reservedUntil, generalId])
|
||||
@@ -212,13 +220,15 @@ model SelectPoolEntry {
|
||||
}
|
||||
|
||||
model NpcSelectionToken {
|
||||
ownerUserId String @id @map("owner_user_id")
|
||||
validUntil DateTime @map("valid_until")
|
||||
pickMoreFrom DateTime @map("pick_more_from")
|
||||
pickResult Json @map("pick_result")
|
||||
nonce Int
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
ownerUserId String @id @map("owner_user_id")
|
||||
validUntil DateTime @map("valid_until")
|
||||
validUntilTick BigInt? @map("valid_until_tick")
|
||||
pickMoreFrom DateTime @map("pick_more_from")
|
||||
pickMoreFromTick BigInt? @map("pick_more_from_tick")
|
||||
pickResult Json @map("pick_result")
|
||||
nonce Int
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([validUntil])
|
||||
@@map("select_npc_token")
|
||||
@@ -280,14 +290,16 @@ model MessageReadState {
|
||||
}
|
||||
|
||||
model Message {
|
||||
id Int @id @default(autoincrement())
|
||||
mailbox Int
|
||||
type String
|
||||
src Int
|
||||
dest Int
|
||||
time DateTime
|
||||
validUntil DateTime @map("valid_until")
|
||||
message Json
|
||||
id Int @id @default(autoincrement())
|
||||
mailbox Int
|
||||
type String
|
||||
src Int
|
||||
dest Int
|
||||
time DateTime
|
||||
timeTick BigInt? @map("time_tick")
|
||||
validUntil DateTime @map("valid_until")
|
||||
validUntilTick BigInt? @map("valid_until_tick")
|
||||
message Json
|
||||
|
||||
@@map("message")
|
||||
}
|
||||
@@ -674,6 +686,8 @@ model Auction {
|
||||
detail Json @default(dbgenerated("'{}'::jsonb"))
|
||||
status AuctionStatus @default(OPEN)
|
||||
closeAt DateTime @map("close_at")
|
||||
openTick BigInt? @map("open_tick")
|
||||
closeTick BigInt? @map("close_tick")
|
||||
latestEventId String @default("") @map("latest_event_id")
|
||||
latestEventAt DateTime @default(now()) @map("latest_event_at")
|
||||
finalizingAt DateTime? @map("finalizing_at")
|
||||
@@ -770,7 +784,9 @@ model VotePoll {
|
||||
openerGeneralId Int @map("opener_general_id")
|
||||
openerName String @map("opener_name")
|
||||
startAt DateTime @default(now()) @map("start_at")
|
||||
startTick BigInt? @map("start_tick")
|
||||
endAt DateTime? @map("end_at")
|
||||
endTick BigInt? @map("end_tick")
|
||||
closedAt DateTime? @map("closed_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
ALTER TABLE world_state
|
||||
ADD COLUMN clock_base_time TIMESTAMP(3),
|
||||
ADD COLUMN clock_tick BIGINT,
|
||||
ADD COLUMN clock_mode TEXT NOT NULL DEFAULT 'realtime',
|
||||
ADD COLUMN clock_wall_anchor TIMESTAMP(3),
|
||||
ADD COLUMN last_turn_tick BIGINT;
|
||||
|
||||
UPDATE world_state
|
||||
SET clock_base_time = COALESCE(NULLIF(meta->>'lastTurnTime', '')::timestamp, updated_at),
|
||||
clock_wall_anchor = CURRENT_TIMESTAMP,
|
||||
clock_tick = ROUND(
|
||||
EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - COALESCE(NULLIF(meta->>'lastTurnTime', '')::timestamp, updated_at)))
|
||||
* (36000000::numeric / tick_seconds)
|
||||
)::bigint,
|
||||
last_turn_tick = 0;
|
||||
|
||||
ALTER TABLE general
|
||||
ADD COLUMN turn_tick BIGINT,
|
||||
ADD COLUMN recent_war_tick BIGINT;
|
||||
|
||||
UPDATE general
|
||||
SET turn_tick = ROUND(
|
||||
EXTRACT(EPOCH FROM (general.turn_time - world_state.clock_base_time))
|
||||
* (36000000::numeric / world_state.tick_seconds)
|
||||
)::bigint,
|
||||
recent_war_tick = CASE WHEN general.recent_war_time IS NULL THEN NULL ELSE ROUND(
|
||||
EXTRACT(EPOCH FROM (general.recent_war_time - world_state.clock_base_time))
|
||||
* (36000000::numeric / world_state.tick_seconds)
|
||||
)::bigint END
|
||||
FROM world_state;
|
||||
|
||||
ALTER TABLE select_pool ADD COLUMN reserved_until_tick BIGINT;
|
||||
ALTER TABLE select_npc_token ADD COLUMN valid_until_tick BIGINT, ADD COLUMN pick_more_from_tick BIGINT;
|
||||
ALTER TABLE message ADD COLUMN time_tick BIGINT, ADD COLUMN valid_until_tick BIGINT;
|
||||
ALTER TABLE auction ADD COLUMN open_tick BIGINT, ADD COLUMN close_tick BIGINT;
|
||||
ALTER TABLE vote_poll ADD COLUMN start_tick BIGINT, ADD COLUMN end_tick BIGINT;
|
||||
|
||||
UPDATE select_pool SET reserved_until_tick = CASE WHEN reserved_until IS NULL THEN NULL ELSE ROUND(EXTRACT(EPOCH FROM (reserved_until - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint END FROM world_state;
|
||||
UPDATE select_npc_token SET valid_until_tick = ROUND(EXTRACT(EPOCH FROM (valid_until - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint, pick_more_from_tick = ROUND(EXTRACT(EPOCH FROM (pick_more_from - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint FROM world_state;
|
||||
UPDATE message
|
||||
SET time_tick = ROUND(
|
||||
EXTRACT(EPOCH FROM (time - world_state.clock_base_time))
|
||||
* (36000000::numeric / world_state.tick_seconds)
|
||||
)::bigint,
|
||||
valid_until_tick = CASE
|
||||
-- Legacy permanent messages use the year-9999 sentinel. Keep their
|
||||
-- DateTime fallback instead of persisting a tick JavaScript cannot
|
||||
-- represent safely.
|
||||
WHEN valid_until >= TIMESTAMP '9999-01-01 00:00:00' THEN NULL
|
||||
ELSE ROUND(
|
||||
EXTRACT(EPOCH FROM (valid_until - world_state.clock_base_time))
|
||||
* (36000000::numeric / world_state.tick_seconds)
|
||||
)::bigint
|
||||
END
|
||||
FROM world_state;
|
||||
UPDATE auction SET open_tick = ROUND(EXTRACT(EPOCH FROM (created_at - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint, close_tick = ROUND(EXTRACT(EPOCH FROM (close_at - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint FROM world_state;
|
||||
UPDATE vote_poll SET start_tick = ROUND(EXTRACT(EPOCH FROM (start_at - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint, end_tick = CASE WHEN end_at IS NULL THEN NULL ELSE ROUND(EXTRACT(EPOCH FROM (end_at - world_state.clock_base_time)) * (36000000::numeric / world_state.tick_seconds))::bigint END FROM world_state;
|
||||
|
||||
CREATE INDEX general_turn_tick_id_idx ON general(turn_tick, id);
|
||||
CREATE INDEX auction_status_close_tick_idx ON auction(status, close_tick);
|
||||
@@ -9,6 +9,11 @@ export interface TurnEngineWorldStateRow {
|
||||
currentYear: number;
|
||||
currentMonth: number;
|
||||
tickSeconds: number;
|
||||
clockBaseTime: Date | null;
|
||||
clockTick: bigint | null;
|
||||
clockMode: string;
|
||||
clockWallAnchor: Date | null;
|
||||
lastTurnTick: bigint | null;
|
||||
config: JsonValue;
|
||||
meta: JsonValue;
|
||||
updatedAt?: Date | null;
|
||||
@@ -53,7 +58,9 @@ export interface TurnEngineGeneralRow {
|
||||
meta: JsonValue;
|
||||
penalty: JsonValue;
|
||||
turnTime: Date;
|
||||
turnTick: bigint | null;
|
||||
recentWarTime: Date | null;
|
||||
recentWarTick: bigint | null;
|
||||
}
|
||||
|
||||
export interface TurnEngineRankDataRow {
|
||||
@@ -157,6 +164,11 @@ export interface TurnEngineWorldStateUpdateInput {
|
||||
currentYear: number;
|
||||
currentMonth: number;
|
||||
tickSeconds: number;
|
||||
clockBaseTime: Date;
|
||||
clockTick: bigint;
|
||||
clockMode: string;
|
||||
clockWallAnchor: Date;
|
||||
lastTurnTick: bigint;
|
||||
meta: InputJsonValue;
|
||||
}
|
||||
|
||||
@@ -165,6 +177,11 @@ export interface TurnEngineWorldStateCreateInput {
|
||||
currentYear: number;
|
||||
currentMonth: number;
|
||||
tickSeconds: number;
|
||||
clockBaseTime: Date;
|
||||
clockTick: bigint;
|
||||
clockMode: string;
|
||||
clockWallAnchor: Date;
|
||||
lastTurnTick: bigint;
|
||||
config: InputJsonValue;
|
||||
meta: InputJsonValue;
|
||||
}
|
||||
@@ -207,7 +224,9 @@ export interface TurnEngineGeneralUpdateInput {
|
||||
penalty: InputJsonValue;
|
||||
meta: InputJsonValue;
|
||||
turnTime: Date;
|
||||
turnTick: bigint;
|
||||
recentWarTime: Date | null;
|
||||
recentWarTick: bigint | null;
|
||||
}
|
||||
|
||||
export interface TurnEngineGeneralCreateManyInput {
|
||||
@@ -241,7 +260,9 @@ export interface TurnEngineGeneralCreateManyInput {
|
||||
special2Code: string;
|
||||
meta: InputJsonValue;
|
||||
turnTime: Date;
|
||||
turnTick: bigint;
|
||||
recentWarTime?: Date | null;
|
||||
recentWarTick?: bigint | null;
|
||||
affinity?: number | null;
|
||||
bornYear?: number;
|
||||
deadYear?: number;
|
||||
|
||||
Reference in New Issue
Block a user