feat: player runtime for the Phone library and That New Teacher
CI / frontend (push) Failing after 17s
CI / backend (push) Failing after 34s

Named stores (PyNamespace: dotted access, functions that see their own store first, restored after a
save is loaded), real generators run step by step (next, send, yield as an expression), len/bool through
__len__/__bool__, os/calendar/itertools/pygame_sdl2 helpers, Skip and ToggleLocalVariable actions,
text tags {glitch} and {wave} and plain display of explode/gradient/ruby, SnowBlossom and anim.Blink,
RoundedCorners as a transform, transforms listed in `at`, ATL choice weights that are flags, and
renpy.image_size from the converter's picture sizes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-26 22:39:16 +03:00
1 parent 83cc7fdd5c
commit 11f87df712
15 files changed
+457 -24

No files matched your search

+27
View File
@@ -129,4 +129,31 @@ test("generator functions hand out what they yield; iter and next walk a sequenc
assert.equal(store.result_first, 7);
assert.equal(store.result_second, 8);
assert.equal(store.result_default, "done");
assert.deepEqual([store.result_a, store.result_b, store.result_c], [1, 11, 10]); // send() answers the yield
});
test("named stores keep their names apart, are reached through dotted paths, and survive a save", () => {
const { py, store } = runtime();
const call = (f, ...a) => ({ k: "call", f, a, kw: {} });
const name = (id) => ({ k: "name", id });
const attr = (o, a) => ({ k: "attr", o, a });
const c = (v) => ({ k: "const", v });
py.exec([{ op: "in_store", ns: "phone.chat", body: [
{ op: "set", t: name("counter"), v: c(0) },
{ op: "def", name: "bump", params: [], body: [
{ op: "global", names: ["counter"] },
{ op: "set", t: name("counter"), v: { k: "bin", op: "+", l: name("counter"), r: c(1) } },
{ op: "return", v: name("counter") }] },
] }]);
assert.equal(store.counter, undefined, "the name stays inside the store");
assert.equal(py.eval(call(attr(attr(name("phone"), "chat"), "bump"))), 1);
assert.equal(py.eval(call(attr(attr(name("phone"), "chat"), "bump"))), 2);
py.assignPath("phone.chat.mode", "night");
assert.equal(py.eval(attr(attr(name("phone"), "chat"), "mode")), "night");
const saved = JSON.parse(JSON.stringify({ phone: store.phone }));
assert.equal(saved.phone.a.chat.a.counter, 2);
assert.equal(saved.phone.a.chat.a.bump, undefined, "functions are rebuilt by init, not saved");
py.assignPath("phone.chat.counter", 99);
py.restoreNamespaces({ phone: decodeValue(saved).phone });
assert.equal(py.eval(attr(attr(name("phone"), "chat"), "counter")), 2);
});