Conveyors and producers: goods flow from presses down the belts
Deploy web Studio / deploy (push) Successful in 1m4s

- Producer (category Industry): a press making cartons, crates, drums, sacks or parts at a set
  rate per minute; its ram goes down once per item, a green / red light shows running / stopped.
- Conveyor: drawn the way it runs (new prefab meta `directed`: the Studio turns the piece from
  where the drag starts), belt width, height, rise (inclines), speed, goods and spacing; legs,
  rails and a drive motor. Corners join without overlap (the receiving belt runs through, the
  feeding one stops at its side).
- A conveyor starting on a producer's output side carries its goods at its rate; one starting at
  another's end carries on with what that one carries. The gap is speed / rate. A stopped press or
  belt stops the goods after it. Tooltips show speed, rate and source.
- The goods ride a group moving one gap per loop (no reordering), first fading in, last out.
- Script API: world_of(o, u, v), info_row(key, value); objects_on falls back to half of p.d.
- Theme: industry colours, LED colours (the marker's LED had none).
- examples/factory + Factory demo in the web Studio; MCP instructions on production lines.

Checks: 68 Rust tests (conveyor joints, feed and spacing, every view of the factory demo),
Studio 108/108 (draw direction, feed from a producer, rate change), web 89/89.
This commit is contained in:
grabowski committed 2026-10-24 21:46:10 +07:00
1 parent a202283a60
commit 18dd324543
20 files changed
+617 -18

No files matched your search

+11
View File
@@ -115,6 +115,13 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
/* fish: each turns round its pond's middle (the box is centred there), at its own speed */
.iso-svg .iso-swim { transform-box: fill-box; transform-origin: center; animation: iso-spin 20s linear infinite; }
.iso-svg .iso-rip { transform-box: fill-box; transform-origin: center; animation: iso-rip 5.1s ease-out infinite; }
/* conveyors: the goods move one spacing per loop and start again, the first fading in, the last out;
presses go down once per item */
.iso-svg .iso-ride { animation: iso-move 2s linear infinite; }
.iso-svg .iso-ridein { animation: iso-fadein 2s linear infinite; }
.iso-svg .iso-rideout { animation: iso-fadeout 2s linear infinite; }
.iso-svg .iso-rideio { animation: iso-fadeio 2s linear infinite; }
.iso-svg .iso-ram { animation: iso-ram 2s ease-in-out infinite; }
.iso-svg .iso-park { display: none; }
/* paused off-screen (iso-off), when stopped (iso-still), with animation off and during pan/zoom gestures */
.iso-off .iso-a, .iso-still .iso-a, .iso-off .iso-drive, .iso-still .iso-drive, .iso-off .iso-ledr, .iso-off .iso-ledo, .iso-still .iso-ledr, .iso-still .iso-ledo,
@@ -132,6 +139,10 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; }
@keyframes iso-rip { 0% { transform: scale(.2); opacity: 0; } 15% { opacity: .9; } 100% { transform: scale(1.5); opacity: 0; } }
@keyframes iso-glint { 0%, 84%, 100% { opacity: 0; } 91% { opacity: .9; } }
@keyframes iso-blink { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@keyframes iso-fadein { 0% { opacity: 0; } 35%, 100% { opacity: 1; } }
@keyframes iso-fadeout { 0%, 65% { opacity: 1; } 100% { opacity: 0; } }
@keyframes iso-fadeio { 0%, 100% { opacity: 0; } 30%, 70% { opacity: 1; } }
@keyframes iso-ram { 0%, 20%, 100% { transform: translate(0, 0); } 45%, 55% { transform: translate(var(--dx), var(--dy)); } }
@keyframes iso-move { from { transform: translate(0, 0); } to { transform: translate(var(--dx), var(--dy)); } }
@keyframes iso-shuttle {
0%, 8% { transform: translate(0, 0); }