1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! # D01: Shrine chamber
//!
//! Combine a multi-object unlock, a latched gate, a continuous bridge target,
//! and a one-shot room-transition request in one chamber graph.
//!
//! ```
//! use wyrd::{
//! from_level, tick_once, weave, BindOpts, FlagPriority, KnotKind, Runtime, ScriptedHost,
//! SignalDomain, ONE, ZERO,
//! };
//! # fn value(runtime: &Runtime, path: &str) -> wyrd::Signal { let id = runtime.path_id(path).unwrap(); runtime.outbox().signals().iter().find(|s| s.path == id).unwrap().value }
//!
//! let weave = weave! {
//! id: "shrine-chamber";
//! knots {
//! crate_on_sun_pad = KnotKind::signal_in(SignalDomain::Bool);
//! player_on_moon_pad = KnotKind::signal_in(SignalDomain::Bool);
//! relic_placed = KnotKind::signal_in(SignalDomain::Bool);
//! pads_ready = KnotKind::and2();
//! shrine_ready = KnotKind::and2();
//! unlock_edge = KnotKind::rising_from_zero();
//! gate_latch = KnotKind::flag(FlagPriority::ResetWins, false);
//! gate_open = KnotKind::signal_out("shrine.gate.open", SignalDomain::Bool);
//!
//! bridge_lever = KnotKind::signal_in(SignalDomain::Level);
//! bridge_target = KnotKind::map(ZERO, ONE, ZERO, from_level(8.0), SignalDomain::Level);
//! bridge_out = KnotKind::signal_out("shrine.bridge.target", SignalDomain::Level);
//!
//! player_at_exit = KnotKind::signal_in(SignalDomain::Bool);
//! exit_ready = KnotKind::and2();
//! exit_edge = KnotKind::rising_from_zero();
//! transition = KnotKind::emit_command("world.request_transition");
//! }
//! threads {
//! crate_on_sun_pad.out -> pads_ready.in_0;
//! player_on_moon_pad.out -> pads_ready.in_1;
//! pads_ready.out -> shrine_ready.in_0;
//! relic_placed.out -> shrine_ready.in_1;
//! shrine_ready.out -> unlock_edge.in;
//! unlock_edge.out -> gate_latch.set;
//! gate_latch.out -> gate_open.in;
//!
//! bridge_lever.out -> bridge_target.in;
//! bridge_target.out -> bridge_out.in;
//!
//! gate_latch.out -> exit_ready.in_0;
//! player_at_exit.out -> exit_ready.in_1;
//! exit_ready.out -> exit_edge.in;
//! exit_edge.out -> transition.trigger;
//! }
//! }?;
//!
//! let mut runtime = Runtime::bind(weave, BindOpts::default())?;
//! let crate_on_pad = runtime.required_sense("crate_on_sun_pad")?;
//! let player_on_pad = runtime.required_sense("player_on_moon_pad")?;
//! let relic = runtime.required_sense("relic_placed")?;
//! let lever = runtime.required_sense("bridge_lever")?;
//! let exit = runtime.required_sense("player_at_exit")?;
//! let mut host = ScriptedHost::new();
//!
//! host.push_frame([
//! (crate_on_pad, ONE),
//! (player_on_pad, ONE),
//! (relic, ZERO),
//! (lever, ONE),
//! (exit, ZERO),
//! ]);
//! tick_once(&mut host, &mut runtime)?;
//! assert_eq!(value(&runtime, "shrine.gate.open"), ZERO);
//! assert_eq!(value(&runtime, "shrine.bridge.target"), from_level(8.0));
//!
//! host.push_frame([
//! (crate_on_pad, ONE),
//! (player_on_pad, ONE),
//! (relic, ONE),
//! (lever, ONE),
//! (exit, ZERO),
//! ]);
//! tick_once(&mut host, &mut runtime)?;
//! assert_eq!(value(&runtime, "shrine.gate.open"), ONE);
//! assert!(runtime.outbox().emits().is_empty());
//!
//! host.push_frame([
//! (crate_on_pad, ZERO),
//! (player_on_pad, ZERO),
//! (relic, ZERO),
//! (lever, ZERO),
//! (exit, ONE),
//! ]);
//! tick_once(&mut host, &mut runtime)?;
//! assert_eq!(value(&runtime, "shrine.gate.open"), ONE);
//! assert_eq!(value(&runtime, "shrine.bridge.target"), ZERO);
//! assert_eq!(runtime.outbox().emits().len(), 1);
//!
//! host.push_frame([
//! (crate_on_pad, ZERO),
//! (player_on_pad, ZERO),
//! (relic, ZERO),
//! (lever, ZERO),
//! (exit, ONE),
//! ]);
//! tick_once(&mut host, &mut runtime)?;
//! assert!(runtime.outbox().emits().is_empty());
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! Wyrd owns the deterministic decisions. The host reads the gate and bridge
//! targets, performs movement and collision, handles the transition request,
//! and persists whatever progress the game design requires.
//!
//! You have completed the tiered examples. Return to the [`examples`](crate::examples)
//! index or continue into the API reference.