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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//! Environment traits and implementations
//!
//! This module defines the core environment interface and provides
//! built-in environments for reinforcement learning.
//!
//! # Action types and continuous (Box) action spaces
//!
//! The `Environment` trait exposes its action type as an associated
//! type `Environment::Action`. Discrete envs (CartPole, Snake, Pong,
//! SimpleBandit, BucketBrigade) set `type Action = i64;`. Continuous
//! envs set `type Action = Vec<f32>;` (or another float type for
//! single-dim cases). See `games::continuous_lqr::ContinuousLqr` for
//! a minimal continuous-action existence proof.
//!
//! ## Why the associated-type strategy (Strategy A)?
//!
//! When this trait was extended to support continuous-control
//! algorithms (SAC, TD3, DDPG, PPO with Gaussian heads), there were
//! two candidate designs:
//!
//! - **A. Associated `Action` type on `Environment`** (chosen). One trait,
//! parameterised by the action type. Discrete envs default to `type Action =
//! i64;` so existing call sites and trainers migrate by adding a single line
//! per env impl.
//! - **B. Parallel `ContinuousEnvironment` trait.** Two distinct traits; envs
//! implement one or the other (or both). The trainer dispatches per-trait.
//!
//! Strategy A was picked because:
//!
//! 1. **One trait.** Downstream code (snapshot/restore, pool, multi-agent
//! simulator) does not have to branch on which trait an env implements.
//! There is exactly one `Environment` to reason about.
//! 2. **Cheap default for the common case.** Every discrete env in the repo
//! today gets `type Action = i64;` as a one-line addition. Continuous envs
//! opt in to `Vec<f32>`.
//! 3. **Orthogonal to other trait extensions.** The associated-type approach
//! composes cleanly with planned additions like a `type State` slot for env
//! snapshotting (issue #62 / clone_state / restore_state). Strategy B would
//! have forced snapshot machinery to be implemented twice or behind a third
//! trait.
//! 4. **Generic trainers stay generic.** Discrete trainers add a `<Action =
//! i64>` bound on their `E: Environment` type parameter, which is purely
//! additive.
//!
//! The trade-off: any code that wants to handle *both* discrete and
//! continuous actions polymorphically must either be parametric on
//! `E::Action` or use a sum-type wrapper. Until SAC lands, no such
//! call site exists in Thrust.
//!
//! # Env state snapshots (`type State` / `clone_state` / `restore_state`)
//!
//! The `Environment` trait also exposes a `type State` associated type
//! plus `clone_state` / `restore_state` methods so callers (MCTS-style
//! search, replay tooling) can snapshot env state and roll out
//! hypothetical trajectories without restarting from `reset()`. The
//! determinism contract is per-env: fully deterministic envs (e.g.
//! CartPole, ContinuousLqr) reproduce every subsequent step bit-for-bit
//! after restore; envs that consume internal RNG (Snake food respawn,
//! Pong ball serve) snapshot the simulation step but not the RNG, so
//! reproduction is deterministic only across steps that do not draw
//! from the RNG. Per-env docs spell out the exact guarantee.
/// Core trait for RL environments
/// Result of an environment step
/// Space information for observations and actions
/// Space data types
/// Additional step information
// Game environments
// Re-export game environments for backwards compatibility
pub use ;
// `signaling` depends on `crate::multi_agent`, which is gated behind the
// `training` feature, so its re-export must be gated the same way.
pub use ;
// Training utilities. Gated on the `training` feature because the env
// pool only ships when the trainers are built.