From 9ad3bee59b1105c25b382d307085eea9edc1c066 Mon Sep 17 00:00:00 2001 From: Dash Date: Sat, 17 Oct 2026 11:33:18 +0200 Subject: [PATCH] mechanic: start acts as their loading task does Upstream calls CompleteAct() when it dequeues the plot task, so the act number, the plot bar and the act rewards change as "Loading Act N" begins. pqcli did all that when the task ended. The random sequence is the same either way, so the parity traces are unchanged; only the 1-2 seconds of the loading task differ. --- pqcli/mechanic.py | 13 ++++++++---- tests/test_mechanic.py | 46 ++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/pqcli/mechanic.py b/pqcli/mechanic.py index 48204db..e7d42c0 100644 --- a/pqcli/mechanic.py +++ b/pqcli/mechanic.py @@ -618,12 +618,17 @@ class Simulation: ) break - elif isinstance(self.player.task, PlotTask): - self.complete_act() - old = self.player.task if self.player.queue: - self.player.set_task(self.player.queue.pop(0)) + task = self.player.queue.pop(0) + if isinstance(task, PlotTask): + # the act starts as its loading task does, as upstream + self.complete_act() + task = PlotTask( + f"Loading {act_name(self.player.quest_book.act)}", + task.duration, + ) + self.player.set_task(task) elif self.player.inventory.encum_bar.done: self.player.set_task( HeadingToMarketTask("Heading to market to sell loot", 4000) diff --git a/tests/test_mechanic.py b/tests/test_mechanic.py index a48ff75..2d12ea3 100644 --- a/tests/test_mechanic.py +++ b/tests/test_mechanic.py @@ -167,30 +167,36 @@ def test_quest_log_keeps_100_quests() -> None: def test_prologue_fills_plot_bar() -> None: - # upstream advances the plot bar on any task while act == 0 - random.seed("prologue") + # upstream advances the plot bar on any task while act == 0, and starts + # act I as its loading task starts simulation = make_simulation() player = simulation.player - positions = [] - player.connect( - "new_task", - lambda: positions.append( - (player.task.description, player.quest_book.plot_bar.position) - ), - ) - while player.quest_book.act == 0: + seen: list[tuple[str, float, int, int]] = [] + + def record() -> None: + assert player.task is not None + bar = player.quest_book.plot_bar + seen.append( + ( + player.task.description, + bar.position, + bar.max_, + player.quest_book.act, + ) + ) + + player.connect("new_task", record) + while len(seen) < 7: simulation.tick(100000.0) - assert player.quest_book.plot_bar.max_ != 26 # reset by act I - assert [position for _, position in positions[:6]] == [ - 0, - 0, - 10, - 16, - 22, - 26, + assert [(position, act) for _, position, _, act in seen[:5]] == [ + (0, 0), + (0, 0), + (10, 0), + (16, 0), + (22, 0), ] - assert positions[5][0] == "Loading Act I" - assert positions[6][0] == "Heading to the killing fields" + assert seen[5] == ("Loading Act I", 0, 21600, 1) + assert seen[6][0] == "Heading to the killing fields" def test_player_rng_survives_save_and_load() -> None: