feat: an infused shot can travel from its own subject to the infused word (or back), not only aim at one

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
digital-garbage
2026-10-13 06:38:43 +03:00
co-authored by Claude Sonnet 5.5
parent 090f8cfbb8
commit 8fbffdea99
2 changed files with 23 additions and 2 deletions
+6 -1
View File
@@ -75,6 +75,7 @@ MOVES_THEN = ("Then the camera pans to {y}.", "Then the camera racks focus to {y
MOVES_FINISH = ("Then the camera zooms out.", "Then the camera pulls back.",
"Then the camera pulls back to a wider view.")
COUNT_WEIGHTS = (6, 3, 1) # one move / two / three, in a shot that gets any
INFUSED_TRAVEL = 0.5 # of infused shots with a subject of their own, how many travel between the two
TRAVEL_SHARE = 0.25 # of one-move shots with two topics, how many travel X -> Y
HOLD_SHARE = 0.25 # of the other one-move shots, how many stay still on one thing
MOVES_HOLD = ("The camera holds steady on {x}.", "The camera stays still, focused on {x}.",
@@ -616,7 +617,11 @@ def add_camera_moves(text, seed=None, chance=1.0, prior=None, choices=None, arms
infused = _infused(picture, {c[0] for c in pool}, bank, roll)
else:
infuse_arm = "infuse:no"
moves, desc, opening, style = _plan(pool, last, rng, shot_prior, force=[infused] if infused else force, mode=mode, arms=arms)
aim = [infused] if infused else force
if infused and roll.random() < INFUSED_TRAVEL: # "from X to Y": the infused word and the shot's own subject, either way round
own = _draw(pool, shot_prior, roll, 1)[0]
aim = [infused, own] if roll.random() < 0.5 else [own, infused]
moves, desc, opening, style = _plan(pool, last, rng, shot_prior, force=aim, mode=mode, arms=arms)
entry.update(move=moves, target=desc, infused=infused[0] if infused else None)
if rng is not None and mode == "auto" and not force: # only what nobody dictated is learned
entry["arms"] = ["move:yes"] + ([f"style:{style}"] if style else [])
@@ -1,5 +1,7 @@
"""Focus infusion: a camera focus now and then aims at a word the user's prompts keep returning to."""
import re
import pytest
from .. import engine, memory, nodes
@@ -35,7 +37,8 @@ def test_at_one_the_focus_is_a_word_from_other_prompts_not_the_shots_own():
out, said, arms = _move(focus_infusion_chance=1, variation=variation)
sentence = out.split(WALK)[1]
assert "hand" in sentence or "head" in sentence, out
assert "legs" not in sentence and "street" not in sentence, "instead of the shot's own focus"
if " from " not in sentence:
assert "legs" not in sentence and "street" not in sentence, "instead of the shot's own focus, unless it travels between the two"
assert "infuse:yes" in arms and any(a in arms for a in ("infused:hand", "infused:head"))
assert "infused:" in said or "infused" in said
@@ -134,3 +137,16 @@ def test_the_oldest_projects_are_forgotten_past_the_cap_and_a_forgotten_word_lea
kept = memory._read()["projects"]
assert len(kept) == memory.MAX_PROJECTS and "proj0" not in kept and f"proj{memory.MAX_PROJECTS + 2}" in kept
assert memory.forget("word", "lamp") and all("lamp" not in r["seen"] for r in memory._read()["projects"].values())
def test_an_infused_shot_often_travels_from_its_own_subject_to_the_infused_word_or_back():
text = "[Shot 1] A woman holds a red umbrella and a lantern while she walks along the wet street."
travels = 0
for seed in range(200):
out, report = engine.add_camera_moves(text, seed=seed, chance=1, infuse=1.0, bank=[("window", 1.0)])
assert report[0]["infused"] == "window"
added = out[len(text):]
if re.search(r"from .+ to .+", added):
assert "window" in added, added
travels += 1
assert 60 < travels < 140, f"about half travel, got {travels}"