mt-lang 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/docs/index.html +4 -3
  3. data/lib/milk_tea/base.rb +1 -1
  4. data/std/asset_pack.mt +267 -0
  5. data/std/async/libuv_runtime.mt +539 -0
  6. data/std/async/mailbox.mt +191 -0
  7. data/std/async/runtime.mt +87 -0
  8. data/std/async.mt +87 -0
  9. data/std/base64.mt +185 -0
  10. data/std/behavior_tree.mt +396 -0
  11. data/std/binary.mt +314 -0
  12. data/std/binary_heap.mt +157 -0
  13. data/std/bitset.mt +239 -0
  14. data/std/box2d.mt +535 -0
  15. data/std/bytes.mt +46 -0
  16. data/std/c/box2d.mt +1254 -0
  17. data/std/c/cgltf.mt +647 -0
  18. data/std/c/cjson.mt +106 -0
  19. data/std/c/crypto.mt +11 -0
  20. data/std/c/crypto_support.h +51 -0
  21. data/std/c/ctype.mt +19 -0
  22. data/std/c/ctype_bindgen.h +29 -0
  23. data/std/c/curl.mt +1223 -0
  24. data/std/c/enet.mt +473 -0
  25. data/std/c/errno.mt +41 -0
  26. data/std/c/errno_bindgen.h +53 -0
  27. data/std/c/flecs.mt +2945 -0
  28. data/std/c/fs.linux.mt +43 -0
  29. data/std/c/fs.windows.mt +43 -0
  30. data/std/c/fs_support.h +954 -0
  31. data/std/c/gl.mt +2065 -0
  32. data/std/c/gl_registry_helpers.h +10748 -0
  33. data/std/c/glfw.mt +499 -0
  34. data/std/c/libc.mt +167 -0
  35. data/std/c/libuv.mt +1491 -0
  36. data/std/c/math.mt +22 -0
  37. data/std/c/math_bindgen.h +31 -0
  38. data/std/c/miniaudio.mt +3420 -0
  39. data/std/c/pcre2.mt +735 -0
  40. data/std/c/process.mt +58 -0
  41. data/std/c/process_support.h +1147 -0
  42. data/std/c/raygui.mt +1602 -0
  43. data/std/c/raylib.mt +1245 -0
  44. data/std/c/raymath.mt +163 -0
  45. data/std/c/rlgl.mt +434 -0
  46. data/std/c/rpng.mt +60 -0
  47. data/std/c/rres.mt +187 -0
  48. data/std/c/sdl3.mt +4132 -0
  49. data/std/c/sqlite3.mt +951 -0
  50. data/std/c/stb_image.mt +52 -0
  51. data/std/c/stb_image_resize2.mt +128 -0
  52. data/std/c/stb_image_write.mt +19 -0
  53. data/std/c/stb_rect_pack.mt +38 -0
  54. data/std/c/stb_truetype.mt +175 -0
  55. data/std/c/stb_vorbis.mt +31 -0
  56. data/std/c/stdio.mt +90 -0
  57. data/std/c/steamworks.h +5769 -0
  58. data/std/c/steamworks.mt +4771 -0
  59. data/std/c/string.mt +16 -0
  60. data/std/c/string_bindgen.h +36 -0
  61. data/std/c/sync.mt +33 -0
  62. data/std/c/sync_support.h +219 -0
  63. data/std/c/terminal.mt +24 -0
  64. data/std/c/terminal_support.h +408 -0
  65. data/std/c/time.mt +26 -0
  66. data/std/c/tls.mt +24 -0
  67. data/std/c/tls_support.h +626 -0
  68. data/std/c/tracy.mt +53 -0
  69. data/std/c/zlib.mt +20 -0
  70. data/std/c/zlib_support.h +239 -0
  71. data/std/c/zstd.mt +231 -0
  72. data/std/cell.mt +60 -0
  73. data/std/cgltf.mt +115 -0
  74. data/std/cjson.mt +90 -0
  75. data/std/cli.mt +768 -0
  76. data/std/cookie.mt +198 -0
  77. data/std/counter.mt +160 -0
  78. data/std/crypto.mt +74 -0
  79. data/std/cstring.mt +13 -0
  80. data/std/ctype.mt +52 -0
  81. data/std/curl/runtime.mt +261 -0
  82. data/std/curl.mt +38 -0
  83. data/std/deque.mt +348 -0
  84. data/std/encoding.mt +93 -0
  85. data/std/enet.mt +133 -0
  86. data/std/env.mt +41 -0
  87. data/std/errno.mt +47 -0
  88. data/std/flecs.mt +978 -0
  89. data/std/fmt.mt +271 -0
  90. data/std/fs.linux.mt +696 -0
  91. data/std/fs.windows.mt +711 -0
  92. data/std/fsm.mt +267 -0
  93. data/std/gl.mt +2062 -0
  94. data/std/glfw.mt +471 -0
  95. data/std/goap.mt +342 -0
  96. data/std/graph.mt +521 -0
  97. data/std/gzip.mt +77 -0
  98. data/std/hash.mt +429 -0
  99. data/std/http/server.mt +810 -0
  100. data/std/http.mt +1227 -0
  101. data/std/intern.mt +53 -0
  102. data/std/jobs.mt +288 -0
  103. data/std/json.mt +627 -0
  104. data/std/libc.mt +34 -0
  105. data/std/libuv.mt +554 -0
  106. data/std/linear_algebra.mt +243 -0
  107. data/std/linked_map.mt +372 -0
  108. data/std/linked_map_view.mt +49 -0
  109. data/std/linked_set.mt +117 -0
  110. data/std/log.mt +69 -0
  111. data/std/map.mt +418 -0
  112. data/std/math.mt +24 -0
  113. data/std/mem/arena.mt +137 -0
  114. data/std/mem/endian.mt +51 -0
  115. data/std/mem/heap.mt +298 -0
  116. data/std/mem/pool.mt +164 -0
  117. data/std/mem/stack.mt +47 -0
  118. data/std/mem/tracking.mt +119 -0
  119. data/std/miniaudio.mt +1299 -0
  120. data/std/multiset.mt +191 -0
  121. data/std/net/channel.mt +727 -0
  122. data/std/net/clock.mt +237 -0
  123. data/std/net/discovery.mt +277 -0
  124. data/std/net/lobby.mt +813 -0
  125. data/std/net/manager.mt +539 -0
  126. data/std/net/mux.mt +839 -0
  127. data/std/net/nat.mt +122 -0
  128. data/std/net/packet.mt +219 -0
  129. data/std/net/punch.mt +162 -0
  130. data/std/net/rpc.mt +119 -0
  131. data/std/net/session.mt +1157 -0
  132. data/std/net/stun.mt +252 -0
  133. data/std/net/sync.mt +183 -0
  134. data/std/net/turn.mt +459 -0
  135. data/std/net.mt +2944 -0
  136. data/std/oauth2.mt +408 -0
  137. data/std/option.mt +51 -0
  138. data/std/ordered_map.mt +497 -0
  139. data/std/ordered_set.mt +348 -0
  140. data/std/path.mt +368 -0
  141. data/std/pcre2/runtime.mt +35 -0
  142. data/std/pcre2.mt +78 -0
  143. data/std/priority_queue.mt +55 -0
  144. data/std/process.mt +837 -0
  145. data/std/queue.mt +55 -0
  146. data/std/random.mt +146 -0
  147. data/std/raygui.mt +99 -0
  148. data/std/raylib/debug_console.mt +71 -0
  149. data/std/raylib/easing.mt +388 -0
  150. data/std/raylib/packed_assets.mt +255 -0
  151. data/std/raylib/runtime.mt +30 -0
  152. data/std/raylib/tracy_gpu.mt +37 -0
  153. data/std/raylib.mt +1510 -0
  154. data/std/raymath.mt +153 -0
  155. data/std/result.mt +89 -0
  156. data/std/rlgl.mt +268 -0
  157. data/std/rpng.mt +46 -0
  158. data/std/rres.mt +36 -0
  159. data/std/sdl3/runtime.mt +54 -0
  160. data/std/sdl3.mt +1731 -0
  161. data/std/serialize.mt +68 -0
  162. data/std/set.mt +124 -0
  163. data/std/spatial.mt +176 -0
  164. data/std/sqlite3.mt +151 -0
  165. data/std/stack.mt +55 -0
  166. data/std/stb_image.mt +47 -0
  167. data/std/stb_image_resize2.mt +41 -0
  168. data/std/stb_image_write.mt +17 -0
  169. data/std/stb_rect_pack.mt +15 -0
  170. data/std/stb_truetype.mt +77 -0
  171. data/std/stb_vorbis.mt +16 -0
  172. data/std/stdio.mt +88 -0
  173. data/std/steamworks.mt +1542 -0
  174. data/std/str.mt +293 -0
  175. data/std/string.mt +234 -0
  176. data/std/sync.mt +194 -0
  177. data/std/tar.mt +704 -0
  178. data/std/terminal.mt +1002 -0
  179. data/std/testing.mt +266 -0
  180. data/std/thread.mt +120 -0
  181. data/std/time.mt +105 -0
  182. data/std/tls.mt +616 -0
  183. data/std/toml.mt +1310 -0
  184. data/std/tracy.mt +42 -0
  185. data/std/uri.mt +118 -0
  186. data/std/url.mt +372 -0
  187. data/std/vec.mt +433 -0
  188. data/std/zstd.mt +94 -0
  189. metadata +187 -2
data/std/goap.mt ADDED
@@ -0,0 +1,342 @@
1
+ import std.vec as vec
2
+
3
+ public enum PlanningStatus: ubyte
4
+ found = 0
5
+ not_found = 1
6
+ iteration_limit = 2
7
+
8
+ public struct Action[World, Context]:
9
+ name: str
10
+ precondition: fn(context: ptr[Context], world: World) -> bool
11
+ apply: fn(context: ptr[Context], world: World) -> World
12
+ cost: fn(context: ptr[Context], world: World) -> float
13
+
14
+ public struct PlanStep:
15
+ action_index: ptr_uint
16
+ action_name: str
17
+
18
+ public struct Plan[World]:
19
+ steps: vec.Vec[PlanStep]
20
+ total_cost: float
21
+ final_world: World
22
+
23
+ public struct PlanningResult[World]:
24
+ status: PlanningStatus
25
+ plan: Option[Plan[World]]
26
+ iterations: ptr_uint
27
+ expanded_nodes: ptr_uint
28
+
29
+ public struct Planner[World, Goal, Context]:
30
+ actions: vec.Vec[Action[World, Context]]
31
+ is_goal: fn(context: ptr[Context], world: World, goal: Goal) -> bool
32
+ heuristic: fn(context: ptr[Context], world: World, goal: Goal) -> float
33
+ worlds_equal: fn(left: World, right: World) -> bool
34
+ max_iterations: ptr_uint
35
+
36
+ struct SearchNode[World]:
37
+ world: World
38
+ parent_index: ptr_uint
39
+ has_parent: bool
40
+ action_index: ptr_uint
41
+ cost_so_far: float
42
+ closed: bool
43
+
44
+
45
+ function find_node_index[World, Goal, Context](
46
+ planner: ref[Planner[World, Goal, Context]],
47
+ nodes: ref[vec.Vec[SearchNode[World]]],
48
+ world: World
49
+ ) -> Option[ptr_uint]:
50
+ var index: ptr_uint = 0
51
+ for entry in nodes:
52
+ unsafe:
53
+ if planner.worlds_equal(read(entry).world, world):
54
+ return Option[ptr_uint].some(value = index)
55
+ index += 1
56
+
57
+ return Option[ptr_uint].none
58
+
59
+
60
+ function open_list_contains(open_list: ref[vec.Vec[ptr_uint]], node_index: ptr_uint) -> bool:
61
+ for entry in open_list:
62
+ unsafe:
63
+ if read(entry) == node_index:
64
+ return true
65
+
66
+ return false
67
+
68
+
69
+ function choose_best_open[World, Goal, Context](
70
+ planner: ref[Planner[World, Goal, Context]],
71
+ nodes: ref[vec.Vec[SearchNode[World]]],
72
+ open_list: ref[vec.Vec[ptr_uint]],
73
+ context: ref[Context],
74
+ goal: Goal
75
+ ) -> Option[ptr_uint]:
76
+ var best_open_index: ptr_uint = 0
77
+ var best_score: float = 0.0
78
+ var saw_candidate = false
79
+
80
+ var open_index: ptr_uint = 0
81
+ for entry in open_list:
82
+ unsafe:
83
+ let node_index = read(entry)
84
+ let node_ptr = nodes.get(node_index) else:
85
+ continue
86
+
87
+ let node = read(node_ptr)
88
+ if node.closed:
89
+ open_index += 1
90
+ continue
91
+
92
+ let score = node.cost_so_far + planner.heuristic(ptr_of(context), node.world, goal)
93
+ if not saw_candidate or score < best_score:
94
+ best_score = score
95
+ best_open_index = open_index
96
+ saw_candidate = true
97
+ open_index += 1
98
+
99
+ if not saw_candidate:
100
+ return Option[ptr_uint].none
101
+
102
+ return Option[ptr_uint].some(value = best_open_index)
103
+
104
+
105
+ function build_plan[World, Goal, Context](
106
+ planner: ref[Planner[World, Goal, Context]],
107
+ nodes: ref[vec.Vec[SearchNode[World]]],
108
+ goal_index: ptr_uint
109
+ ) -> Plan[World]:
110
+ let goal_node_ptr = nodes.get(goal_index) else:
111
+ fatal(c"goap.build_plan missing goal node")
112
+
113
+ unsafe:
114
+ let goal_node = read(goal_node_ptr)
115
+ var reverse_steps = vec.Vec[PlanStep].create()
116
+ var current_index = goal_index
117
+ while true:
118
+ let current_ptr = nodes.get(current_index) else:
119
+ fatal(c"goap.build_plan missing current node")
120
+
121
+ let current = read(current_ptr)
122
+ if not current.has_parent:
123
+ break
124
+
125
+ let action_ptr = planner.actions.get(current.action_index) else:
126
+ fatal(c"goap.build_plan missing action")
127
+
128
+ reverse_steps.push(
129
+ PlanStep(
130
+ action_index = current.action_index,
131
+ action_name = read(action_ptr).name
132
+ )
133
+ )
134
+ current_index = current.parent_index
135
+
136
+ var plan = Plan[World](
137
+ steps = vec.Vec[PlanStep].with_capacity(reverse_steps.len()),
138
+ total_cost = goal_node.cost_so_far,
139
+ final_world = goal_node.world
140
+ )
141
+
142
+ while true:
143
+ let step = reverse_steps.pop() else:
144
+ break
145
+
146
+ plan.steps.push(step)
147
+
148
+ reverse_steps.release()
149
+ return plan
150
+
151
+
152
+ extending Action[World, Context]:
153
+ public static function create(
154
+ name: str,
155
+ precondition: fn(context: ptr[Context], world: World) -> bool,
156
+ apply: fn(context: ptr[Context], world: World) -> World,
157
+ cost: fn(context: ptr[Context], world: World) -> float
158
+ ) -> Action[World, Context]:
159
+ return Action[World, Context](
160
+ name = name,
161
+ precondition = precondition,
162
+ apply = apply,
163
+ cost = cost
164
+ )
165
+
166
+
167
+ extending Plan[World]:
168
+ public editable function release() -> void:
169
+ this.steps.release()
170
+
171
+
172
+ public function step_count() -> ptr_uint:
173
+ return this.steps.len()
174
+
175
+
176
+ public function iter() -> vec.Iter[PlanStep]:
177
+ return this.steps.iter()
178
+
179
+
180
+ public function step(index: ptr_uint) -> ptr[PlanStep]?:
181
+ return this.steps.get(index)
182
+
183
+
184
+ extending PlanningResult[World]:
185
+ public editable function release() -> void:
186
+ match this.plan:
187
+ Option.none:
188
+ pass
189
+ Option.some as payload:
190
+ var plan = payload.value
191
+ plan.release()
192
+ this.plan = Option[Plan[World]].none
193
+
194
+
195
+ public function has_plan() -> bool:
196
+ match this.plan:
197
+ Option.none:
198
+ return false
199
+ Option.some:
200
+ return true
201
+
202
+
203
+ extending Planner[World, Goal, Context]:
204
+ public static function create(
205
+ is_goal: fn(context: ptr[Context], world: World, goal: Goal) -> bool,
206
+ heuristic: fn(context: ptr[Context], world: World, goal: Goal) -> float,
207
+ worlds_equal: fn(left: World, right: World) -> bool
208
+ ) -> Planner[World, Goal, Context]:
209
+ return Planner[World, Goal, Context](
210
+ actions = vec.Vec[Action[World, Context]].create(),
211
+ is_goal = is_goal,
212
+ heuristic = heuristic,
213
+ worlds_equal = worlds_equal,
214
+ max_iterations = 256
215
+ )
216
+
217
+
218
+ public editable function release() -> void:
219
+ this.actions.release()
220
+
221
+
222
+ public function action_count() -> ptr_uint:
223
+ return this.actions.len()
224
+
225
+
226
+ public editable function add_action(action: Action[World, Context]) -> void:
227
+ this.actions.push(action)
228
+
229
+
230
+ public editable function set_max_iterations(limit: ptr_uint) -> void:
231
+ this.max_iterations = limit
232
+
233
+
234
+ public editable function plan(context: ref[Context], initial_world: World, goal: Goal) -> PlanningResult[World]:
235
+ var nodes = vec.Vec[SearchNode[World]].create()
236
+ defer nodes.release()
237
+ var open_list = vec.Vec[ptr_uint].create()
238
+ defer open_list.release()
239
+
240
+ nodes.push(
241
+ SearchNode[World](
242
+ world = initial_world,
243
+ parent_index = 0,
244
+ has_parent = false,
245
+ action_index = 0,
246
+ cost_so_far = 0.0,
247
+ closed = false
248
+ )
249
+ )
250
+ open_list.push(0)
251
+
252
+ var iterations: ptr_uint = 0
253
+ var expanded_nodes: ptr_uint = 0
254
+
255
+ while not open_list.is_empty():
256
+ if iterations >= this.max_iterations:
257
+ return PlanningResult[World](
258
+ status = PlanningStatus.iteration_limit,
259
+ plan = Option[Plan[World]].none,
260
+ iterations = iterations,
261
+ expanded_nodes = expanded_nodes
262
+ )
263
+
264
+ let best_open_index = choose_best_open(ref_of(this), ref_of(nodes), ref_of(open_list), context, goal) else:
265
+ break
266
+
267
+ let current_index_option = open_list.swap_remove(best_open_index)
268
+ match current_index_option:
269
+ Option.none:
270
+ break
271
+ Option.some as current_payload:
272
+ iterations += 1
273
+ let current_index = current_payload.value
274
+ let current_ptr = nodes.get(current_index) else:
275
+ continue
276
+
277
+ unsafe:
278
+ if read(current_ptr).closed:
279
+ continue
280
+
281
+ if this.is_goal(ptr_of(context), read(current_ptr).world, goal):
282
+ let plan = build_plan(ref_of(this), ref_of(nodes), current_index)
283
+ return PlanningResult[World](
284
+ status = PlanningStatus.found,
285
+ plan = Option[Plan[World]].some(value = plan),
286
+ iterations = iterations,
287
+ expanded_nodes = expanded_nodes
288
+ )
289
+
290
+ read(current_ptr).closed = true
291
+
292
+ expanded_nodes += 1
293
+
294
+ var action_index: ptr_uint = 0
295
+ for action_ptr in this.actions:
296
+ unsafe:
297
+ let action = read(action_ptr)
298
+ let current_node = read(current_ptr)
299
+ if not action.precondition(ptr_of(context), current_node.world):
300
+ action_index += 1
301
+ continue
302
+
303
+ let next_world = action.apply(ptr_of(context), current_node.world)
304
+ let next_cost = current_node.cost_so_far + action.cost(ptr_of(context), current_node.world)
305
+ let existing_index = find_node_index(ref_of(this), ref_of(nodes), next_world)
306
+ match existing_index:
307
+ Option.none:
308
+ let next_node_index = nodes.len()
309
+ nodes.push(
310
+ SearchNode[World](
311
+ world = next_world,
312
+ parent_index = current_index,
313
+ has_parent = true,
314
+ action_index = action_index,
315
+ cost_so_far = next_cost,
316
+ closed = false
317
+ )
318
+ )
319
+ open_list.push(next_node_index)
320
+
321
+ Option.some as existing_payload:
322
+ let existing_ptr = nodes.get(existing_payload.value) else:
323
+ action_index += 1
324
+ continue
325
+
326
+ if next_cost < unsafe: read(existing_ptr).cost_so_far:
327
+ unsafe:
328
+ read(existing_ptr).parent_index = current_index
329
+ read(existing_ptr).has_parent = true
330
+ read(existing_ptr).action_index = action_index
331
+ read(existing_ptr).cost_so_far = next_cost
332
+ read(existing_ptr).closed = false
333
+ if not open_list_contains(ref_of(open_list), existing_payload.value):
334
+ open_list.push(existing_payload.value)
335
+ action_index += 1
336
+
337
+ return PlanningResult[World](
338
+ status = PlanningStatus.not_found,
339
+ plan = Option[Plan[World]].none,
340
+ iterations = iterations,
341
+ expanded_nodes = expanded_nodes
342
+ )