summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/LivingVillage.Desktop.Tests/PrototypeTests.fs4
-rw-r--r--src/LivingVillage.Desktop/Game.fs15
-rw-r--r--src/LivingVillage.Desktop/M6Presentation.fs4
3 files changed, 22 insertions, 1 deletions
diff --git a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
index 5a153b1..4d2c895 100644
--- a/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
+++ b/src/LivingVillage.Desktop.Tests/PrototypeTests.fs
@@ -897,6 +897,10 @@ type PrototypeTests () =
Assert.AreEqual<float32>(0.0f, (atHour 13).LanternGlow)
Assert.AreEqual<float32>(1.0f, (atHour 0).LanternGlow)
+ // Evidence hook: fractional start hours map exactly onto sim ticks.
+ Assert.AreEqual<int64>(int64 20 * ticksPerHour + ticksPerHour * 3L / 4L, M6Presentation.startTickForHour 20.75)
+ Assert.AreEqual<int64>(6L * ticksPerHour, M6Presentation.startTickForHour 6.0)
+
[<TestMethod>]
member _.TitleEntranceProgressIsDeterministicAndCompleteAfterTwoSeconds () =
// 120 frames at the fixed 60Hz step = 2s entrance, pure function of frame count.
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index 3f3a1d8..4760d4e 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -126,8 +126,21 @@ type LivingVillageGame() as this =
let mutable cjkAtlas = Unchecked.defaultof<Texture2D>
let mutable pixel = Unchecked.defaultof<Texture2D>
let renderPlan = VillageArt.sampleRenderPlan ()
+ // Evidence hook: pin the starting wall-clock hour (e.g. 20.75 for 黄昏), desktop-only.
+ let startHourOverride =
+ match Environment.GetEnvironmentVariable("LV_AUTOPLAY_START_HOUR") with
+ | null | "" -> None
+ | value ->
+ match Double.TryParse(value, Globalization.NumberStyles.Float, Globalization.CultureInfo.InvariantCulture) with
+ | true, hour -> Some hour
+ | _ -> None
let createInitialWorld () =
- WorldBootstrap.initialWorldForDaylight daylightAutoplay 42UL Sim.npcCount
+ let baseWorld = WorldBootstrap.initialWorldForDaylight daylightAutoplay 42UL Sim.npcCount
+ match startHourOverride with
+ | Some hour ->
+ let tick = M6Presentation.startTickForHour hour
+ { baseWorld with Tick = tick; Time = float tick * Sim.dtSeconds }
+ | None -> baseWorld
let mutable world = createInitialWorld ()
let mutable camera = Vector2.Zero
let mutable avatarFacing = VillageArt.SouthFacing
diff --git a/src/LivingVillage.Desktop/M6Presentation.fs b/src/LivingVillage.Desktop/M6Presentation.fs
index 11399c0..a64d494 100644
--- a/src/LivingVillage.Desktop/M6Presentation.fs
+++ b/src/LivingVillage.Desktop/M6Presentation.fs
@@ -100,6 +100,10 @@ module M6Presentation =
/// 倍速标签(语义别名,HUD 用)。
let speedLabel (control: SimulationControl) : string = clockLabel control
+ /// Deterministic start tick for a wall-clock hour (evidence harness): 20.75 -> 20:45.
+ let startTickForHour (hour: float) : int64 =
+ int64 (hour * float (Sim.ticksPerDay / 24L))
+
let private hourOf (tick: int64) : int =
int ((tick / (Sim.ticksPerDay / 24L)) % 24L)