feat: build profile for The Lewdest House; panoramas as GPU hints, live2d-only init branches, drag/at syntax
CI / frontend (push) Failing after 15s
CI / backend (push) Failing after 33s

The build (fingerprint of its scripts) skips third-party code written against Ren'Py's render API
(colour picker demo, Kinetic Text Tags, cps_preview) and waives its one missing test screen. Converter:
xpan/ypan/matrixtransform/matrixanchor are skipped like other GPU hints, `if renpy.has_live2d()` in an
init block keeps only its else branch, `crop(...)xpos` and `crop (1, 2, 3, 4)` parse, `drag` is a screen
container, `at icon["at"]` becomes a dynamic entry, and the whitelist gains Matrix, Move, absolute and
the no-op helpers. The game now passes the strict check and converts fully (3272 files, 288 MB).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-26 04:29:20 +03:00
1 parent 353cd5e49e
commit 6d78b8b847
9 files changed
+94 -10

No files matched your search

+24 -4
View File
@@ -81,7 +81,7 @@ def _static_props(kw: dict[str, Expr]) -> dict[str, Any]:
def _atl_props(text: str) -> dict[str, Any]:
"""Extract static `prop value` pairs from one ATL line, ignoring timing."""
tokens = text.replace(",", " ").split()
tokens = _words(text)
props: dict[str, Any] = {}
i = 0
while i < len(tokens) - 1:
@@ -89,11 +89,12 @@ def _atl_props(text: str) -> dict[str, Any]:
if key in POSITION_PROPS:
raw = tokens[i + 1]
try:
props[key] = ast.literal_eval(raw)
value = ast.literal_eval(raw)
props[key] = list(value) if isinstance(value, tuple) else value
except (ValueError, SyntaxError):
if raw.startswith("(") and i + 2 < len(tokens):
if not raw.startswith("(") and i + 2 < len(tokens): # `pos 0.5 0.3`
try:
props[key] = list(ast.literal_eval(raw + "," + tokens[i + 2]))
props[key] = [ast.literal_eval(raw), ast.literal_eval(tokens[i + 2])]
i += 1
except (ValueError, SyntaxError):
pass
@@ -103,6 +104,25 @@ def _atl_props(text: str) -> dict[str, Any]:
return props
def _words(text: str) -> list[str]:
"""Words split on whitespace and commas outside brackets: `crop (1, 2, 3, 4)` keeps its tuple whole."""
out, cur, depth = [], [], 0
for ch in text:
if ch in "([{":
depth += 1
elif ch in ")]}":
depth -= 1
if (ch.isspace() or ch == ",") and depth == 0:
if cur:
out.append("".join(cur))
cur = []
else:
cur.append(ch)
if cur:
out.append("".join(cur))
return out
def _split_top(source: str) -> list[str]:
parts, depth, cur = [], 0, []
for ch in source: