feat: report ATL problems only for used transforms; animate moving images
- Unsupported ATL constructs in a transform now block the import only when the transform is used (at clause, another transform, even before its definition). Stock screens.rpy transforms for unused screens no longer fail games - image blocks with one picture plus linear/ease/parallel/repeat keep their animation (image-level ATL); the renderer also starts it - Python: skip @gui.variant/@renpy.variant functions (inactive variants), treat @renpy.pure as transparent, read renpy.store.x as x - Accept renpy.transition, end_replay, block_rollback and music set_pause/set_pan as presentation-only no-ops, and implement them in the player (set_pause and set_pan were allowed by the converter but missing at runtime) - Skip the 0x52-URM add-on directory (in-game console / save editor) when parsing scripts and media - Tests for lazy ATL warnings, moving images and variants Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ff82d882c0
commit
4418da47eb
9 files changed
+133
-12
No files matched your search
@@ -102,9 +102,14 @@ def test_renpy_atl_animation_becomes_a_timeline_not_a_static_pose():
|
||||
def test_renpy_atl_constructs_without_a_runtime_are_still_rejected():
|
||||
for body in ("function slide", "time 1.0:\n xalign 1.0", "matrixcolor TintMatrix('#f00')",
|
||||
"contains:\n 'a.png'"):
|
||||
data = script(f'transform odd:\n {body}\nlabel start:\n "Hi"')
|
||||
unused = script(f'transform odd:\n {body}\nlabel start:\n "Hi"')
|
||||
require_supported_scripts(unused) # nothing shows it, so it cannot break the game
|
||||
used = script(f'transform odd:\n {body}\nlabel start:\n show eileen at odd\n "Hi"')
|
||||
with pytest.raises(CompatibilityError, match="ATL"):
|
||||
require_supported_scripts(data)
|
||||
require_supported_scripts(used)
|
||||
early = script(f'label start:\n show eileen at odd\n "Hi"\ntransform odd:\n {body}\n')
|
||||
with pytest.raises(CompatibilityError, match="ATL"): # used before it is defined
|
||||
require_supported_scripts(early)
|
||||
|
||||
|
||||
def test_renpy_atl_groups_events_and_named_transforms():
|
||||
|
||||
@@ -164,3 +164,34 @@ def test_atl_frames_layeredimage_and_channels():
|
||||
"img": {"ref": "eileen_face_happy"}}
|
||||
assert layers[2]["img"] == {"file": "sad.png"}
|
||||
assert d.channels["amb"] == {"mixer": "sfx", "loop": True}
|
||||
|
||||
|
||||
def test_moving_image_keeps_its_animation():
|
||||
d = parse('image spin:\n "mark.png"\n xalign 0.5\n linear 0 rotate 0\n linear 4 rotate -360\n repeat\n')
|
||||
image = d.images["spin"]
|
||||
assert image["file"] == "mark.png"
|
||||
spec = image["at"][0]
|
||||
assert spec["props"] == {"xalign": 0.5}
|
||||
assert spec["atl"]["repeat"] is True and spec["atl"]["steps"][-1]["props"] == {"rotate": -360.0}
|
||||
assert not d.blockers
|
||||
|
||||
|
||||
def test_unused_transforms_with_unsupported_atl_do_not_block():
|
||||
d = parse("transform spinner(delay, cycle):\n function renpy.display.layout.example\nlabel start:\n 'Hi'\n")
|
||||
assert not d.blockers
|
||||
|
||||
|
||||
def test_gui_variants_and_renpy_store_are_understood():
|
||||
d = parse(
|
||||
"init python:\n"
|
||||
" @gui.variant\n"
|
||||
" def small():\n"
|
||||
" gui.text_size = 30\n"
|
||||
" @renpy.pure\n"
|
||||
" def twice(x):\n"
|
||||
" return x * 2\n"
|
||||
" renpy.store.seen.append(1)\n")
|
||||
assert [s["op"] for s in d.init_code] == ["def", "eval"]
|
||||
assert d.init_code[0]["decos"] == [] and d.init_code[0]["name"] == "twice"
|
||||
assert d.init_code[1]["e"]["f"]["o"] == {"k": "name", "id": "seen"}
|
||||
assert not d.blockers
|
||||
Reference in new issue
Block a user