McRogueFace/tests/snippets/081_game_inventory.py

57 lines
1.6 KiB
Python
Raw Normal View History

# mcrf: objects=[Caption,Color,Frame,Scene,Sprite] verified=0.2.8-dev status=ok
test(snippets): the docs site's 130 code samples are now part of the test suite The samples published on mcrogueface.github.io were executed by nothing at all. Each carried a machine-readable header -- objects=[...] verified=0.2.8@b6720f6 status=ok -- and every one of those fields was hand-typed. 130 snippets asserted "status=ok" while no run had ever confirmed it. This is the same failure mode as the 82 rotted tests in 112f357, at a larger scale and with no gate whatsoever. The samples now live here, in the engine repo, so that breaking the API breaks the build. The site pulls them from tests/snippets/ rather than keeping a copy to rot in parallel (build_library.py, site-side). They are display scripts: each builds a scene and stops. They deliberately do NOT call sys.exit(), because they must stay copy-pasteable -- a reader who pastes one into their game should get a running scene, not an interpreter that quits. Since #350 that also makes them un-runnable on their own, so _harness.py is chained as a second --exec to supply the ending the snippet must not have. Chaining rather than exec()-ing the source is deliberate: the snippet travels the same path a real user's script travels, and nothing has to read the file -- which is how the first draft of this harness tripped over #378 and mistook three healthy snippets for broken ones. A snippet passes only if it runs clean AND leaves a scene with something in it. Not raising is not enough: a sample whose body silently no-ops still renders as code on the docs site, and would still be wrong. tools/stamp_snippets.py makes the header a measurement instead of a claim: status comes from an actual run, verified from the engine that ran it, and objects is derived from the source intersected with what the engine exports -- so a snippet that starts using a new type gets tagged for it without anyone remembering to. It immediately found tags the humans had missed (062 uses Transition, Key and InputState; the hand-written header listed none of them). --check is the CI gate. The gate earned its keep on the first run, catching #379 (fixed here): configuring default_transition before the first scene activation made the engine transition FROM the internal "uitest" bootstrap scene, which is not a PyScene and has no Python wrapper -- so mcrfpy.current_scene reported None for the transition's full duration, immediately after the user had assigned it. A transition with nothing meaningful to transition from now changes scene immediately. Scene-to-scene transitions still report the outgoing scene until they complete. Suite: 468/468 (336 + 130 snippets + 2 regressions). closes #379
2026-07-14 18:29:37 -04:00
# Game Inventory - Grid-based inventory UI
import mcrfpy
scene = mcrfpy.Scene("demo")
mcrfpy.current_scene = scene
scene.children.append(mcrfpy.Frame(pos=(0, 0), size=(1024, 768), fill_color=mcrfpy.Color(30, 30, 40)))
# Inventory grid
inv_frame = mcrfpy.Frame(
pos=(262, 184), size=(500, 400),
fill_color=mcrfpy.Color(40, 40, 60),
outline=3.0, outline_color=mcrfpy.Color(100, 100, 140)
)
scene.children.append(inv_frame)
inv_frame.children.append(mcrfpy.Caption(text="Inventory", pos=(200, 20)))
# Create inventory slots
slots = []
items = [84, 17, 65, 0, 0, 0, 112, 0, 88, 0, 0, 0] # Sprite indices, 0 = empty
for i in range(12):
x = 30 + (i % 4) * 115
y = 70 + (i // 4) * 100
slot = mcrfpy.Frame(
pos=(x, y), size=(90, 80),
fill_color=mcrfpy.Color(60, 60, 80),
outline=2.0, outline_color=mcrfpy.Color(80, 80, 100)
)
inv_frame.children.append(slot)
if items[i] > 0:
sprite = mcrfpy.Sprite(
texture=mcrfpy.default_texture,
sprite_index=items[i],
pos=(25, 15),
scale=3.0
)
slot.children.append(sprite)
# Hover effect
def make_hover(s):
def enter(pos): s.fill_color = mcrfpy.Color(80, 80, 100)
def exit(pos): s.fill_color = mcrfpy.Color(60, 60, 80)
return enter, exit
enter, exit = make_hover(slot)
slot.on_enter = enter
slot.on_exit = exit
status = mcrfpy.Caption(text="Hover over slots to highlight", pos=(400, 620))
status.outline = 2
status.outline_color = mcrfpy.Color(0, 0, 0)
scene.children.append(status)