feat: generator interpreter for Python that waits for the player (Ren'Py)
Python containing renpy.input, narrator("..."), character calls, renpy.say,
renpy.pause, renpy.display_menu, renpy.with_statement or renpy.call_screen now
runs through loops, try, functions, methods and expressions.
Player
- python.ts: execG/evalG/callG run only the code that may wait (mayBlock);
everything else stays on the synchronous fast path. A waiting call returns a
BlockingCall; outside the generator interpreter it is an explicit error. The
interpreter scope is set aside while the player decides
- engine: drives the generator and answers requests (dialogue, text input with
length/allow/exclude, pause, choice menu, transition, call screen)
- renpy.show/hide/scene, transitions and transforms as Python values,
Character(...) objects, Borders, set_tag_attributes
Converter
- blocking_names() lists game functions that may wait, transitively, and ships
them as game.json "blocking"; character calls are allowed
- hide screen of an unknown screen is harmless; images defined by a parenthesised
expression are supported
Hooked now passes the strict compatibility check (with Tomie and Twisted-Thoughts).
Tests: waiting.py fixture run through the generator interpreter; blocking-name analysis.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea03cebf6a
commit
3923ee72fb
11 files changed
+698
-27
No files matched your search
@@ -195,3 +195,24 @@ def test_gui_variants_and_renpy_store_are_understood():
|
||||
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
|
||||
|
||||
|
||||
def test_functions_that_wait_for_the_player_are_listed_transitively():
|
||||
from app.converter.compatibility import audit_ir, blocking_names
|
||||
|
||||
d = parse(
|
||||
"define e = Character('E')\n"
|
||||
"init python:\n"
|
||||
" def ask_name():\n"
|
||||
" return renpy.input('Name?')\n"
|
||||
" def outer():\n"
|
||||
" n = ask_name()\n"
|
||||
" e('hi ' + n)\n"
|
||||
" def plain(x):\n"
|
||||
" return x + 1\n"
|
||||
"label start:\n"
|
||||
" $ outer()\n"
|
||||
" $ y = plain(2)\n")
|
||||
audit_ir(d)
|
||||
assert not d.blockers
|
||||
assert blocking_names(d) == ["ask_name", "outer"]
|
||||
Reference in new issue
Block a user