ATL
- Image blocks become timelines: picture steps with dissolve, parallel, contains,
finite repeat, time, function f(trans, st, at), calls of other transforms with
arguments, on hover/idle events for buttons. Animations stop when their element
leaves the page
- Pictures defined by an expression (get_face_path("base")) are drawn at show time
- Purely graphical hints (shader, mesh, gl_*, u_*) are accepted and dropped
Colour
- matrixcolor and im.matrix.* as 5x5 matrices combined with `*`, applied through SVG
filters; im.MatrixColor/Scale/Crop/Blur/Composite and Text/Image as values
Python
- match statement, re/copy/time/datetime/defaultdict/functools.partial, more
str/dict methods, Character(...) created by code
- narrator("..."), Character calls, renpy.say and renpy.show/hide with expressions in
Python blocks become script nodes
- Audit follows reachability: functions and classes nothing refers to (custom
statement lexers, unused tools) no longer block an import
Docs: README and ARCHITECTURE now describe a multi-engine library (GameMaker and
QSP planned). Tests for the new runtime pieces.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
29 lines
1.1 KiB
Python
29 lines
1.1 KiB
Python
"""Splitting Ren'Py "simple expression" values out of a line (screens and ATL)."""
|
|
import re
|
|
|
|
OPERATORS = {"+", "-", "*", "/", "//", "%", "**", "==", "!=", "<", ">", "<=", ">=", "and", "or", "in", "is",
|
|
"if", "else", "not"}
|
|
|
|
|
|
def read_value(words: list[str], i: int) -> tuple[str, int]:
|
|
"""One property value starting at words[i]. Decompiled sources keep operators unparenthesised
|
|
(``text "Day " + str(day)``), so a value continues while the next word is an operator."""
|
|
parts = [words[i]]
|
|
i += 1
|
|
if parts[0] in ("not", "-") and i < len(words):
|
|
parts.append(words[i])
|
|
i += 1
|
|
while i < len(words):
|
|
if words[i].startswith("(") and re.search(r"[\w\])]$", parts[-1]): # `ToggleVariable ("x")`
|
|
parts[-1] += words[i]
|
|
i += 1
|
|
elif parts[-1].endswith(",") or parts[-1] in OPERATORS: # `A(), B()` / `a +` continue
|
|
parts.append(words[i])
|
|
i += 1
|
|
elif i + 1 < len(words) and words[i] in OPERATORS:
|
|
parts.extend([words[i], words[i + 1]])
|
|
i += 2
|
|
else:
|
|
break
|
|
return " ".join(parts), i
|