Wildlife and nature: animals, beehives, bushes, flowers, rocks, logs
Deploy web Studio / deploy (push) Successful in 1m5s
Deploy web Studio / deploy (push) Successful in 1m5s
New stdlib module wildlife.rhai: - Animals (new palette category): Deer (stag with antlers, does, fawns), Wild boar, Fox, Elephant (bull with tusks, cow, calf), Rabbits. Low-poly solids from faces (loft, tube), parts drawn back to front by depth, faces edged in their own shade (class beast). Herds scatter round a spot, each animal its own sprite facing about the object's rotation. Grazing animals switch between two head poses (iso-pose2 groups), elephants curl their trunks, rabbits hop. - Birds and Butterflies as flocks: swim() takes a shape (bird, fly, bee); wings flap out of step. Fish output unchanged. - Beehives on stands with supers, lids, entrances and bees flying round; Bush (round, flowering, berries); Flowers (bed in rows or meadow); Rocks; Log or stump. g-meadow and g-soil ground materials. - polyline() takes 3D points as documented (antlers). Theme colours for dark and light, viewer CSS for poses, flapping, hopping. examples/country: elephants in a paddock with a cut corner, deer at a forest edge, boar, fox, rabbits, an apiary by a meadow, a pond, a lane, fence and hedgerow at angles; Country demo in the web Studio and deploy. MCP guidance, README, SCRIPTING, ROADMAP. Tests: Rust 78, Studio 122; existing examples draw the same (only the embedded theme CSS grew).
This commit is contained in:
1 parent
96d472625f
commit
e840d36000
22 files changed
+1211
-16
No files matched your search
@@ -150,6 +150,7 @@ def main():
|
||||
(web / "house.json").write_text(json.dumps(demo_files("house"), ensure_ascii=False), encoding="utf-8")
|
||||
(web / "factory.json").write_text(json.dumps(demo_files("factory"), ensure_ascii=False), encoding="utf-8")
|
||||
(web / "streets.json").write_text(json.dumps(demo_files("streets"), ensure_ascii=False), encoding="utf-8")
|
||||
(web / "country.json").write_text(json.dumps(demo_files("country"), ensure_ascii=False), encoding="utf-8")
|
||||
|
||||
h = hashlib.sha256()
|
||||
for p in sorted((out / "assets").rglob("*")):
|
||||
|
||||
@@ -555,6 +555,28 @@ with sync_playwright() as p:
|
||||
pg.wait_for_timeout(700)
|
||||
check(len(doc()["objects"]) == n5, "four undos take the diagonals back")
|
||||
|
||||
# animals and an apiary from the palette: a deer herd grazes, the hives get bees
|
||||
pal = pg.evaluate("() => [...document.querySelectorAll('.st-cat')].map(e => e.dataset.cat)")
|
||||
check("Animals" in pal, "the palette has an Animals category")
|
||||
pg.locator('.st-tile[data-type="deer"]').click()
|
||||
pg.mouse.click(*at(44, 28))
|
||||
pg.wait_for_timeout(900)
|
||||
deer = doc()["objects"][-1]
|
||||
pg.locator('.st-tile[data-type="beehive"]').click()
|
||||
pg.mouse.click(*at(52, 18))
|
||||
pg.wait_for_timeout(900)
|
||||
hives = doc()["objects"][-1]
|
||||
grazing = pg.evaluate(f"() => document.querySelectorAll('[data-obj=\"{deer['id']}\"] .iso-pose2.iso-pose0').length")
|
||||
bees = pg.evaluate(f"() => document.querySelectorAll('[data-obj=\"{hives['id']}\"] .iso-bee').length")
|
||||
herd = pg.evaluate(f"() => Object.fromEntries((__studio.view.info('{deer['id']}') || {{rows: []}}).rows)['Herd'] || ''")
|
||||
check(deer["type"] == "deer" and hives["type"] == "beehive" and grazing == 4 and bees == 24 and herd == "1 stag, 2 does, 1 fawn",
|
||||
f"a deer herd and beehives placed from the palette: {grazing} grazing, {bees} bees, herd {herd}")
|
||||
pg.screenshot(path=str(OUT / "studio-wildlife.jpg"), type="jpeg", quality=80)
|
||||
for _ in range(2):
|
||||
pg.locator("#undo").click()
|
||||
pg.wait_for_timeout(700)
|
||||
check(len(doc()["objects"]) == n5, "two undos take the animals back")
|
||||
|
||||
# an agent edits over MCP: the open Studio follows
|
||||
init = mcp({"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "test", "version": "0"}}})
|
||||
check(init["result"]["serverInfo"]["name"] == "isokit", "MCP initialize")
|
||||
|
||||
@@ -342,6 +342,22 @@ try:
|
||||
check(meets == "east-ave, park-rd" and ring.startswith("4:"), f"streets know what they meet: cross-st meets {meets}; roundabout arms {ring}")
|
||||
shot(pg, "web-streets.jpg")
|
||||
|
||||
# ---------------------------------------------------------------- the country demo: animals, an apiary, diagonals
|
||||
pg.locator("#wb-projects").click()
|
||||
pg.locator("#wb-ncountry").click()
|
||||
pg.wait_for_load_state()
|
||||
ready(pg)
|
||||
pg.wait_for_timeout(500)
|
||||
nc = len(doc(pg)["objects"])
|
||||
beasts = pg.evaluate("() => new Set([...document.querySelectorAll('.iso-svg .iso-beast')].map(e => e.closest('[data-obj]')?.dataset.obj)).size")
|
||||
poses = pg.evaluate("() => document.querySelectorAll('.iso-svg .iso-pose2.iso-pose0').length")
|
||||
check(title(pg) == "isokit country" and nc > 30 and beasts >= 8 and poses >= 12 and pg.evaluate("() => __studio.S.warnings.length") == 0,
|
||||
f"Country demo opens the countryside ({nc} objects, {beasts} animal and rock groups, {poses} grazing animals, no warnings)")
|
||||
herd = pg.evaluate("() => Object.fromEntries((__studio.view.info('elephants') || {rows: []}).rows)['Herd'] || ''")
|
||||
rot = pg.evaluate("() => __studio.S.doc.objects.find(o => o.id === 'lane-d').rot")
|
||||
check(herd == "1 bull, 1 cow, 1 calf" and abs(rot - 45) < 1e-6, f"elephants: {herd}; the lane bends at {rot} degrees")
|
||||
shot(pg, "web-country.jpg")
|
||||
|
||||
# ---------------------------------------------------------------- a system asking for less motion
|
||||
# (Windows: Animation effects off): the view starts still, but the button stays and turns it on
|
||||
rctx = b.new_context(viewport={"width": 1200, "height": 800}, reduced_motion="reduce")
|
||||
|
||||
Reference in new issue
Block a user