feat: report ATL problems only for used transforms; animate moving images
CI / frontend (push) Successful in 23s
CI / backend (push) Successful in 1m55s

- 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:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-25 12:20:39 +03:00
1 parent ff82d882c0
commit 4418da47eb
9 files changed
+133 -12

No files matched your search

+4 -1
View File
@@ -60,8 +60,10 @@ def tokens(text: str) -> list[str]:
class AtlParser:
def __init__(self, warn: Callable[[str, Line], None], is_static: Callable[[str], dict | None]):
def __init__(self, warn: Callable[[str, Line], None], is_static: Callable[[str], dict | None],
on_use: Callable[[str], None] = lambda name: None):
self.warn = warn
self.on_use = on_use
# name -> props when `name` is a known static transform (inlined), else None
self.static_transform = is_static
@@ -137,6 +139,7 @@ class AtlParser:
if props:
steps.append({"op": "set", "props": props})
elif len(parts) == 1 and re.fullmatch(r"[A-Za-z_]\w*", first):
self.on_use(first)
known = self.static_transform(first)
steps.append({"op": "set", "props": known} if known is not None else {"op": "use", "name": first})
else: