plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
774e6d8
— Peter John
2026-10-26T12:11:35+05:30
docs(plans): value types are a single-constructor value enum, not a struct keyword
docs/plans/2026-10-26-game-engine.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
What the user decided:
|
|
12
12
|
- macroquad is the host, and Plum handles game logic plus rendering.
|
|
13
|
-
- `
|
|
13
|
+
- Value types (user: a `value enum` with a single constructor, not a new `struct` keyword) and simd128 are wanted.
|
|
14
14
|
- Port KaM, with no scripting engine and simpler rules but the same animations and sounds.
|
|
15
15
|
- It must work in the browser, as the Rust version does today.
|
|
16
16
|
|
|
@@ -36,15 +36,15 @@ Survey of `../kam_macroquad`:
|
|
|
36
36
|
- Input: `isKeyDown(k: Key)`, `isKeyPressed`, `mousePos() -> Vec2`, `isMouseDown(b: MouseButton)` and `mouseWheel() -> Float`.
|
|
37
37
|
- Audio: `playSound(id: Int, x, y: Float)` (positional, as in KaM), `playMusic(id)` and `stopMusic()`.
|
|
38
38
|
- Assets, as host lookups by name: `atlasId`, `animFrames(unitKind, action, dir) -> List[Int]` (frame indices, copied once at load) and `animStep`, `loadMap(name) -> MapData`, which copies terrain into Plum `Array[Int]`s once.
|
|
39
|
-
- `Color` and `Vec2` are
|
|
39
|
+
- `Color` and `Vec2` are value enums flattened across the boundary. `Key` and `MouseButton` are enums matching macroquad's codes.
|
|
40
40
|
4. **Language additions this port needs** (beyond the Zig-generics plan and items 5–7 below):
|
|
41
41
|
- **Unboxed typed arrays.** With copies per type, `Array[Int]` and `Array[Float]` lower to native `array (mut i64)` and `array (mut f64)`. These are for tile grids, fog of war, passability and path costs. Add `Array.filled(n, v)` and a 2D index helper.
|
|
42
42
|
- **Collections in std:** `Set[T]`, `Deque[T]` (ring buffer) and `Heap[T]` (binary min-heap with a key fn, for A*), all Plum code over `Array`.
|
|
43
43
|
- **Constants:** large top-level constant tables must parse and be usable in expressions. A probe file with `LIMIT = 10` followed by a `type` failed to parse (cause not yet confirmed), and the notes record a SCREAMING_CASE constant gotcha. The fix needs tests with 1k-entry tables.
|
|
44
44
|
- **Seeded RNG** (`Random(seed: Int)` with xorshift/PCG) for deterministic AI and simulation.
|
|
45
45
|
- Lazy iteration is deferred. Hot loops use `for … range`, and it's revisited only if profiling shows `map`/`filter` allocation in `update`.
|
|
46
|
-
5. **Value
|
|
47
|
-
6. **Duck-typed operators** on
|
|
46
|
+
5. **Value enums** (`value enum Vec2 = | Vec2(x: Float, y: Float)`, `Color`, `TilePos`). Exactly one constructor named like the type, fields only `Int`/`Float`/`Bool` or other value enums (no `Str`/`List`, no recursion). Lowering: flattened locals and params, multi-value returns, copy semantics and in-place field assignment. They are boxed only inside `List`/`Map`/`Try`, and by then they belong to a generic copy, so a `List[Vec2]` copy stores them as GC structs.
|
|
47
|
+
6. **Duck-typed operators** on value enums (`add`/`sub`/`mul`/`neg`/`eq`): `pos + dir * speed`.
|
|
48
48
|
7. **SIMD (late):** `f32x4` (wasm v128) and `Mat4`/`Vec4` in `plum-std/Math.plum`. KaM is 2D, so this is low priority for the port and kept for future 3D work.
|
|
49
49
|
8. **Port scope (simplified KaM):**
|
|
50
50
|
- Kept:
|
|
@@ -78,7 +78,7 @@ Success criteria:
|
|
|
78
78
|
```mermaid
|
|
79
79
|
flowchart LR
|
|
80
80
|
L1[typed arrays + collections + consts + RNG]
|
|
81
|
-
L2[
|
|
81
|
+
L2[value enums]
|
|
82
82
|
L3[duck-typed operators]
|
|
83
83
|
H1[plum-game host native + Game.plum]
|
|
84
84
|
H2[browser bridge]
|
|
@@ -116,13 +116,13 @@ Tests:
|
|
|
116
116
|
- `const_table_1000_entries`;
|
|
117
117
|
- `random_seed_deterministic` (same seed gives the same first 100 values).
|
|
118
118
|
|
|
119
|
-
### L2
|
|
120
|
-
Grammar `
|
|
121
|
-
- `
|
|
122
|
-
- `
|
|
123
|
-
- `
|
|
124
|
-
- `
|
|
125
|
-
- `
|
|
119
|
+
### L2 value enums (`value enum`, single constructor)
|
|
120
|
+
Grammar: a `value` modifier on `enum`, with checker errors for more than one constructor (`value enum X must have exactly one constructor`) and for non-value fields (`value enum field 'name' must be Int, Float, Bool or a value enum`). Flattened lowering, multi-value returns, copy semantics, field assignment, recursion rejected. Tests:
|
|
121
|
+
- `value_copy_semantics`;
|
|
122
|
+
- `value_multi_value_return`;
|
|
123
|
+
- `value_in_list_roundtrip`;
|
|
124
|
+
- `value_eq_fieldwise`;
|
|
125
|
+
- `value_enum_two_constructors_rejected`; `value_enum_str_field_rejected`.
|
|
126
126
|
|
|
127
127
|
### L3 duck-typed operators
|
|
128
128
|
`a + b` → `a.add(b)` and so on, resolved per instantiation. Tests:
|
|
@@ -148,7 +148,7 @@ Check: a demo scene (sprites, sound, input) runs in Chrome and Firefox. Playwrig
|
|
|
148
148
|
Load a KaM map via the host, terrain into `Array[Int]`, tile rendering, camera pan/zoom, minimap. Check: renders the same as the Rust version on 2 maps (screenshot diff tolerance).
|
|
149
149
|
|
|
150
150
|
### P2 units + animations + sounds
|
|
151
|
-
Unit
|
|
151
|
+
Unit types, directional animation state machine, walk interpolation, selection, positional sounds. Tests: the animation frame sequence for walk dir 3 equals the Rust table, and the sound fires on the step frames.
|
|
152
152
|
|
|
153
153
|
### P3 pathfinding
|
|
154
154
|
A* over passability with `Heap`, path smoothing as in `src/pathfinding.rs` (simplified), unit move orders. Tests: shortest-path length on 5 fixture grids matches the Rust implementation, and 300 units repathing stays under 2 ms per frame (native).
|