@rpgm-tools/neo-angband-core 0.10.0

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 (1183) hide show
  1. package/LICENSE.md +43 -0
  2. package/README.md +80 -0
  3. package/dist/agent/act.d.ts +22 -0
  4. package/dist/agent/act.d.ts.map +1 -0
  5. package/dist/agent/act.js +88 -0
  6. package/dist/agent/act.js.map +1 -0
  7. package/dist/agent/controller.d.ts +34 -0
  8. package/dist/agent/controller.d.ts.map +1 -0
  9. package/dist/agent/controller.js +90 -0
  10. package/dist/agent/controller.js.map +1 -0
  11. package/dist/agent/events.d.ts +27 -0
  12. package/dist/agent/events.d.ts.map +1 -0
  13. package/dist/agent/events.js +31 -0
  14. package/dist/agent/events.js.map +1 -0
  15. package/dist/agent/index.d.ts +17 -0
  16. package/dist/agent/index.d.ts.map +1 -0
  17. package/dist/agent/index.js +15 -0
  18. package/dist/agent/index.js.map +1 -0
  19. package/dist/agent/perceive.d.ts +21 -0
  20. package/dist/agent/perceive.d.ts.map +1 -0
  21. package/dist/agent/perceive.js +386 -0
  22. package/dist/agent/perceive.js.map +1 -0
  23. package/dist/agent/types.d.ts +436 -0
  24. package/dist/agent/types.d.ts.map +1 -0
  25. package/dist/agent/types.js +63 -0
  26. package/dist/agent/types.js.map +1 -0
  27. package/dist/bitflag.d.ts +199 -0
  28. package/dist/bitflag.d.ts.map +1 -0
  29. package/dist/bitflag.js +478 -0
  30. package/dist/bitflag.js.map +1 -0
  31. package/dist/cmd.d.ts +164 -0
  32. package/dist/cmd.d.ts.map +1 -0
  33. package/dist/cmd.js +350 -0
  34. package/dist/cmd.js.map +1 -0
  35. package/dist/color.d.ts +104 -0
  36. package/dist/color.d.ts.map +1 -0
  37. package/dist/color.js +240 -0
  38. package/dist/color.js.map +1 -0
  39. package/dist/combat/brand-slay.d.ts +119 -0
  40. package/dist/combat/brand-slay.d.ts.map +1 -0
  41. package/dist/combat/brand-slay.js +264 -0
  42. package/dist/combat/brand-slay.js.map +1 -0
  43. package/dist/combat/hit.d.ts +198 -0
  44. package/dist/combat/hit.d.ts.map +1 -0
  45. package/dist/combat/hit.js +310 -0
  46. package/dist/combat/hit.js.map +1 -0
  47. package/dist/combat/index.d.ts +15 -0
  48. package/dist/combat/index.d.ts.map +1 -0
  49. package/dist/combat/index.js +15 -0
  50. package/dist/combat/index.js.map +1 -0
  51. package/dist/combat/melee.d.ts +261 -0
  52. package/dist/combat/melee.d.ts.map +1 -0
  53. package/dist/combat/melee.js +402 -0
  54. package/dist/combat/melee.js.map +1 -0
  55. package/dist/combat/mon-melee.d.ts +233 -0
  56. package/dist/combat/mon-melee.d.ts.map +1 -0
  57. package/dist/combat/mon-melee.js +883 -0
  58. package/dist/combat/mon-melee.js.map +1 -0
  59. package/dist/combat/ranged.d.ts +89 -0
  60. package/dist/combat/ranged.d.ts.map +1 -0
  61. package/dist/combat/ranged.js +253 -0
  62. package/dist/combat/ranged.js.map +1 -0
  63. package/dist/constants.d.ts +134 -0
  64. package/dist/constants.d.ts.map +1 -0
  65. package/dist/constants.js +171 -0
  66. package/dist/constants.js.map +1 -0
  67. package/dist/dice.d.ts +91 -0
  68. package/dist/dice.d.ts.map +1 -0
  69. package/dist/dice.js +424 -0
  70. package/dist/dice.js.map +1 -0
  71. package/dist/effects/effect-choice.d.ts +15 -0
  72. package/dist/effects/effect-choice.d.ts.map +1 -0
  73. package/dist/effects/effect-choice.js +18 -0
  74. package/dist/effects/effect-choice.js.map +1 -0
  75. package/dist/effects/effect-info.d.ts +124 -0
  76. package/dist/effects/effect-info.d.ts.map +1 -0
  77. package/dist/effects/effect-info.js +706 -0
  78. package/dist/effects/effect-info.js.map +1 -0
  79. package/dist/effects/effect.d.ts +165 -0
  80. package/dist/effects/effect.d.ts.map +1 -0
  81. package/dist/effects/effect.js +452 -0
  82. package/dist/effects/effect.js.map +1 -0
  83. package/dist/effects/handlers.d.ts +70 -0
  84. package/dist/effects/handlers.d.ts.map +1 -0
  85. package/dist/effects/handlers.js +394 -0
  86. package/dist/effects/handlers.js.map +1 -0
  87. package/dist/effects/interpreter.d.ts +291 -0
  88. package/dist/effects/interpreter.d.ts.map +1 -0
  89. package/dist/effects/interpreter.js +325 -0
  90. package/dist/effects/interpreter.js.map +1 -0
  91. package/dist/events.d.ts +188 -0
  92. package/dist/events.d.ts.map +1 -0
  93. package/dist/events.js +138 -0
  94. package/dist/events.js.map +1 -0
  95. package/dist/expression.d.ts +83 -0
  96. package/dist/expression.d.ts.map +1 -0
  97. package/dist/expression.js +333 -0
  98. package/dist/expression.js.map +1 -0
  99. package/dist/game/cave-cmd.d.ts +195 -0
  100. package/dist/game/cave-cmd.d.ts.map +1 -0
  101. package/dist/game/cave-cmd.js +968 -0
  102. package/dist/game/cave-cmd.js.map +1 -0
  103. package/dist/game/char-sheet.d.ts +189 -0
  104. package/dist/game/char-sheet.d.ts.map +1 -0
  105. package/dist/game/char-sheet.js +381 -0
  106. package/dist/game/char-sheet.js.map +1 -0
  107. package/dist/game/chest.d.ts +94 -0
  108. package/dist/game/chest.d.ts.map +1 -0
  109. package/dist/game/chest.js +267 -0
  110. package/dist/game/chest.js.map +1 -0
  111. package/dist/game/context.d.ts +970 -0
  112. package/dist/game/context.d.ts.map +1 -0
  113. package/dist/game/context.js +353 -0
  114. package/dist/game/context.js.map +1 -0
  115. package/dist/game/curse-tick.d.ts +35 -0
  116. package/dist/game/curse-tick.d.ts.map +1 -0
  117. package/dist/game/curse-tick.js +100 -0
  118. package/dist/game/curse-tick.js.map +1 -0
  119. package/dist/game/describe.d.ts +20 -0
  120. package/dist/game/describe.d.ts.map +1 -0
  121. package/dist/game/describe.js +45 -0
  122. package/dist/game/describe.js.map +1 -0
  123. package/dist/game/display.d.ts +196 -0
  124. package/dist/game/display.d.ts.map +1 -0
  125. package/dist/game/display.js +684 -0
  126. package/dist/game/display.js.map +1 -0
  127. package/dist/game/dump-level.d.ts +37 -0
  128. package/dist/game/dump-level.d.ts.map +1 -0
  129. package/dist/game/dump-level.js +110 -0
  130. package/dist/game/dump-level.js.map +1 -0
  131. package/dist/game/effect-attack.d.ts +36 -0
  132. package/dist/game/effect-attack.d.ts.map +1 -0
  133. package/dist/game/effect-attack.js +694 -0
  134. package/dist/game/effect-attack.js.map +1 -0
  135. package/dist/game/effect-detect.d.ts +34 -0
  136. package/dist/game/effect-detect.d.ts.map +1 -0
  137. package/dist/game/effect-detect.js +456 -0
  138. package/dist/game/effect-detect.js.map +1 -0
  139. package/dist/game/effect-env.d.ts +77 -0
  140. package/dist/game/effect-env.d.ts.map +1 -0
  141. package/dist/game/effect-env.js +166 -0
  142. package/dist/game/effect-env.js.map +1 -0
  143. package/dist/game/effect-game-env.d.ts +76 -0
  144. package/dist/game/effect-game-env.d.ts.map +1 -0
  145. package/dist/game/effect-game-env.js +23 -0
  146. package/dist/game/effect-game-env.js.map +1 -0
  147. package/dist/game/effect-general.d.ts +98 -0
  148. package/dist/game/effect-general.d.ts.map +1 -0
  149. package/dist/game/effect-general.js +914 -0
  150. package/dist/game/effect-general.js.map +1 -0
  151. package/dist/game/effect-item.d.ts +124 -0
  152. package/dist/game/effect-item.d.ts.map +1 -0
  153. package/dist/game/effect-item.js +789 -0
  154. package/dist/game/effect-item.js.map +1 -0
  155. package/dist/game/effect-melee.d.ts +43 -0
  156. package/dist/game/effect-melee.d.ts.map +1 -0
  157. package/dist/game/effect-melee.js +477 -0
  158. package/dist/game/effect-melee.js.map +1 -0
  159. package/dist/game/effect-mon-origin.d.ts +67 -0
  160. package/dist/game/effect-mon-origin.d.ts.map +1 -0
  161. package/dist/game/effect-mon-origin.js +164 -0
  162. package/dist/game/effect-mon-origin.js.map +1 -0
  163. package/dist/game/effect-monster.d.ts +29 -0
  164. package/dist/game/effect-monster.d.ts.map +1 -0
  165. package/dist/game/effect-monster.js +281 -0
  166. package/dist/game/effect-monster.js.map +1 -0
  167. package/dist/game/effect-summon.d.ts +37 -0
  168. package/dist/game/effect-summon.d.ts.map +1 -0
  169. package/dist/game/effect-summon.js +113 -0
  170. package/dist/game/effect-summon.js.map +1 -0
  171. package/dist/game/effect-teleport.d.ts +130 -0
  172. package/dist/game/effect-teleport.d.ts.map +1 -0
  173. package/dist/game/effect-teleport.js +529 -0
  174. package/dist/game/effect-teleport.js.map +1 -0
  175. package/dist/game/effect-terrain.d.ts +91 -0
  176. package/dist/game/effect-terrain.d.ts.map +1 -0
  177. package/dist/game/effect-terrain.js +812 -0
  178. package/dist/game/effect-terrain.js.map +1 -0
  179. package/dist/game/energy.d.ts +45 -0
  180. package/dist/game/energy.d.ts.map +1 -0
  181. package/dist/game/energy.js +51 -0
  182. package/dist/game/energy.js.map +1 -0
  183. package/dist/game/equip-cmp.d.ts +138 -0
  184. package/dist/game/equip-cmp.d.ts.map +1 -0
  185. package/dist/game/equip-cmp.js +363 -0
  186. package/dist/game/equip-cmp.js.map +1 -0
  187. package/dist/game/floor.d.ts +182 -0
  188. package/dist/game/floor.d.ts.map +1 -0
  189. package/dist/game/floor.js +435 -0
  190. package/dist/game/floor.js.map +1 -0
  191. package/dist/game/gear.d.ts +408 -0
  192. package/dist/game/gear.d.ts.map +1 -0
  193. package/dist/game/gear.js +1037 -0
  194. package/dist/game/gear.js.map +1 -0
  195. package/dist/game/harness.d.ts +61 -0
  196. package/dist/game/harness.d.ts.map +1 -0
  197. package/dist/game/harness.js +198 -0
  198. package/dist/game/harness.js.map +1 -0
  199. package/dist/game/history.d.ts +49 -0
  200. package/dist/game/history.d.ts.map +1 -0
  201. package/dist/game/history.js +55 -0
  202. package/dist/game/history.js.map +1 -0
  203. package/dist/game/ignore-cmd.d.ts +42 -0
  204. package/dist/game/ignore-cmd.d.ts.map +1 -0
  205. package/dist/game/ignore-cmd.js +59 -0
  206. package/dist/game/ignore-cmd.js.map +1 -0
  207. package/dist/game/inscription-confirm.d.ts +80 -0
  208. package/dist/game/inscription-confirm.d.ts.map +1 -0
  209. package/dist/game/inscription-confirm.js +95 -0
  210. package/dist/game/inscription-confirm.js.map +1 -0
  211. package/dist/game/known.d.ts +297 -0
  212. package/dist/game/known.d.ts.map +1 -0
  213. package/dist/game/known.js +849 -0
  214. package/dist/game/known.js.map +1 -0
  215. package/dist/game/loop.d.ts +139 -0
  216. package/dist/game/loop.d.ts.map +1 -0
  217. package/dist/game/loop.js +631 -0
  218. package/dist/game/loop.js.map +1 -0
  219. package/dist/game/lore-color.d.ts +25 -0
  220. package/dist/game/lore-color.d.ts.map +1 -0
  221. package/dist/game/lore-color.js +95 -0
  222. package/dist/game/lore-color.js.map +1 -0
  223. package/dist/game/mon-cast.d.ts +150 -0
  224. package/dist/game/mon-cast.d.ts.map +1 -0
  225. package/dist/game/mon-cast.js +301 -0
  226. package/dist/game/mon-cast.js.map +1 -0
  227. package/dist/game/mon-cmd.d.ts +51 -0
  228. package/dist/game/mon-cmd.d.ts.map +1 -0
  229. package/dist/game/mon-cmd.js +670 -0
  230. package/dist/game/mon-cmd.js.map +1 -0
  231. package/dist/game/mon-death.d.ts +143 -0
  232. package/dist/game/mon-death.d.ts.map +1 -0
  233. package/dist/game/mon-death.js +328 -0
  234. package/dist/game/mon-death.js.map +1 -0
  235. package/dist/game/mon-group.d.ts +81 -0
  236. package/dist/game/mon-group.d.ts.map +1 -0
  237. package/dist/game/mon-group.js +323 -0
  238. package/dist/game/mon-group.js.map +1 -0
  239. package/dist/game/mon-list.d.ts +85 -0
  240. package/dist/game/mon-list.d.ts.map +1 -0
  241. package/dist/game/mon-list.js +154 -0
  242. package/dist/game/mon-list.js.map +1 -0
  243. package/dist/game/mon-message.d.ts +100 -0
  244. package/dist/game/mon-message.d.ts.map +1 -0
  245. package/dist/game/mon-message.js +336 -0
  246. package/dist/game/mon-message.js.map +1 -0
  247. package/dist/game/mon-place.d.ts +226 -0
  248. package/dist/game/mon-place.d.ts.map +1 -0
  249. package/dist/game/mon-place.js +642 -0
  250. package/dist/game/mon-place.js.map +1 -0
  251. package/dist/game/mon-ranged.d.ts +87 -0
  252. package/dist/game/mon-ranged.d.ts.map +1 -0
  253. package/dist/game/mon-ranged.js +353 -0
  254. package/dist/game/mon-ranged.js.map +1 -0
  255. package/dist/game/mon-shape.d.ts +43 -0
  256. package/dist/game/mon-shape.d.ts.map +1 -0
  257. package/dist/game/mon-shape.js +115 -0
  258. package/dist/game/mon-shape.js.map +1 -0
  259. package/dist/game/mon-side.d.ts +63 -0
  260. package/dist/game/mon-side.d.ts.map +1 -0
  261. package/dist/game/mon-side.js +403 -0
  262. package/dist/game/mon-side.js.map +1 -0
  263. package/dist/game/monster-turn.d.ts +195 -0
  264. package/dist/game/monster-turn.d.ts.map +1 -0
  265. package/dist/game/monster-turn.js +1560 -0
  266. package/dist/game/monster-turn.js.map +1 -0
  267. package/dist/game/obj-cmd.d.ts +453 -0
  268. package/dist/game/obj-cmd.d.ts.map +1 -0
  269. package/dist/game/obj-cmd.js +1530 -0
  270. package/dist/game/obj-cmd.js.map +1 -0
  271. package/dist/game/obj-list.d.ts +92 -0
  272. package/dist/game/obj-list.d.ts.map +1 -0
  273. package/dist/game/obj-list.js +251 -0
  274. package/dist/game/obj-list.js.map +1 -0
  275. package/dist/game/object-inspect.d.ts +37 -0
  276. package/dist/game/object-inspect.d.ts.map +1 -0
  277. package/dist/game/object-inspect.js +106 -0
  278. package/dist/game/object-inspect.js.map +1 -0
  279. package/dist/game/pickup.d.ts +126 -0
  280. package/dist/game/pickup.d.ts.map +1 -0
  281. package/dist/game/pickup.js +367 -0
  282. package/dist/game/pickup.js.map +1 -0
  283. package/dist/game/player-path.d.ts +133 -0
  284. package/dist/game/player-path.d.ts.map +1 -0
  285. package/dist/game/player-path.js +1268 -0
  286. package/dist/game/player-path.js.map +1 -0
  287. package/dist/game/player-side.d.ts +59 -0
  288. package/dist/game/player-side.d.ts.map +1 -0
  289. package/dist/game/player-side.js +506 -0
  290. package/dist/game/player-side.js.map +1 -0
  291. package/dist/game/player-turn.d.ts +161 -0
  292. package/dist/game/player-turn.d.ts.map +1 -0
  293. package/dist/game/player-turn.js +739 -0
  294. package/dist/game/player-turn.js.map +1 -0
  295. package/dist/game/project-cast.d.ts +268 -0
  296. package/dist/game/project-cast.d.ts.map +1 -0
  297. package/dist/game/project-cast.js +496 -0
  298. package/dist/game/project-cast.js.map +1 -0
  299. package/dist/game/project-feat.d.ts +47 -0
  300. package/dist/game/project-feat.d.ts.map +1 -0
  301. package/dist/game/project-feat.js +350 -0
  302. package/dist/game/project-feat.js.map +1 -0
  303. package/dist/game/project-monster.d.ts +106 -0
  304. package/dist/game/project-monster.d.ts.map +1 -0
  305. package/dist/game/project-monster.js +272 -0
  306. package/dist/game/project-monster.js.map +1 -0
  307. package/dist/game/project-obj.d.ts +60 -0
  308. package/dist/game/project-obj.d.ts.map +1 -0
  309. package/dist/game/project-obj.js +245 -0
  310. package/dist/game/project-obj.js.map +1 -0
  311. package/dist/game/project-player.d.ts +120 -0
  312. package/dist/game/project-player.d.ts.map +1 -0
  313. package/dist/game/project-player.js +108 -0
  314. package/dist/game/project-player.js.map +1 -0
  315. package/dist/game/quest.d.ts +101 -0
  316. package/dist/game/quest.d.ts.map +1 -0
  317. package/dist/game/quest.js +192 -0
  318. package/dist/game/quest.js.map +1 -0
  319. package/dist/game/ranged-cmd.d.ts +32 -0
  320. package/dist/game/ranged-cmd.d.ts.map +1 -0
  321. package/dist/game/ranged-cmd.js +372 -0
  322. package/dist/game/ranged-cmd.js.map +1 -0
  323. package/dist/game/scheduler.d.ts +47 -0
  324. package/dist/game/scheduler.d.ts.map +1 -0
  325. package/dist/game/scheduler.js +141 -0
  326. package/dist/game/scheduler.js.map +1 -0
  327. package/dist/game/spell-cmd.d.ts +104 -0
  328. package/dist/game/spell-cmd.d.ts.map +1 -0
  329. package/dist/game/spell-cmd.js +320 -0
  330. package/dist/game/spell-cmd.js.map +1 -0
  331. package/dist/game/spoil.d.ts +28 -0
  332. package/dist/game/spoil.d.ts.map +1 -0
  333. package/dist/game/spoil.js +435 -0
  334. package/dist/game/spoil.js.map +1 -0
  335. package/dist/game/steal.d.ts +35 -0
  336. package/dist/game/steal.d.ts.map +1 -0
  337. package/dist/game/steal.js +145 -0
  338. package/dist/game/steal.js.map +1 -0
  339. package/dist/game/take-hit-hooks.d.ts +52 -0
  340. package/dist/game/take-hit-hooks.d.ts.map +1 -0
  341. package/dist/game/take-hit-hooks.js +127 -0
  342. package/dist/game/take-hit-hooks.js.map +1 -0
  343. package/dist/game/target-loop.d.ts +119 -0
  344. package/dist/game/target-loop.d.ts.map +1 -0
  345. package/dist/game/target-loop.js +408 -0
  346. package/dist/game/target-loop.js.map +1 -0
  347. package/dist/game/target.d.ts +133 -0
  348. package/dist/game/target.d.ts.map +1 -0
  349. package/dist/game/target.js +353 -0
  350. package/dist/game/target.js.map +1 -0
  351. package/dist/game/thrust.d.ts +37 -0
  352. package/dist/game/thrust.d.ts.map +1 -0
  353. package/dist/game/thrust.js +155 -0
  354. package/dist/game/thrust.js.map +1 -0
  355. package/dist/game/trap.d.ts +218 -0
  356. package/dist/game/trap.d.ts.map +1 -0
  357. package/dist/game/trap.js +618 -0
  358. package/dist/game/trap.js.map +1 -0
  359. package/dist/game/ui-entry.d.ts +282 -0
  360. package/dist/game/ui-entry.d.ts.map +1 -0
  361. package/dist/game/ui-entry.js +1838 -0
  362. package/dist/game/ui-entry.js.map +1 -0
  363. package/dist/game/wizard.d.ts +654 -0
  364. package/dist/game/wizard.d.ts.map +1 -0
  365. package/dist/game/wizard.js +1323 -0
  366. package/dist/game/wizard.js.map +1 -0
  367. package/dist/game/world.d.ts +183 -0
  368. package/dist/game/world.d.ts.map +1 -0
  369. package/dist/game/world.js +685 -0
  370. package/dist/game/world.js.map +1 -0
  371. package/dist/gen/cave.d.ts +247 -0
  372. package/dist/gen/cave.d.ts.map +1 -0
  373. package/dist/gen/cave.js +2406 -0
  374. package/dist/gen/cave.js.map +1 -0
  375. package/dist/gen/gen-monster.d.ts +151 -0
  376. package/dist/gen/gen-monster.d.ts.map +1 -0
  377. package/dist/gen/gen-monster.js +473 -0
  378. package/dist/gen/gen-monster.js.map +1 -0
  379. package/dist/gen/generate.d.ts +240 -0
  380. package/dist/gen/generate.d.ts.map +1 -0
  381. package/dist/gen/generate.js +358 -0
  382. package/dist/gen/generate.js.map +1 -0
  383. package/dist/gen/room.d.ts +160 -0
  384. package/dist/gen/room.d.ts.map +1 -0
  385. package/dist/gen/room.js +1910 -0
  386. package/dist/gen/room.js.map +1 -0
  387. package/dist/gen/util.d.ts +466 -0
  388. package/dist/gen/util.d.ts.map +1 -0
  389. package/dist/gen/util.js +1553 -0
  390. package/dist/gen/util.js.map +1 -0
  391. package/dist/generated/dun-profiles.d.ts +44 -0
  392. package/dist/generated/dun-profiles.d.ts.map +1 -0
  393. package/dist/generated/dun-profiles.js +28 -0
  394. package/dist/generated/dun-profiles.js.map +1 -0
  395. package/dist/generated/effects.d.ts +1021 -0
  396. package/dist/generated/effects.d.ts.map +1 -0
  397. package/dist/generated/effects.js +239 -0
  398. package/dist/generated/effects.js.map +1 -0
  399. package/dist/generated/elements.d.ts +83 -0
  400. package/dist/generated/elements.d.ts.map +1 -0
  401. package/dist/generated/elements.js +60 -0
  402. package/dist/generated/elements.js.map +1 -0
  403. package/dist/generated/equip-slots.d.ts +104 -0
  404. package/dist/generated/equip-slots.d.ts.map +1 -0
  405. package/dist/generated/equip-slots.js +34 -0
  406. package/dist/generated/equip-slots.js.map +1 -0
  407. package/dist/generated/history-types.d.ts +52 -0
  408. package/dist/generated/history-types.d.ts.map +1 -0
  409. package/dist/generated/history-types.js +32 -0
  410. package/dist/generated/history-types.js.map +1 -0
  411. package/dist/generated/ignore-types.d.ts +116 -0
  412. package/dist/generated/ignore-types.d.ts.map +1 -0
  413. package/dist/generated/ignore-types.js +64 -0
  414. package/dist/generated/ignore-types.js.map +1 -0
  415. package/dist/generated/index.d.ts +32 -0
  416. package/dist/generated/index.d.ts.map +1 -0
  417. package/dist/generated/index.js +33 -0
  418. package/dist/generated/index.js.map +1 -0
  419. package/dist/generated/kind-flags.d.ts +72 -0
  420. package/dist/generated/kind-flags.d.ts.map +1 -0
  421. package/dist/generated/kind-flags.js +42 -0
  422. package/dist/generated/kind-flags.js.map +1 -0
  423. package/dist/generated/message.d.ts +624 -0
  424. package/dist/generated/message.d.ts.map +1 -0
  425. package/dist/generated/message.js +318 -0
  426. package/dist/generated/message.js.map +1 -0
  427. package/dist/generated/mon-message.d.ts +386 -0
  428. package/dist/generated/mon-message.d.ts.map +1 -0
  429. package/dist/generated/mon-message.js +136 -0
  430. package/dist/generated/mon-message.js.map +1 -0
  431. package/dist/generated/mon-race-flags.d.ts +433 -0
  432. package/dist/generated/mon-race-flags.d.ts.map +1 -0
  433. package/dist/generated/mon-race-flags.js +180 -0
  434. package/dist/generated/mon-race-flags.js.map +1 -0
  435. package/dist/generated/mon-spells.d.ts +380 -0
  436. package/dist/generated/mon-spells.d.ts.map +1 -0
  437. package/dist/generated/mon-spells.js +196 -0
  438. package/dist/generated/mon-spells.js.map +1 -0
  439. package/dist/generated/mon-temp-flags.d.ts +52 -0
  440. package/dist/generated/mon-temp-flags.d.ts.map +1 -0
  441. package/dist/generated/mon-temp-flags.js +32 -0
  442. package/dist/generated/mon-temp-flags.js.map +1 -0
  443. package/dist/generated/mon-timed.d.ts +118 -0
  444. package/dist/generated/mon-timed.d.ts.map +1 -0
  445. package/dist/generated/mon-timed.js +32 -0
  446. package/dist/generated/mon-timed.js.map +1 -0
  447. package/dist/generated/object-flags.d.ts +169 -0
  448. package/dist/generated/object-flags.d.ts.map +1 -0
  449. package/dist/generated/object-flags.js +93 -0
  450. package/dist/generated/object-flags.js.map +1 -0
  451. package/dist/generated/object-modifiers.d.ts +50 -0
  452. package/dist/generated/object-modifiers.d.ts.map +1 -0
  453. package/dist/generated/object-modifiers.js +41 -0
  454. package/dist/generated/object-modifiers.js.map +1 -0
  455. package/dist/generated/options.d.ts +284 -0
  456. package/dist/generated/options.d.ts.map +1 -0
  457. package/dist/generated/options.js +102 -0
  458. package/dist/generated/options.js.map +1 -0
  459. package/dist/generated/origins.d.ts +138 -0
  460. package/dist/generated/origins.d.ts.map +1 -0
  461. package/dist/generated/origins.js +62 -0
  462. package/dist/generated/origins.js.map +1 -0
  463. package/dist/generated/parser-errors.d.ts +264 -0
  464. package/dist/generated/parser-errors.d.ts.map +1 -0
  465. package/dist/generated/parser-errors.js +138 -0
  466. package/dist/generated/parser-errors.js.map +1 -0
  467. package/dist/generated/player-flags.d.ts +62 -0
  468. package/dist/generated/player-flags.d.ts.map +1 -0
  469. package/dist/generated/player-flags.js +46 -0
  470. package/dist/generated/player-flags.js.map +1 -0
  471. package/dist/generated/player-timed.d.ts +273 -0
  472. package/dist/generated/player-timed.d.ts.map +1 -0
  473. package/dist/generated/player-timed.js +116 -0
  474. package/dist/generated/player-timed.js.map +1 -0
  475. package/dist/generated/projections.d.ts +130 -0
  476. package/dist/generated/projections.d.ts.map +1 -0
  477. package/dist/generated/projections.js +101 -0
  478. package/dist/generated/projections.js.map +1 -0
  479. package/dist/generated/randart-properties.d.ts +388 -0
  480. package/dist/generated/randart-properties.d.ts.map +1 -0
  481. package/dist/generated/randart-properties.js +200 -0
  482. package/dist/generated/randart-properties.js.map +1 -0
  483. package/dist/generated/room-flags.d.ts +21 -0
  484. package/dist/generated/room-flags.d.ts.map +1 -0
  485. package/dist/generated/room-flags.js +19 -0
  486. package/dist/generated/room-flags.js.map +1 -0
  487. package/dist/generated/rooms.d.ts +122 -0
  488. package/dist/generated/rooms.d.ts.map +1 -0
  489. package/dist/generated/rooms.js +48 -0
  490. package/dist/generated/rooms.js.map +1 -0
  491. package/dist/generated/square-flags.d.ts +96 -0
  492. package/dist/generated/square-flags.d.ts.map +1 -0
  493. package/dist/generated/square-flags.js +54 -0
  494. package/dist/generated/square-flags.js.map +1 -0
  495. package/dist/generated/stats.d.ts +23 -0
  496. package/dist/generated/stats.d.ts.map +1 -0
  497. package/dist/generated/stats.js +20 -0
  498. package/dist/generated/stats.js.map +1 -0
  499. package/dist/generated/terrain-flags.d.ts +136 -0
  500. package/dist/generated/terrain-flags.d.ts.map +1 -0
  501. package/dist/generated/terrain-flags.js +74 -0
  502. package/dist/generated/terrain-flags.js.map +1 -0
  503. package/dist/generated/terrain.d.ts +83 -0
  504. package/dist/generated/terrain.d.ts.map +1 -0
  505. package/dist/generated/terrain.js +60 -0
  506. package/dist/generated/terrain.js.map +1 -0
  507. package/dist/generated/trap-flags.d.ts +68 -0
  508. package/dist/generated/trap-flags.d.ts.map +1 -0
  509. package/dist/generated/trap-flags.js +40 -0
  510. package/dist/generated/trap-flags.js.map +1 -0
  511. package/dist/generated/tvals.d.ts +152 -0
  512. package/dist/generated/tvals.d.ts.map +1 -0
  513. package/dist/generated/tvals.js +82 -0
  514. package/dist/generated/tvals.js.map +1 -0
  515. package/dist/generated/ui-entry-renderers.d.ts +62 -0
  516. package/dist/generated/ui-entry-renderers.d.ts.map +1 -0
  517. package/dist/generated/ui-entry-renderers.js +22 -0
  518. package/dist/generated/ui-entry-renderers.js.map +1 -0
  519. package/dist/guard.d.ts +43 -0
  520. package/dist/guard.d.ts.map +1 -0
  521. package/dist/guard.js +65 -0
  522. package/dist/guard.js.map +1 -0
  523. package/dist/host/args.d.ts +129 -0
  524. package/dist/host/args.d.ts.map +1 -0
  525. package/dist/host/args.js +251 -0
  526. package/dist/host/args.js.map +1 -0
  527. package/dist/host/bridge.d.ts +61 -0
  528. package/dist/host/bridge.d.ts.map +1 -0
  529. package/dist/host/bridge.js +176 -0
  530. package/dist/host/bridge.js.map +1 -0
  531. package/dist/host/index.d.ts +18 -0
  532. package/dist/host/index.d.ts.map +1 -0
  533. package/dist/host/index.js +18 -0
  534. package/dist/host/index.js.map +1 -0
  535. package/dist/host/io.d.ts +169 -0
  536. package/dist/host/io.d.ts.map +1 -0
  537. package/dist/host/io.js +137 -0
  538. package/dist/host/io.js.map +1 -0
  539. package/dist/host/memory.d.ts +56 -0
  540. package/dist/host/memory.d.ts.map +1 -0
  541. package/dist/host/memory.js +105 -0
  542. package/dist/host/memory.js.map +1 -0
  543. package/dist/host/raw.d.ts +114 -0
  544. package/dist/host/raw.d.ts.map +1 -0
  545. package/dist/host/raw.js +107 -0
  546. package/dist/host/raw.js.map +1 -0
  547. package/dist/index.d.ts +180 -0
  548. package/dist/index.d.ts.map +1 -0
  549. package/dist/index.js +222 -0
  550. package/dist/index.js.map +1 -0
  551. package/dist/loc.d.ts +63 -0
  552. package/dist/loc.d.ts.map +1 -0
  553. package/dist/loc.js +128 -0
  554. package/dist/loc.js.map +1 -0
  555. package/dist/mod/hooks.d.ts +204 -0
  556. package/dist/mod/hooks.d.ts.map +1 -0
  557. package/dist/mod/hooks.js +161 -0
  558. package/dist/mod/hooks.js.map +1 -0
  559. package/dist/mod/ids.d.ts +160 -0
  560. package/dist/mod/ids.d.ts.map +1 -0
  561. package/dist/mod/ids.js +343 -0
  562. package/dist/mod/ids.js.map +1 -0
  563. package/dist/mod/registry-host.d.ts +156 -0
  564. package/dist/mod/registry-host.d.ts.map +1 -0
  565. package/dist/mod/registry-host.js +142 -0
  566. package/dist/mod/registry-host.js.map +1 -0
  567. package/dist/mod/save-blocks.d.ts +201 -0
  568. package/dist/mod/save-blocks.d.ts.map +1 -0
  569. package/dist/mod/save-blocks.js +640 -0
  570. package/dist/mod/save-blocks.js.map +1 -0
  571. package/dist/mod/vocabulary.d.ts +104 -0
  572. package/dist/mod/vocabulary.d.ts.map +1 -0
  573. package/dist/mod/vocabulary.js +0 -0
  574. package/dist/mod/vocabulary.js.map +1 -0
  575. package/dist/mon/bind.d.ts +266 -0
  576. package/dist/mon/bind.d.ts.map +1 -0
  577. package/dist/mon/bind.js +610 -0
  578. package/dist/mon/bind.js.map +1 -0
  579. package/dist/mon/desc.d.ts +72 -0
  580. package/dist/mon/desc.d.ts.map +1 -0
  581. package/dist/mon/desc.js +237 -0
  582. package/dist/mon/desc.js.map +1 -0
  583. package/dist/mon/knowledge-groups.d.ts +61 -0
  584. package/dist/mon/knowledge-groups.d.ts.map +1 -0
  585. package/dist/mon/knowledge-groups.js +121 -0
  586. package/dist/mon/knowledge-groups.js.map +1 -0
  587. package/dist/mon/lore-describe.d.ts +216 -0
  588. package/dist/mon/lore-describe.d.ts.map +1 -0
  589. package/dist/mon/lore-describe.js +1105 -0
  590. package/dist/mon/lore-describe.js.map +1 -0
  591. package/dist/mon/lore.d.ts +117 -0
  592. package/dist/mon/lore.d.ts.map +1 -0
  593. package/dist/mon/lore.js +221 -0
  594. package/dist/mon/lore.js.map +1 -0
  595. package/dist/mon/make.d.ts +147 -0
  596. package/dist/mon/make.d.ts.map +1 -0
  597. package/dist/mon/make.js +353 -0
  598. package/dist/mon/make.js.map +1 -0
  599. package/dist/mon/monster.d.ts +94 -0
  600. package/dist/mon/monster.d.ts.map +1 -0
  601. package/dist/mon/monster.js +90 -0
  602. package/dist/mon/monster.js.map +1 -0
  603. package/dist/mon/predicate.d.ts +87 -0
  604. package/dist/mon/predicate.d.ts.map +1 -0
  605. package/dist/mon/predicate.js +190 -0
  606. package/dist/mon/predicate.js.map +1 -0
  607. package/dist/mon/project-mon.d.ts +129 -0
  608. package/dist/mon/project-mon.d.ts.map +1 -0
  609. package/dist/mon/project-mon.js +652 -0
  610. package/dist/mon/project-mon.js.map +1 -0
  611. package/dist/mon/spell.d.ts +155 -0
  612. package/dist/mon/spell.d.ts.map +1 -0
  613. package/dist/mon/spell.js +355 -0
  614. package/dist/mon/spell.js.map +1 -0
  615. package/dist/mon/steal.d.ts +112 -0
  616. package/dist/mon/steal.d.ts.map +1 -0
  617. package/dist/mon/steal.js +163 -0
  618. package/dist/mon/steal.js.map +1 -0
  619. package/dist/mon/summon.d.ts +62 -0
  620. package/dist/mon/summon.d.ts.map +1 -0
  621. package/dist/mon/summon.js +111 -0
  622. package/dist/mon/summon.js.map +1 -0
  623. package/dist/mon/take-hit.d.ts +75 -0
  624. package/dist/mon/take-hit.d.ts.map +1 -0
  625. package/dist/mon/take-hit.js +122 -0
  626. package/dist/mon/take-hit.js.map +1 -0
  627. package/dist/mon/timed.d.ts +74 -0
  628. package/dist/mon/timed.d.ts.map +1 -0
  629. package/dist/mon/timed.js +219 -0
  630. package/dist/mon/timed.js.map +1 -0
  631. package/dist/mon/types.d.ts +252 -0
  632. package/dist/mon/types.d.ts.map +1 -0
  633. package/dist/mon/types.js +46 -0
  634. package/dist/mon/types.js.map +1 -0
  635. package/dist/msg.d.ts +71 -0
  636. package/dist/msg.d.ts.map +1 -0
  637. package/dist/msg.js +126 -0
  638. package/dist/msg.js.map +1 -0
  639. package/dist/obj/artifact-fake.d.ts +39 -0
  640. package/dist/obj/artifact-fake.d.ts.map +1 -0
  641. package/dist/obj/artifact-fake.js +52 -0
  642. package/dist/obj/artifact-fake.js.map +1 -0
  643. package/dist/obj/artifact-known.d.ts +50 -0
  644. package/dist/obj/artifact-known.d.ts.map +1 -0
  645. package/dist/obj/artifact-known.js +55 -0
  646. package/dist/obj/artifact-known.js.map +1 -0
  647. package/dist/obj/bind.d.ts +219 -0
  648. package/dist/obj/bind.d.ts.map +1 -0
  649. package/dist/obj/bind.js +1239 -0
  650. package/dist/obj/bind.js.map +1 -0
  651. package/dist/obj/chest.d.ts +91 -0
  652. package/dist/obj/chest.d.ts.map +1 -0
  653. package/dist/obj/chest.js +220 -0
  654. package/dist/obj/chest.js.map +1 -0
  655. package/dist/obj/desc.d.ts +79 -0
  656. package/dist/obj/desc.d.ts.map +1 -0
  657. package/dist/obj/desc.js +602 -0
  658. package/dist/obj/desc.js.map +1 -0
  659. package/dist/obj/effects-info.d.ts +78 -0
  660. package/dist/obj/effects-info.d.ts.map +1 -0
  661. package/dist/obj/effects-info.js +240 -0
  662. package/dist/obj/effects-info.js.map +1 -0
  663. package/dist/obj/flavor.d.ts +68 -0
  664. package/dist/obj/flavor.d.ts.map +1 -0
  665. package/dist/obj/flavor.js +201 -0
  666. package/dist/obj/flavor.js.map +1 -0
  667. package/dist/obj/ignore.d.ts +143 -0
  668. package/dist/obj/ignore.d.ts.map +1 -0
  669. package/dist/obj/ignore.js +345 -0
  670. package/dist/obj/ignore.js.map +1 -0
  671. package/dist/obj/knowledge.d.ts +520 -0
  672. package/dist/obj/knowledge.d.ts.map +1 -0
  673. package/dist/obj/knowledge.js +1364 -0
  674. package/dist/obj/knowledge.js.map +1 -0
  675. package/dist/obj/known-object.d.ts +293 -0
  676. package/dist/obj/known-object.d.ts.map +1 -0
  677. package/dist/obj/known-object.js +532 -0
  678. package/dist/obj/known-object.js.map +1 -0
  679. package/dist/obj/make.d.ts +292 -0
  680. package/dist/obj/make.d.ts.map +1 -0
  681. package/dist/obj/make.js +1055 -0
  682. package/dist/obj/make.js.map +1 -0
  683. package/dist/obj/object-info.d.ts +188 -0
  684. package/dist/obj/object-info.d.ts.map +1 -0
  685. package/dist/obj/object-info.js +1407 -0
  686. package/dist/obj/object-info.js.map +1 -0
  687. package/dist/obj/object.d.ts +335 -0
  688. package/dist/obj/object.d.ts.map +1 -0
  689. package/dist/obj/object.js +1051 -0
  690. package/dist/obj/object.js.map +1 -0
  691. package/dist/obj/power.d.ts +65 -0
  692. package/dist/obj/power.d.ts.map +1 -0
  693. package/dist/obj/power.js +580 -0
  694. package/dist/obj/power.js.map +1 -0
  695. package/dist/obj/randart-build.d.ts +223 -0
  696. package/dist/obj/randart-build.d.ts.map +1 -0
  697. package/dist/obj/randart-build.js +1444 -0
  698. package/dist/obj/randart-build.js.map +1 -0
  699. package/dist/obj/randart-data.d.ts +179 -0
  700. package/dist/obj/randart-data.d.ts.map +1 -0
  701. package/dist/obj/randart-data.js +1153 -0
  702. package/dist/obj/randart-data.js.map +1 -0
  703. package/dist/obj/randart.d.ts +128 -0
  704. package/dist/obj/randart.d.ts.map +1 -0
  705. package/dist/obj/randart.js +458 -0
  706. package/dist/obj/randart.js.map +1 -0
  707. package/dist/obj/randname.d.ts +33 -0
  708. package/dist/obj/randname.d.ts.map +1 -0
  709. package/dist/obj/randname.js +116 -0
  710. package/dist/obj/randname.js.map +1 -0
  711. package/dist/obj/recharge.d.ts +28 -0
  712. package/dist/obj/recharge.d.ts.map +1 -0
  713. package/dist/obj/recharge.js +52 -0
  714. package/dist/obj/recharge.js.map +1 -0
  715. package/dist/obj/types.d.ts +584 -0
  716. package/dist/obj/types.d.ts.map +1 -0
  717. package/dist/obj/types.js +104 -0
  718. package/dist/obj/types.js.map +1 -0
  719. package/dist/obj/value.d.ts +64 -0
  720. package/dist/obj/value.d.ts.map +1 -0
  721. package/dist/obj/value.js +176 -0
  722. package/dist/obj/value.js.map +1 -0
  723. package/dist/player/abilities.d.ts +57 -0
  724. package/dist/player/abilities.d.ts.map +1 -0
  725. package/dist/player/abilities.js +118 -0
  726. package/dist/player/abilities.js.map +1 -0
  727. package/dist/player/best-digger.d.ts +42 -0
  728. package/dist/player/best-digger.d.ts.map +1 -0
  729. package/dist/player/best-digger.js +89 -0
  730. package/dist/player/best-digger.js.map +1 -0
  731. package/dist/player/bind.d.ts +270 -0
  732. package/dist/player/bind.d.ts.map +1 -0
  733. package/dist/player/bind.js +698 -0
  734. package/dist/player/bind.js.map +1 -0
  735. package/dist/player/birth.d.ts +258 -0
  736. package/dist/player/birth.d.ts.map +1 -0
  737. package/dist/player/birth.js +639 -0
  738. package/dist/player/birth.js.map +1 -0
  739. package/dist/player/calcs.d.ts +403 -0
  740. package/dist/player/calcs.d.ts.map +1 -0
  741. package/dist/player/calcs.js +1189 -0
  742. package/dist/player/calcs.js.map +1 -0
  743. package/dist/player/combat-regen.d.ts +14 -0
  744. package/dist/player/combat-regen.d.ts.map +1 -0
  745. package/dist/player/combat-regen.js +29 -0
  746. package/dist/player/combat-regen.js.map +1 -0
  747. package/dist/player/exp.d.ts +96 -0
  748. package/dist/player/exp.d.ts.map +1 -0
  749. package/dist/player/exp.js +229 -0
  750. package/dist/player/exp.js.map +1 -0
  751. package/dist/player/history.d.ts +91 -0
  752. package/dist/player/history.d.ts.map +1 -0
  753. package/dist/player/history.js +145 -0
  754. package/dist/player/history.js.map +1 -0
  755. package/dist/player/options.d.ts +123 -0
  756. package/dist/player/options.d.ts.map +1 -0
  757. package/dist/player/options.js +199 -0
  758. package/dist/player/options.js.map +1 -0
  759. package/dist/player/player.d.ts +242 -0
  760. package/dist/player/player.d.ts.map +1 -0
  761. package/dist/player/player.js +119 -0
  762. package/dist/player/player.js.map +1 -0
  763. package/dist/player/shape-lore.d.ts +56 -0
  764. package/dist/player/shape-lore.d.ts.map +1 -0
  765. package/dist/player/shape-lore.js +221 -0
  766. package/dist/player/shape-lore.js.map +1 -0
  767. package/dist/player/spell.d.ts +146 -0
  768. package/dist/player/spell.d.ts.map +1 -0
  769. package/dist/player/spell.js +519 -0
  770. package/dist/player/spell.js.map +1 -0
  771. package/dist/player/take-hit.d.ts +87 -0
  772. package/dist/player/take-hit.d.ts.map +1 -0
  773. package/dist/player/take-hit.js +99 -0
  774. package/dist/player/take-hit.js.map +1 -0
  775. package/dist/player/timed.d.ts +205 -0
  776. package/dist/player/timed.d.ts.map +1 -0
  777. package/dist/player/timed.js +310 -0
  778. package/dist/player/timed.js.map +1 -0
  779. package/dist/player/types.d.ts +390 -0
  780. package/dist/player/types.d.ts.map +1 -0
  781. package/dist/player/types.js +51 -0
  782. package/dist/player/types.js.map +1 -0
  783. package/dist/rational.d.ts +99 -0
  784. package/dist/rational.d.ts.map +1 -0
  785. package/dist/rational.js +345 -0
  786. package/dist/rational.js.map +1 -0
  787. package/dist/rng.d.ts +168 -0
  788. package/dist/rng.d.ts.map +1 -0
  789. package/dist/rng.js +404 -0
  790. package/dist/rng.js.map +1 -0
  791. package/dist/save/buffer.d.ts +120 -0
  792. package/dist/save/buffer.d.ts.map +1 -0
  793. package/dist/save/buffer.js +238 -0
  794. package/dist/save/buffer.js.map +1 -0
  795. package/dist/save/compress.d.ts +79 -0
  796. package/dist/save/compress.d.ts.map +1 -0
  797. package/dist/save/compress.js +97 -0
  798. package/dist/save/compress.js.map +1 -0
  799. package/dist/save/description.d.ts +61 -0
  800. package/dist/save/description.d.ts.map +1 -0
  801. package/dist/save/description.js +51 -0
  802. package/dist/save/description.js.map +1 -0
  803. package/dist/save/integrity.d.ts +59 -0
  804. package/dist/save/integrity.d.ts.map +1 -0
  805. package/dist/save/integrity.js +103 -0
  806. package/dist/save/integrity.js.map +1 -0
  807. package/dist/score/display.d.ts +40 -0
  808. package/dist/score/display.d.ts.map +1 -0
  809. package/dist/score/display.js +86 -0
  810. package/dist/score/display.js.map +1 -0
  811. package/dist/score/score.d.ts +166 -0
  812. package/dist/score/score.d.ts.map +1 -0
  813. package/dist/score/score.js +244 -0
  814. package/dist/score/score.js.map +1 -0
  815. package/dist/score/types.d.ts +98 -0
  816. package/dist/score/types.d.ts.map +1 -0
  817. package/dist/score/types.js +27 -0
  818. package/dist/score/types.js.map +1 -0
  819. package/dist/session/boot.d.ts +207 -0
  820. package/dist/session/boot.d.ts.map +1 -0
  821. package/dist/session/boot.js +151 -0
  822. package/dist/session/boot.js.map +1 -0
  823. package/dist/session/game.d.ts +257 -0
  824. package/dist/session/game.d.ts.map +1 -0
  825. package/dist/session/game.js +2880 -0
  826. package/dist/session/game.js.map +1 -0
  827. package/dist/session/save.d.ts +847 -0
  828. package/dist/session/save.d.ts.map +1 -0
  829. package/dist/session/save.js +1306 -0
  830. package/dist/session/save.js.map +1 -0
  831. package/dist/sound/engine.d.ts +146 -0
  832. package/dist/sound/engine.d.ts.map +1 -0
  833. package/dist/sound/engine.js +332 -0
  834. package/dist/sound/engine.js.map +1 -0
  835. package/dist/sound/index.d.ts +13 -0
  836. package/dist/sound/index.d.ts.map +1 -0
  837. package/dist/sound/index.js +13 -0
  838. package/dist/sound/index.js.map +1 -0
  839. package/dist/sound/sound-prefs-data.d.ts +10 -0
  840. package/dist/sound/sound-prefs-data.d.ts.map +1 -0
  841. package/dist/sound/sound-prefs-data.js +165 -0
  842. package/dist/sound/sound-prefs-data.js.map +1 -0
  843. package/dist/sound/types.d.ts +64 -0
  844. package/dist/sound/types.d.ts.map +1 -0
  845. package/dist/sound/types.js +23 -0
  846. package/dist/sound/types.js.map +1 -0
  847. package/dist/store/bind.d.ts +43 -0
  848. package/dist/store/bind.d.ts.map +1 -0
  849. package/dist/store/bind.js +130 -0
  850. package/dist/store/bind.js.map +1 -0
  851. package/dist/store/price.d.ts +27 -0
  852. package/dist/store/price.d.ts.map +1 -0
  853. package/dist/store/price.js +81 -0
  854. package/dist/store/price.js.map +1 -0
  855. package/dist/store/store-cmd.d.ts +51 -0
  856. package/dist/store/store-cmd.d.ts.map +1 -0
  857. package/dist/store/store-cmd.js +73 -0
  858. package/dist/store/store-cmd.js.map +1 -0
  859. package/dist/store/store.d.ts +156 -0
  860. package/dist/store/store.d.ts.map +1 -0
  861. package/dist/store/store.js +616 -0
  862. package/dist/store/store.js.map +1 -0
  863. package/dist/store/transact.d.ts +198 -0
  864. package/dist/store/transact.d.ts.map +1 -0
  865. package/dist/store/transact.js +383 -0
  866. package/dist/store/transact.js.map +1 -0
  867. package/dist/store/types.d.ts +101 -0
  868. package/dist/store/types.d.ts.map +1 -0
  869. package/dist/store/types.js +14 -0
  870. package/dist/store/types.js.map +1 -0
  871. package/dist/version.d.ts +25 -0
  872. package/dist/version.d.ts.map +1 -0
  873. package/dist/version.js +25 -0
  874. package/dist/version.js.map +1 -0
  875. package/dist/visuals/engine.d.ts +223 -0
  876. package/dist/visuals/engine.d.ts.map +1 -0
  877. package/dist/visuals/engine.js +357 -0
  878. package/dist/visuals/engine.js.map +1 -0
  879. package/dist/visuals/glyph-table.d.ts +112 -0
  880. package/dist/visuals/glyph-table.d.ts.map +1 -0
  881. package/dist/visuals/glyph-table.js +156 -0
  882. package/dist/visuals/glyph-table.js.map +1 -0
  883. package/dist/visuals/grafmode-data.d.ts +4 -0
  884. package/dist/visuals/grafmode-data.d.ts.map +1 -0
  885. package/dist/visuals/grafmode-data.js +88 -0
  886. package/dist/visuals/grafmode-data.js.map +1 -0
  887. package/dist/visuals/grafmode.d.ts +83 -0
  888. package/dist/visuals/grafmode.d.ts.map +1 -0
  889. package/dist/visuals/grafmode.js +82 -0
  890. package/dist/visuals/grafmode.js.map +1 -0
  891. package/dist/visuals/index.d.ts +19 -0
  892. package/dist/visuals/index.d.ts.map +1 -0
  893. package/dist/visuals/index.js +19 -0
  894. package/dist/visuals/index.js.map +1 -0
  895. package/dist/visuals/map-text.d.ts +79 -0
  896. package/dist/visuals/map-text.d.ts.map +1 -0
  897. package/dist/visuals/map-text.js +122 -0
  898. package/dist/visuals/map-text.js.map +1 -0
  899. package/dist/visuals/pref-expr.d.ts +56 -0
  900. package/dist/visuals/pref-expr.d.ts.map +1 -0
  901. package/dist/visuals/pref-expr.js +173 -0
  902. package/dist/visuals/pref-expr.js.map +1 -0
  903. package/dist/visuals/prefs.d.ts +280 -0
  904. package/dist/visuals/prefs.d.ts.map +1 -0
  905. package/dist/visuals/prefs.js +835 -0
  906. package/dist/visuals/prefs.js.map +1 -0
  907. package/dist/visuals/tile-prefs.d.ts +132 -0
  908. package/dist/visuals/tile-prefs.d.ts.map +1 -0
  909. package/dist/visuals/tile-prefs.js +105 -0
  910. package/dist/visuals/tile-prefs.js.map +1 -0
  911. package/dist/world/chunk.d.ts +195 -0
  912. package/dist/world/chunk.d.ts.map +1 -0
  913. package/dist/world/chunk.js +422 -0
  914. package/dist/world/chunk.js.map +1 -0
  915. package/dist/world/feature.d.ts +86 -0
  916. package/dist/world/feature.d.ts.map +1 -0
  917. package/dist/world/feature.js +153 -0
  918. package/dist/world/feature.js.map +1 -0
  919. package/dist/world/flow.d.ts +33 -0
  920. package/dist/world/flow.d.ts.map +1 -0
  921. package/dist/world/flow.js +115 -0
  922. package/dist/world/flow.js.map +1 -0
  923. package/dist/world/project.d.ts +176 -0
  924. package/dist/world/project.d.ts.map +1 -0
  925. package/dist/world/project.js +543 -0
  926. package/dist/world/project.js.map +1 -0
  927. package/dist/world/projection.d.ts +100 -0
  928. package/dist/world/projection.d.ts.map +1 -0
  929. package/dist/world/projection.js +152 -0
  930. package/dist/world/projection.js.map +1 -0
  931. package/dist/world/scatter.d.ts +25 -0
  932. package/dist/world/scatter.d.ts.map +1 -0
  933. package/dist/world/scatter.js +54 -0
  934. package/dist/world/scatter.js.map +1 -0
  935. package/dist/world/trap.d.ts +84 -0
  936. package/dist/world/trap.d.ts.map +1 -0
  937. package/dist/world/trap.js +106 -0
  938. package/dist/world/trap.js.map +1 -0
  939. package/dist/world/view.d.ts +60 -0
  940. package/dist/world/view.d.ts.map +1 -0
  941. package/dist/world/view.js +436 -0
  942. package/dist/world/view.js.map +1 -0
  943. package/dist/z-queue.d.ts +133 -0
  944. package/dist/z-queue.d.ts.map +1 -0
  945. package/dist/z-queue.js +283 -0
  946. package/dist/z-queue.js.map +1 -0
  947. package/package.json +75 -0
  948. package/src/agent/act.ts +114 -0
  949. package/src/agent/controller.ts +109 -0
  950. package/src/agent/events.ts +47 -0
  951. package/src/agent/index.ts +36 -0
  952. package/src/agent/perceive.ts +440 -0
  953. package/src/agent/types.ts +464 -0
  954. package/src/bitflag.ts +536 -0
  955. package/src/cmd.ts +547 -0
  956. package/src/color.ts +267 -0
  957. package/src/combat/brand-slay.ts +360 -0
  958. package/src/combat/hit.ts +471 -0
  959. package/src/combat/index.ts +15 -0
  960. package/src/combat/melee.ts +728 -0
  961. package/src/combat/mon-melee.ts +1153 -0
  962. package/src/combat/ranged.ts +397 -0
  963. package/src/constants.ts +324 -0
  964. package/src/dice.ts +467 -0
  965. package/src/effects/effect-choice.ts +32 -0
  966. package/src/effects/effect-info.ts +859 -0
  967. package/src/effects/effect.ts +560 -0
  968. package/src/effects/handlers.ts +452 -0
  969. package/src/effects/interpreter.ts +603 -0
  970. package/src/events.ts +317 -0
  971. package/src/expression.ts +360 -0
  972. package/src/game/cave-cmd.ts +1147 -0
  973. package/src/game/char-sheet.ts +557 -0
  974. package/src/game/chest.ts +348 -0
  975. package/src/game/context.ts +1218 -0
  976. package/src/game/curse-tick.ts +130 -0
  977. package/src/game/describe.ts +62 -0
  978. package/src/game/display.ts +838 -0
  979. package/src/game/dump-level.ts +114 -0
  980. package/src/game/effect-attack.ts +746 -0
  981. package/src/game/effect-detect.ts +542 -0
  982. package/src/game/effect-env.ts +252 -0
  983. package/src/game/effect-game-env.ts +86 -0
  984. package/src/game/effect-general.ts +1122 -0
  985. package/src/game/effect-item.ts +999 -0
  986. package/src/game/effect-melee.ts +557 -0
  987. package/src/game/effect-mon-origin.ts +196 -0
  988. package/src/game/effect-monster.ts +310 -0
  989. package/src/game/effect-summon.ts +161 -0
  990. package/src/game/effect-teleport.ts +645 -0
  991. package/src/game/effect-terrain.ts +881 -0
  992. package/src/game/energy.ts +61 -0
  993. package/src/game/equip-cmp.ts +476 -0
  994. package/src/game/floor.ts +524 -0
  995. package/src/game/gear.ts +1352 -0
  996. package/src/game/harness.ts +270 -0
  997. package/src/game/history.ts +78 -0
  998. package/src/game/ignore-cmd.ts +68 -0
  999. package/src/game/inscription-confirm.ts +115 -0
  1000. package/src/game/known.ts +960 -0
  1001. package/src/game/loop.ts +671 -0
  1002. package/src/game/lore-color.ts +108 -0
  1003. package/src/game/mon-cast.ts +409 -0
  1004. package/src/game/mon-cmd.ts +767 -0
  1005. package/src/game/mon-death.ts +459 -0
  1006. package/src/game/mon-group.ts +368 -0
  1007. package/src/game/mon-list.ts +213 -0
  1008. package/src/game/mon-message.ts +359 -0
  1009. package/src/game/mon-place.ts +1012 -0
  1010. package/src/game/mon-ranged.ts +405 -0
  1011. package/src/game/mon-shape.ts +161 -0
  1012. package/src/game/mon-side.ts +511 -0
  1013. package/src/game/monster-turn.ts +1750 -0
  1014. package/src/game/obj-cmd.ts +1970 -0
  1015. package/src/game/obj-list.ts +302 -0
  1016. package/src/game/object-inspect.ts +162 -0
  1017. package/src/game/pickup.ts +483 -0
  1018. package/src/game/player-path.ts +1434 -0
  1019. package/src/game/player-side.ts +555 -0
  1020. package/src/game/player-turn.ts +852 -0
  1021. package/src/game/project-cast.ts +766 -0
  1022. package/src/game/project-feat.ts +386 -0
  1023. package/src/game/project-monster.ts +407 -0
  1024. package/src/game/project-obj.ts +298 -0
  1025. package/src/game/project-player.ts +236 -0
  1026. package/src/game/quest.ts +248 -0
  1027. package/src/game/ranged-cmd.ts +417 -0
  1028. package/src/game/scheduler.ts +150 -0
  1029. package/src/game/spell-cmd.ts +404 -0
  1030. package/src/game/spoil.ts +562 -0
  1031. package/src/game/steal.ts +169 -0
  1032. package/src/game/take-hit-hooks.ts +152 -0
  1033. package/src/game/target-loop.ts +501 -0
  1034. package/src/game/target.ts +424 -0
  1035. package/src/game/thrust.ts +174 -0
  1036. package/src/game/trap.ts +791 -0
  1037. package/src/game/ui-entry.ts +2075 -0
  1038. package/src/game/wizard.ts +1760 -0
  1039. package/src/game/world.ts +786 -0
  1040. package/src/gen/cave.ts +2858 -0
  1041. package/src/gen/gen-monster.ts +592 -0
  1042. package/src/gen/generate.ts +523 -0
  1043. package/src/gen/room.ts +2213 -0
  1044. package/src/gen/util.ts +1958 -0
  1045. package/src/generated/dun-profiles.ts +30 -0
  1046. package/src/generated/effects.ts +241 -0
  1047. package/src/generated/elements.ts +62 -0
  1048. package/src/generated/equip-slots.ts +36 -0
  1049. package/src/generated/history-types.ts +34 -0
  1050. package/src/generated/ignore-types.ts +66 -0
  1051. package/src/generated/index.ts +33 -0
  1052. package/src/generated/kind-flags.ts +44 -0
  1053. package/src/generated/message.ts +320 -0
  1054. package/src/generated/mon-message.ts +138 -0
  1055. package/src/generated/mon-race-flags.ts +182 -0
  1056. package/src/generated/mon-spells.ts +198 -0
  1057. package/src/generated/mon-temp-flags.ts +34 -0
  1058. package/src/generated/mon-timed.ts +34 -0
  1059. package/src/generated/object-flags.ts +95 -0
  1060. package/src/generated/object-modifiers.ts +43 -0
  1061. package/src/generated/options.ts +104 -0
  1062. package/src/generated/origins.ts +64 -0
  1063. package/src/generated/parser-errors.ts +140 -0
  1064. package/src/generated/player-flags.ts +48 -0
  1065. package/src/generated/player-timed.ts +118 -0
  1066. package/src/generated/projections.ts +103 -0
  1067. package/src/generated/randart-properties.ts +202 -0
  1068. package/src/generated/room-flags.ts +21 -0
  1069. package/src/generated/rooms.ts +50 -0
  1070. package/src/generated/square-flags.ts +56 -0
  1071. package/src/generated/stats.ts +22 -0
  1072. package/src/generated/terrain-flags.ts +76 -0
  1073. package/src/generated/terrain.ts +62 -0
  1074. package/src/generated/trap-flags.ts +42 -0
  1075. package/src/generated/tvals.ts +84 -0
  1076. package/src/generated/ui-entry-renderers.ts +24 -0
  1077. package/src/guard.ts +70 -0
  1078. package/src/host/args.ts +334 -0
  1079. package/src/host/bridge.ts +193 -0
  1080. package/src/host/index.ts +18 -0
  1081. package/src/host/io.ts +239 -0
  1082. package/src/host/memory.ts +134 -0
  1083. package/src/host/raw.ts +190 -0
  1084. package/src/index.ts +250 -0
  1085. package/src/loc.ts +157 -0
  1086. package/src/mod/hooks.ts +278 -0
  1087. package/src/mod/ids.ts +390 -0
  1088. package/src/mod/registry-host.ts +258 -0
  1089. package/src/mod/save-blocks.ts +787 -0
  1090. package/src/mod/vocabulary.ts +0 -0
  1091. package/src/mon/bind.ts +899 -0
  1092. package/src/mon/desc.ts +212 -0
  1093. package/src/mon/knowledge-groups.ts +164 -0
  1094. package/src/mon/lore-describe.ts +1414 -0
  1095. package/src/mon/lore.ts +306 -0
  1096. package/src/mon/make.ts +422 -0
  1097. package/src/mon/monster.ts +161 -0
  1098. package/src/mon/predicate.ts +220 -0
  1099. package/src/mon/project-mon.ts +855 -0
  1100. package/src/mon/spell.ts +418 -0
  1101. package/src/mon/steal.ts +246 -0
  1102. package/src/mon/summon.ts +145 -0
  1103. package/src/mon/take-hit.ts +195 -0
  1104. package/src/mon/timed.ts +300 -0
  1105. package/src/mon/types.ts +286 -0
  1106. package/src/msg.ts +146 -0
  1107. package/src/obj/artifact-fake.ts +63 -0
  1108. package/src/obj/artifact-known.ts +69 -0
  1109. package/src/obj/bind.ts +1345 -0
  1110. package/src/obj/chest.ts +249 -0
  1111. package/src/obj/desc.ts +699 -0
  1112. package/src/obj/effects-info.ts +349 -0
  1113. package/src/obj/flavor.ts +256 -0
  1114. package/src/obj/ignore.ts +387 -0
  1115. package/src/obj/knowledge.ts +1577 -0
  1116. package/src/obj/known-object.ts +718 -0
  1117. package/src/obj/make.ts +1367 -0
  1118. package/src/obj/object-info.ts +1737 -0
  1119. package/src/obj/object.ts +1296 -0
  1120. package/src/obj/power.ts +674 -0
  1121. package/src/obj/randart-build.ts +1705 -0
  1122. package/src/obj/randart-data.ts +1344 -0
  1123. package/src/obj/randart.ts +552 -0
  1124. package/src/obj/randname.ts +128 -0
  1125. package/src/obj/recharge.ts +62 -0
  1126. package/src/obj/types.ts +559 -0
  1127. package/src/obj/value.ts +215 -0
  1128. package/src/player/abilities.ts +142 -0
  1129. package/src/player/best-digger.ts +118 -0
  1130. package/src/player/bind.ts +1021 -0
  1131. package/src/player/birth.ts +794 -0
  1132. package/src/player/calcs.ts +1522 -0
  1133. package/src/player/combat-regen.ts +33 -0
  1134. package/src/player/exp.ts +275 -0
  1135. package/src/player/history.ts +211 -0
  1136. package/src/player/options.ts +244 -0
  1137. package/src/player/player.ts +356 -0
  1138. package/src/player/shape-lore.ts +250 -0
  1139. package/src/player/spell.ts +627 -0
  1140. package/src/player/take-hit.ts +173 -0
  1141. package/src/player/timed.ts +482 -0
  1142. package/src/player/types.ts +415 -0
  1143. package/src/rational.ts +388 -0
  1144. package/src/rng.ts +476 -0
  1145. package/src/save/buffer.ts +287 -0
  1146. package/src/save/compress.ts +132 -0
  1147. package/src/save/description.ts +70 -0
  1148. package/src/save/integrity.ts +133 -0
  1149. package/src/score/display.ts +125 -0
  1150. package/src/score/score.ts +341 -0
  1151. package/src/score/types.ts +104 -0
  1152. package/src/session/boot.ts +338 -0
  1153. package/src/session/game.ts +3712 -0
  1154. package/src/session/save.ts +2074 -0
  1155. package/src/sound/engine.ts +375 -0
  1156. package/src/sound/index.ts +13 -0
  1157. package/src/sound/sound-prefs-data.ts +173 -0
  1158. package/src/sound/types.ts +68 -0
  1159. package/src/store/bind.ts +145 -0
  1160. package/src/store/price.ts +97 -0
  1161. package/src/store/store-cmd.ts +73 -0
  1162. package/src/store/store.ts +723 -0
  1163. package/src/store/transact.ts +644 -0
  1164. package/src/store/types.ts +110 -0
  1165. package/src/version.ts +26 -0
  1166. package/src/visuals/engine.ts +444 -0
  1167. package/src/visuals/glyph-table.ts +191 -0
  1168. package/src/visuals/grafmode-data.ts +90 -0
  1169. package/src/visuals/grafmode.ts +123 -0
  1170. package/src/visuals/index.ts +19 -0
  1171. package/src/visuals/map-text.ts +152 -0
  1172. package/src/visuals/pref-expr.ts +182 -0
  1173. package/src/visuals/prefs.ts +981 -0
  1174. package/src/visuals/tile-prefs.ts +183 -0
  1175. package/src/world/chunk.ts +531 -0
  1176. package/src/world/feature.ts +215 -0
  1177. package/src/world/flow.ts +128 -0
  1178. package/src/world/project.ts +687 -0
  1179. package/src/world/projection.ts +228 -0
  1180. package/src/world/scatter.ts +72 -0
  1181. package/src/world/trap.ts +155 -0
  1182. package/src/world/view.ts +513 -0
  1183. package/src/z-queue.ts +300 -0
@@ -0,0 +1,1306 @@
1
+ /**
2
+ * JSON save/load (PORT_PLAN.md decision 9): the entity serializers that
3
+ * turn a live GameState into plain JSON and back. The format is the port's
4
+ * own (the C binary blocks of save.c/load.c are replaced by design); WHAT
5
+ * is saved follows upstream savefile semantics - notably the RNG state is
6
+ * persisted (save.c wr_randomizer), which is what the no-save-scum posture
7
+ * rides on (decisions 16/22): reloading resumes the same stream.
8
+ *
9
+ * References into bound registries (races, kinds, egos, artifacts, trap
10
+ * kinds, classes) are saved as stable indices/names and re-resolved against
11
+ * the pack on load, so a save is data + pack, never code. Raw effect chains
12
+ * and kind-owned text re-point at the kind on load rather than being
13
+ * copied into the save.
14
+ *
15
+ * Integrity: serializeGame produces the JSON payload; callers stamp/verify
16
+ * bytes with save/integrity.ts (stampSavefile / verifyStampedSavefile),
17
+ * the decision-16b tamper deterrent.
18
+ *
19
+ * BLOCK MAP (save.c wr_* / load.c rd_* -> the field this file writes). There is
20
+ * deliberately no per-block function pair: the C block table is replaced by one
21
+ * JSON document, so W1's question is field coverage, not symbol presence. Each
22
+ * row is proved by save-fields.test.ts, the C-derived coverage guard.
23
+ *
24
+ * wr_description (save.c:49) -> not a FIELD: the exact string is ported in
25
+ * save/description.ts and derived from
26
+ * fullName / lev / race / class / depth,
27
+ * which this document already carries. In a
28
+ * JSON save it need not be stored at all, and
29
+ * storing it would create the second source
30
+ * of truth upstream's own readers avoid by
31
+ * scanning a directory and asking each file.
32
+ * wr_randomizer (save.c:286) -> SavedGame.rng
33
+ * wr_options (save.c:314) -> SavedGame.options (SIDEBAR_MODE is UI)
34
+ * wr_messages (save.c:339) -> SavedGame.messages
35
+ * wr_monster_memory(save.c:356) -> SavedGame.lore (whole record, not just
36
+ * pkills/thefts: the port has no lore.txt)
37
+ * wr_object_memory (save.c:377) -> flavor.aware / .tried, everseen.kinds,
38
+ * ignore.kindAware / .kindUnaware
39
+ * wr_quests (save.c:405) -> player.quests
40
+ * wr_player (save.c:418) -> SavedPlayer + SavedGame.actor / arena /
41
+ * nameSuffix / skipCmdCoercion / unignoring /
42
+ * restingTurn
43
+ * wr_ignore (save.c:514) -> SavedGame.ignore, .autoinscriptions,
44
+ * everseen.egos. GAP: the rune-note block
45
+ * (save.c:589-605) has no counterpart -
46
+ * rune_note is a ledgered deferral.
47
+ * wr_misc (save.c:610) -> randartSeed, seedFlavor, player.totalWinner,
48
+ * player.noscore, isDead, turn, player.objKnown
49
+ * wr_artifacts (save.c:674) -> artifactsCreated / Seen / Everseen
50
+ * wr_player_hp (save.c:692) -> player.playerHp
51
+ * wr_player_spells (save.c:702) -> player.spellFlags / .spellOrder
52
+ * wr_gear_aux (save.c:715) -> gear (+ player.equipment slot map)
53
+ * wr_gear (save.c:737) -> ditto; the gear_k known twin is N/A
54
+ * wr_stores (save.c:744) -> SavedGame.stores
55
+ * wr_dungeon_aux (save.c:774) -> ChunkSquaresData (+ currentJoins)
56
+ * wr_objects_aux (save.c:873) -> SavedGame.floor
57
+ * wr_monsters_aux (save.c:915) -> SavedGame.monsters / .groups
58
+ * wr_traps_aux (save.c:933) -> SavedGame.traps
59
+ * wr_dungeon (save.c:959) -> dungeonDepth, daycount, actor.grid
60
+ * wr_objects (save.c:980) -> floor (player->cave twin N/A)
61
+ * wr_monsters (save.c:986) -> monsters (player->cave twin N/A)
62
+ * wr_traps (save.c:992) -> traps (player->cave twin N/A)
63
+ * wr_chunks (save.c:1001) -> levelCache + townChunk
64
+ * wr_history (save.c:1048) -> player.hist
65
+ * wr_item (save.c:69) -> SavedObject (obj->oidx N/A)
66
+ * wr_monster (save.c:201) -> SavedMonster
67
+ * wr_trap (save.c:261) -> SavedTrap
68
+ */
69
+ import { loc } from "../loc.js";
70
+ import { FlagSet } from "../bitflag.js";
71
+ import { Chunk, SQUARE_SIZE } from "../world/chunk.js";
72
+ import { buildRuneList, runeKey } from "../obj/knowledge.js";
73
+ import { blankMonster, GROUP_MAX } from "../mon/monster.js";
74
+ import { blankPlayer } from "../player/player.js";
75
+ import { MessageLog } from "../msg.js";
76
+ import { newKnownMap } from "../game/known.js";
77
+ import { fnv1aIntegrity, stampSavefile, verifyStampedSavefile, } from "../save/integrity.js";
78
+ import { applyCodec, findCodec, stripCodec } from "../save/compress.js";
79
+ import { PY_MAX_LEVEL, TMD_MAX } from "../player/types.js";
80
+ /**
81
+ * The save format version this build writes. Version 2 replaced every numeric
82
+ * content index (kidx/eidx/aidx/ridx/tidx/feat, and the positional curse/
83
+ * brand/slay arrays) with the namespaced string ids of mod/ids.ts, the
84
+ * load-bearing rule of the mod substrate (MOD_LIFECYCLE decision 1). Version 3
85
+ * finished that job: `flavor`, `everseen` and `ignore` were the last blocks
86
+ * still keyed by raw kidx/eidx, and the rune-autoinscription block of wr_ignore
87
+ * (save.c:586-605) arrived with them. Older saves are not migrated: the game is
88
+ * pre-1.0 and the save format is still settling, so loadGame rejects them and
89
+ * the host starts a fresh game.
90
+ */
91
+ export const SAVE_VERSION = 3;
92
+ export function serializeObject(obj, ids) {
93
+ return {
94
+ kindId: ids.kindId(obj.kind.kidx),
95
+ egoId: obj.ego ? ids.egoId(obj.ego.eidx) : null,
96
+ artifactId: obj.artifact ? ids.artifactId(obj.artifact.aidx) : null,
97
+ grid: obj.grid ? { x: obj.grid.x, y: obj.grid.y } : null,
98
+ tval: obj.tval,
99
+ sval: obj.sval,
100
+ pval: obj.pval,
101
+ ...(obj.knownPval !== undefined ? { knownPval: obj.knownPval } : {}),
102
+ weight: obj.weight,
103
+ dd: obj.dd,
104
+ ds: obj.ds,
105
+ ac: obj.ac,
106
+ toA: obj.toA,
107
+ toH: obj.toH,
108
+ toD: obj.toD,
109
+ flags: Array.from(obj.flags.bits),
110
+ modifiers: [...obj.modifiers],
111
+ elInfo: obj.elInfo.map((e) => ({ ...e })),
112
+ brands: serializeBrandList(obj.brands, ids),
113
+ slays: serializeSlayList(obj.slays, ids),
114
+ curses: serializeCurseList(obj.curses, ids),
115
+ time: { ...obj.time },
116
+ timeout: obj.timeout,
117
+ number: obj.number,
118
+ notice: obj.notice,
119
+ heldMIdx: obj.heldMIdx,
120
+ mimickingMIdx: obj.mimickingMIdx,
121
+ origin: obj.origin,
122
+ originDepth: obj.originDepth,
123
+ originRaceId: obj.originRace ? ids.raceId(obj.originRace) : null,
124
+ note: obj.note,
125
+ effectPresent: obj.effect !== null,
126
+ activationIndex: obj.activation?.index ?? 0,
127
+ };
128
+ }
129
+ /** Brand booleans -> the ids of the set brands (drops the dense zeroes). */
130
+ function serializeBrandList(brands, ids) {
131
+ if (!brands)
132
+ return null;
133
+ const out = [];
134
+ for (let i = 1; i < brands.length; i++)
135
+ if (brands[i])
136
+ out.push(ids.brandId(i));
137
+ return out;
138
+ }
139
+ /** Slay booleans -> the ids of the set slays. */
140
+ function serializeSlayList(slays, ids) {
141
+ if (!slays)
142
+ return null;
143
+ const out = [];
144
+ for (let i = 1; i < slays.length; i++)
145
+ if (slays[i])
146
+ out.push(ids.slayId(i));
147
+ return out;
148
+ }
149
+ /** Curse data array -> {id,power,timeout} for the powered curses only. */
150
+ function serializeCurseList(curses, ids) {
151
+ if (!curses)
152
+ return null;
153
+ const out = [];
154
+ for (let i = 1; i < curses.length; i++) {
155
+ const c = curses[i];
156
+ if (c && c.power > 0) {
157
+ out.push({ id: ids.curseId(i), power: c.power, timeout: c.timeout });
158
+ }
159
+ }
160
+ return out.length > 0 ? out : null;
161
+ }
162
+ /** obj_k->curses (power 1 = rune known) -> the ids of the known curses. */
163
+ function serializeKnownCurseList(curses, ids) {
164
+ const out = [];
165
+ for (let i = 1; i < curses.length; i++)
166
+ if (curses[i])
167
+ out.push(ids.curseId(i));
168
+ return out;
169
+ }
170
+ export function deserializeObject(data, reg, ids) {
171
+ const kidx = ids.kindIndex(data.kindId);
172
+ const kind = kidx !== undefined ? reg.kinds[kidx] : undefined;
173
+ if (!kind)
174
+ throw new Error(`save: unknown object kind ${data.kindId}`);
175
+ const aIdx = data.artifactId !== null ? ids.artifactIndex(data.artifactId) : undefined;
176
+ const artifact = aIdx !== undefined ? (reg.artifacts[aIdx] ?? null) : null;
177
+ const eIdx = data.egoId !== null ? ids.egoIndex(data.egoId) : undefined;
178
+ const ego = eIdx !== undefined ? (reg.egos[eIdx] ?? null) : null;
179
+ const originIdx = data.originRaceId !== null ? ids.raceIndex(data.originRaceId) : undefined;
180
+ const effectPresent = data.effectPresent ?? true;
181
+ /* load.c:223-232 resolves the saved activation index, not kind defaults. */
182
+ const activation = data.activationIndex !== undefined
183
+ ? data.activationIndex > 0
184
+ ? (reg.activations[data.activationIndex] ?? null)
185
+ : null
186
+ : (artifact?.activation ?? kind.activation);
187
+ return {
188
+ kind,
189
+ ego,
190
+ artifact,
191
+ grid: data.grid ? loc(data.grid.x, data.grid.y) : null,
192
+ tval: data.tval,
193
+ sval: data.sval,
194
+ pval: data.pval,
195
+ ...(data.knownPval !== undefined ? { knownPval: data.knownPval } : {}),
196
+ weight: data.weight,
197
+ dd: data.dd,
198
+ ds: data.ds,
199
+ ac: data.ac,
200
+ toA: data.toA,
201
+ toH: data.toH,
202
+ toD: data.toD,
203
+ flags: new FlagSet(Uint8Array.from(data.flags)),
204
+ modifiers: [...data.modifiers],
205
+ elInfo: data.elInfo.map((e) => ({ ...e })),
206
+ brands: deserializeBrandList(data.brands, reg, ids),
207
+ slays: deserializeSlayList(data.slays, reg, ids),
208
+ curses: deserializeCurseList(data.curses, reg, ids),
209
+ /* Kind-owned data re-points at the bound kind. */
210
+ effect: effectPresent ? kind.effect : null,
211
+ effectMsg: effectPresent ? kind.effectMsg : "",
212
+ activation,
213
+ time: { ...data.time },
214
+ timeout: data.timeout,
215
+ number: data.number,
216
+ notice: data.notice,
217
+ heldMIdx: data.heldMIdx,
218
+ mimickingMIdx: data.mimickingMIdx,
219
+ origin: data.origin,
220
+ originDepth: data.originDepth,
221
+ originRace: originIdx ?? 0,
222
+ note: data.note,
223
+ };
224
+ }
225
+ /** Brand ids -> the dense boolean array (length brandMax), or null. */
226
+ function deserializeBrandList(saved, reg, ids) {
227
+ if (!saved)
228
+ return null;
229
+ const out = new Array(reg.brandMax).fill(false);
230
+ for (const id of saved) {
231
+ const i = ids.brandIndex(id);
232
+ if (i !== undefined)
233
+ out[i] = true;
234
+ }
235
+ return out;
236
+ }
237
+ /** Slay ids -> the dense boolean array (length slayMax), or null. */
238
+ function deserializeSlayList(saved, reg, ids) {
239
+ if (!saved)
240
+ return null;
241
+ const out = new Array(reg.slayMax).fill(false);
242
+ for (const id of saved) {
243
+ const i = ids.slayIndex(id);
244
+ if (i !== undefined)
245
+ out[i] = true;
246
+ }
247
+ return out;
248
+ }
249
+ /** Curse id list -> the dense CurseData array (length curseMax), or null. */
250
+ function deserializeCurseList(saved, reg, ids) {
251
+ if (!saved)
252
+ return null;
253
+ const out = [];
254
+ for (let i = 0; i < reg.curseMax; i++)
255
+ out.push({ power: 0, timeout: 0 });
256
+ for (const c of saved) {
257
+ const i = ids.curseIndex(c.id);
258
+ if (i !== undefined)
259
+ out[i] = { power: c.power, timeout: c.timeout };
260
+ }
261
+ return out;
262
+ }
263
+ /** Known-curse ids -> the dense obj_k->curses array (power 1 = known). */
264
+ function deserializeKnownCurseList(saved, reg, ids) {
265
+ const out = new Array(reg.curseMax).fill(0);
266
+ for (const id of saved) {
267
+ const i = ids.curseIndex(id);
268
+ if (i !== undefined)
269
+ out[i] = 1;
270
+ }
271
+ return out;
272
+ }
273
+ export function serializeMonster(mon, ids) {
274
+ return {
275
+ raceId: ids.raceId(mon.race.ridx),
276
+ originalRaceId: mon.originalRace ? ids.raceId(mon.originalRace.ridx) : null,
277
+ midx: mon.midx,
278
+ grid: { x: mon.grid.x, y: mon.grid.y },
279
+ hp: mon.hp,
280
+ maxhp: mon.maxhp,
281
+ mTimed: Array.from(mon.mTimed),
282
+ mspeed: mon.mspeed,
283
+ energy: mon.energy,
284
+ cdis: mon.cdis,
285
+ mflag: Array.from(mon.mflag.bits),
286
+ mimickedObj: mon.mimickedObj,
287
+ heldObj: mon.heldObj.map((o) => serializeObject(o, ids)),
288
+ attr: mon.attr,
289
+ target: {
290
+ grid: { x: mon.target.grid.x, y: mon.target.grid.y },
291
+ midx: mon.target.midx,
292
+ },
293
+ groupInfo: mon.groupInfo.map((g) => ({ ...g })),
294
+ minRange: mon.minRange,
295
+ bestRange: mon.bestRange,
296
+ knownPstateFlags: Array.from(mon.knownPstate.flags.bits),
297
+ knownPstateElInfo: Array.from(mon.knownPstate.elInfo),
298
+ };
299
+ }
300
+ /** rd_monster (load.c:259), over JSON instead of the binary block. */
301
+ export function deserializeMonster(data, monsters, objects, ids) {
302
+ const ridx = ids.raceIndex(data.raceId);
303
+ const race = ridx !== undefined ? monsters.races[ridx] : undefined;
304
+ if (!race)
305
+ throw new Error(`save: unknown race ${data.raceId}`);
306
+ const mon = blankMonster(race);
307
+ const origRidx = data.originalRaceId !== null
308
+ ? ids.raceIndex(data.originalRaceId)
309
+ : undefined;
310
+ mon.originalRace = origRidx !== undefined ? (monsters.races[origRidx] ?? null) : null;
311
+ mon.midx = data.midx;
312
+ mon.grid = loc(data.grid.x, data.grid.y);
313
+ mon.hp = data.hp;
314
+ mon.maxhp = data.maxhp;
315
+ mon.mTimed.set(data.mTimed);
316
+ mon.mspeed = data.mspeed;
317
+ mon.energy = data.energy;
318
+ mon.cdis = data.cdis;
319
+ mon.mflag.bits.set(data.mflag);
320
+ if (data.knownPstateFlags) {
321
+ /* load.c:302 restores known_pstate.flags before the monster goes live. */
322
+ mon.knownPstate.flags.bits.set(data.knownPstateFlags);
323
+ }
324
+ if (data.knownPstateElInfo) {
325
+ /* load.c:305 restores known_pstate.el_info[].res_level before live use. */
326
+ mon.knownPstate.elInfo.set(data.knownPstateElInfo);
327
+ }
328
+ mon.mimickedObj = data.mimickedObj;
329
+ mon.heldObj = data.heldObj.map((o) => deserializeObject(o, objects, ids));
330
+ mon.attr = data.attr;
331
+ mon.target = {
332
+ grid: loc(data.target.grid.x, data.target.grid.y),
333
+ midx: data.target.midx,
334
+ };
335
+ for (let i = 0; i < GROUP_MAX; i++) {
336
+ const g = data.groupInfo[i];
337
+ if (g)
338
+ mon.groupInfo[i] = { ...g };
339
+ }
340
+ mon.minRange = data.minRange;
341
+ mon.bestRange = data.bestRange;
342
+ return mon;
343
+ }
344
+ export function serializePlayer(p, ids) {
345
+ return {
346
+ raceName: p.race.name,
347
+ clsName: p.cls.name,
348
+ hitdie: p.hitdie,
349
+ expFactor: p.expFactor,
350
+ age: p.age,
351
+ ht: p.ht,
352
+ wt: p.wt,
353
+ au: p.au,
354
+ maxLev: p.maxLev,
355
+ lev: p.lev,
356
+ maxExp: p.maxExp,
357
+ exp: p.exp,
358
+ expFrac: p.expFrac,
359
+ maxDepth: p.maxDepth,
360
+ recallDepth: p.recallDepth,
361
+ wordRecall: p.wordRecall,
362
+ deepDescent: p.deepDescent,
363
+ mhp: p.mhp,
364
+ chp: p.chp,
365
+ chpFrac: p.chpFrac,
366
+ msp: p.msp,
367
+ csp: p.csp,
368
+ cspFrac: p.cspFrac,
369
+ statMax: [...p.statMax],
370
+ statCur: [...p.statCur],
371
+ statMap: [...p.statMap],
372
+ statBirth: [...p.statBirth],
373
+ timed: Array.from(p.timed),
374
+ spellFlags: [...p.spellFlags],
375
+ spellOrder: [...p.spellOrder],
376
+ playerHp: [...p.playerHp],
377
+ auBirth: p.auBirth,
378
+ htBirth: p.htBirth,
379
+ wtBirth: p.wtBirth,
380
+ fullName: p.fullName,
381
+ diedFrom: p.diedFrom,
382
+ noscore: p.noscore,
383
+ history: p.history,
384
+ hist: p.hist.map((e) => ({
385
+ type: e.type,
386
+ dlev: e.dlev,
387
+ clev: e.clev,
388
+ artifactName: ids.artifactName(e.aIdx) ?? "",
389
+ turn: e.turn,
390
+ event: e.event,
391
+ })),
392
+ equipment: [...p.equipment],
393
+ objKnown: {
394
+ modifiers: [...p.objKnown.modifiers],
395
+ toA: p.objKnown.toA,
396
+ toH: p.objKnown.toH,
397
+ toD: p.objKnown.toD,
398
+ dd: p.objKnown.dd,
399
+ ds: p.objKnown.ds,
400
+ ac: p.objKnown.ac,
401
+ elInfo: p.objKnown.elInfo.map((e) => ({ ...e })),
402
+ flags: Array.from(p.objKnown.flags.bits),
403
+ /* The learned runes save as the ids of the known brands/slays/curses. */
404
+ brands: serializeBrandList(p.objKnown.brands, ids) ?? [],
405
+ slays: serializeSlayList(p.objKnown.slays, ids) ?? [],
406
+ curses: serializeKnownCurseList(p.objKnown.curses, ids),
407
+ },
408
+ shapeName: p.shape ? p.shape.name : null,
409
+ skills: [...p.skills],
410
+ upkeep: { ...p.upkeep },
411
+ quests: p.quests.map((q) => ({ ...q })),
412
+ totalWinner: p.totalWinner,
413
+ };
414
+ }
415
+ export function deserializePlayer(data, players, objReg, ids) {
416
+ const race = players.raceByName(data.raceName);
417
+ const cls = players.classByName(data.clsName);
418
+ if (!race || !cls) {
419
+ throw new Error(`save: unknown race/class ${data.raceName}/${data.clsName}`);
420
+ }
421
+ const body = players.bodies[race.body] ?? players.bodies[0];
422
+ const p = blankPlayer(race, cls, body);
423
+ p.hitdie = data.hitdie;
424
+ p.expFactor = data.expFactor;
425
+ p.age = data.age;
426
+ p.ht = data.ht;
427
+ p.wt = data.wt;
428
+ p.au = data.au;
429
+ /* load.c:767-780 rejects levels outside 1..PY_MAX_LEVEL. */
430
+ if (data.lev < 1 || data.lev > PY_MAX_LEVEL) {
431
+ throw new Error(`save: invalid player level ${data.lev}`);
432
+ }
433
+ /* load.c:785-789 repairs max_lev, max_depth and recall_depth. */
434
+ p.maxLev = data.maxLev < data.lev ? data.lev : data.maxLev;
435
+ p.lev = data.lev;
436
+ p.maxExp = data.maxExp;
437
+ p.exp = data.exp;
438
+ p.expFrac = data.expFrac;
439
+ p.maxDepth = data.maxDepth ?? 0;
440
+ if (p.maxDepth < 0)
441
+ p.maxDepth = 1;
442
+ p.recallDepth = data.recallDepth ?? 0;
443
+ if (p.recallDepth <= 0)
444
+ p.recallDepth = p.maxDepth;
445
+ p.wordRecall = data.wordRecall ?? 0;
446
+ p.deepDescent = data.deepDescent ?? 0;
447
+ p.mhp = data.mhp;
448
+ p.chp = data.chp;
449
+ p.chpFrac = data.chpFrac;
450
+ p.msp = data.msp;
451
+ p.csp = data.csp;
452
+ p.cspFrac = data.cspFrac;
453
+ p.statMax = [...data.statMax];
454
+ p.statCur = [...data.statCur];
455
+ p.statMap = [...data.statMap];
456
+ p.statBirth = [...data.statBirth];
457
+ /* load.c:807-823 reads only supported timed entries and discards extras. */
458
+ p.timed.set(data.timed.slice(0, TMD_MAX));
459
+ p.spellFlags = [...data.spellFlags];
460
+ p.spellOrder = [...data.spellOrder];
461
+ p.playerHp = [...data.playerHp];
462
+ p.auBirth = data.auBirth;
463
+ p.htBirth = data.htBirth;
464
+ p.wtBirth = data.wtBirth;
465
+ /* full_name / died_from / noscore (load.c:661, load.c:966): absent in saves
466
+ * predating the fields, which restore the blankPlayer defaults ("" / "" / 0). */
467
+ p.fullName = data.fullName ?? "";
468
+ /* load.c:791-793 resets died_from whenever HP is non-negative. */
469
+ p.diedFrom = p.chp >= 0 ? "(alive and well)" : (data.diedFrom ?? "");
470
+ p.noscore = data.noscore ?? 0;
471
+ p.history = data.history;
472
+ p.hist = [];
473
+ for (const e of data.hist ?? []) {
474
+ let aIdx = 0;
475
+ const artifactName = e.artifactName ?? "";
476
+ if (artifactName) {
477
+ const artifact = objReg.artifacts.find((a) => a?.name === artifactName);
478
+ if (!artifact)
479
+ continue;
480
+ aIdx = artifact.aidx;
481
+ }
482
+ else if (e.aIdx !== undefined) {
483
+ /* Tolerate the pre-fix JSON shape, while all new saves use names. */
484
+ aIdx = e.aIdx;
485
+ }
486
+ p.hist.push({
487
+ type: e.type,
488
+ dlev: e.dlev,
489
+ clev: e.clev,
490
+ aIdx,
491
+ turn: e.turn,
492
+ event: e.event,
493
+ });
494
+ }
495
+ p.equipment = [...data.equipment];
496
+ if (data.objKnown) {
497
+ p.objKnown = {
498
+ modifiers: [...data.objKnown.modifiers],
499
+ toA: data.objKnown.toA,
500
+ toH: data.objKnown.toH,
501
+ toD: data.objKnown.toD,
502
+ /* Default to 1 for pre-field saves: dd/ds/ac are obvious birth knowledge
503
+ * (player_outfit), always 1, so an absent value restores exactly. */
504
+ dd: data.objKnown.dd ?? 1,
505
+ ds: data.objKnown.ds ?? 1,
506
+ ac: data.objKnown.ac ?? 1,
507
+ elInfo: data.objKnown.elInfo.map((e) => ({ ...e })),
508
+ flags: new FlagSet(Uint8Array.from(data.objKnown.flags)),
509
+ brands: deserializeBrandList(data.objKnown.brands, objReg, ids) ?? [],
510
+ slays: deserializeSlayList(data.objKnown.slays, objReg, ids) ?? [],
511
+ curses: deserializeKnownCurseList(data.objKnown.curses, objReg, ids),
512
+ };
513
+ }
514
+ else if (data.objKnownModifiers) {
515
+ /* Legacy pre-#13 save: only the modifier runes were tracked. */
516
+ p.objKnown.modifiers = [...data.objKnownModifiers];
517
+ }
518
+ p.shape =
519
+ data.shapeName !== null
520
+ ? (players.shapes.find((s) => s.name === data.shapeName) ?? null)
521
+ : null;
522
+ p.skills = [...data.skills];
523
+ p.upkeep = { ...data.upkeep };
524
+ p.quests = data.quests ? data.quests.map((q) => ({ ...q })) : [];
525
+ p.totalWinner = data.totalWinner ?? false;
526
+ return p;
527
+ }
528
+ /**
529
+ * Serialize the rolling message log (wr_messages, save.c:339-353): the newest
530
+ * `cap` messages (default 80, the upstream limit) written oldest-first, each as
531
+ * text + type. Returns undefined for an empty / absent log so a clean save omits
532
+ * the block. Faithful to the C: the per-entry repeat count is dropped, so a
533
+ * reload recollapses through MessageLog.add and every count resets to 1.
534
+ */
535
+ export function serializeMessages(log, cap = 80) {
536
+ if (!log || log.num() === 0)
537
+ return undefined;
538
+ const num = Math.min(log.num(), cap);
539
+ const out = [];
540
+ /* save.c:349 dumps oldest-of-the-kept first (i = num - 1 down to 0). */
541
+ for (let age = num - 1; age >= 0; age--) {
542
+ out.push({ str: log.str(age), type: log.type(age) });
543
+ }
544
+ return out;
545
+ }
546
+ /**
547
+ * Rebuild a message log from its saved form (rd_messages, load.c:471-495):
548
+ * re-add each entry oldest-first via MessageLog.add, exactly as upstream calls
549
+ * message_add in a forward loop. An absent block (older save / empty log) yields
550
+ * a fresh empty log.
551
+ */
552
+ export function deserializeMessages(data) {
553
+ const log = new MessageLog();
554
+ if (!data)
555
+ return log;
556
+ for (const m of data)
557
+ log.add(m.str, m.type);
558
+ return log;
559
+ }
560
+ /** Build the feature legend for every fidx appearing in the terrain grids. */
561
+ function buildFeatLegend(feats, known, ids) {
562
+ const present = new Set();
563
+ for (const f of feats)
564
+ present.add(f);
565
+ for (const f of known)
566
+ present.add(f);
567
+ const legend = [];
568
+ for (const f of present) {
569
+ /* Skip sentinels (an unset cell is -1): they carry no feature id and are
570
+ * pack-independent, so remapFeats leaves them untouched. */
571
+ const id = ids.featIdOrNull(f);
572
+ if (id !== null)
573
+ legend.push([f, id]);
574
+ }
575
+ return legend;
576
+ }
577
+ /** aup_info boolean[] (by aidx) -> the ids of the created artifacts. */
578
+ function serializeArtifactsCreated(created, ids) {
579
+ const out = [];
580
+ for (let i = 1; i < created.length; i++) {
581
+ if (created[i])
582
+ out.push(ids.artifactId(i));
583
+ }
584
+ return out;
585
+ }
586
+ /** Serialize one aup_info boolean field as stable artifact names. */
587
+ function serializeArtifactFlags(flags, ids) {
588
+ const out = [];
589
+ for (let i = 1; i < flags.length; i++) {
590
+ if (flags[i])
591
+ out.push(ids.artifactId(i));
592
+ }
593
+ return out;
594
+ }
595
+ /** Serialize a live game (state + flavor knowledge) into plain JSON data. */
596
+ export function serializeGame(state, flavor, seedFlavor, ids, randartSeed = 0, everseen) {
597
+ const floor = [];
598
+ for (const pile of state.floor.values()) {
599
+ const head = pile[0];
600
+ if (!head || !head.grid)
601
+ continue;
602
+ floor.push({
603
+ x: head.grid.x,
604
+ y: head.grid.y,
605
+ objs: pile.map((o) => serializeObject(o, ids)),
606
+ });
607
+ }
608
+ const traps = [];
609
+ for (const list of state.traps.values()) {
610
+ const head = list[0];
611
+ if (!head)
612
+ continue;
613
+ traps.push({
614
+ x: head.grid.x,
615
+ y: head.grid.y,
616
+ traps: list.map((t) => ({
617
+ trapId: ids.trapId(t.tidx),
618
+ grid: { x: t.grid.x, y: t.grid.y },
619
+ power: t.power,
620
+ timeout: t.timeout,
621
+ flags: Array.from(t.flags.bits),
622
+ })),
623
+ });
624
+ }
625
+ /* The noise/scent seam (mod/hooks.ts saveNoiseScent). Faithful 4.2.6 omits the
626
+ * heatmaps from the save - that is upstream's behaviour and upstream's bug - so
627
+ * with no hook installed the `?? false` below IS the faithful answer. */
628
+ const chunk = state.chunk.snapshotSquares(state.modHooks?.saveNoiseScent?.() ?? false);
629
+ const knownFeat = Array.from(state.known.feat);
630
+ const savedLevelCache = serializeLevelCache(state.levelCache, ids);
631
+ const autoinscriptions = state.autoinscribe
632
+ ? serializeAutoinscriptions(state.autoinscribe, ids)
633
+ : undefined;
634
+ /* wr_ignore's rune-autoinscription block (save.c:586-605): the count of runes
635
+ * carrying a note, then `wr_s16b(k)` + the note string for each. The index is
636
+ * converted to its pack-stable runeKey (see obj/knowledge.ts runeKey); a rune
637
+ * the running pack no longer builds is dropped. */
638
+ const runeNoteEntries = [];
639
+ const liveRuneNotes = state.runeNotes?.entries() ?? [];
640
+ if (liveRuneNotes.length > 0) {
641
+ const runes = buildRuneList(state.runeEnv);
642
+ for (const [i, note] of liveRuneNotes) {
643
+ const rune = runes[i];
644
+ if (!rune)
645
+ continue;
646
+ runeNoteEntries.push([runeKey(rune), note]);
647
+ }
648
+ }
649
+ const runeNotes = runeNoteEntries.length > 0 ? runeNoteEntries : undefined;
650
+ return {
651
+ version: SAVE_VERSION,
652
+ player: serializePlayer(state.actor.player, ids),
653
+ actor: {
654
+ grid: { x: state.actor.grid.x, y: state.actor.grid.y },
655
+ energy: state.actor.energy,
656
+ totalEnergy: state.actor.totalEnergy,
657
+ },
658
+ gear: {
659
+ next: state.gear.next,
660
+ pack: [...state.gear.pack],
661
+ store: Array.from(state.gear.store.entries()).map(([h, obj]) => [
662
+ h,
663
+ serializeObject(obj, ids),
664
+ ]),
665
+ },
666
+ /* C save.c:873-1045 omits the live dungeon objects, monsters, traps and
667
+ * chunk-list data for a dead player. */
668
+ ...(state.isDead
669
+ ? { dungeonDepth: state.chunk.depth }
670
+ : {
671
+ chunk,
672
+ featLegend: buildFeatLegend(chunk.feats, knownFeat, ids),
673
+ monsters: state.monsters.map((m) => m ? serializeMonster(m, ids) : null),
674
+ groups: state.groups.map((g) => g ? { index: g.index, leader: g.leader, members: [...g.members] } : null),
675
+ floor,
676
+ traps,
677
+ }),
678
+ rng: state.rng.getState(),
679
+ turn: state.turn,
680
+ playing: state.playing,
681
+ isDead: state.isDead,
682
+ flavor: (() => {
683
+ const raw = flavor.snapshot();
684
+ return {
685
+ aware: kidxSetToIds(raw.aware, ids),
686
+ tried: kidxSetToIds(raw.tried, ids),
687
+ };
688
+ })(),
689
+ ...(everseen
690
+ ? {
691
+ everseen: (() => {
692
+ const raw = everseen.snapshot();
693
+ const egos = [];
694
+ for (const eidx of raw.egos) {
695
+ const id = ids.egoIdOrNull(eidx);
696
+ if (id !== null)
697
+ egos.push(id);
698
+ }
699
+ return { kinds: kidxSetToIds(raw.kinds, ids), egos };
700
+ })(),
701
+ }
702
+ : {}),
703
+ seedFlavor,
704
+ ...(state.options ? { options: state.options.snapshot() } : {}),
705
+ ...(randartSeed ? { randartSeed } : {}),
706
+ ...(state.artifacts
707
+ ? {
708
+ artifactsCreated: serializeArtifactsCreated(state.artifacts.snapshot(), ids),
709
+ artifactsSeen: serializeArtifactFlags(state.artifacts.snapshotState().seen, ids),
710
+ artifactsEverseen: serializeArtifactFlags(state.artifacts.snapshotState().everseen, ids),
711
+ }
712
+ : {}),
713
+ ...(!state.isDead && savedLevelCache ? { levelCache: savedLevelCache } : {}),
714
+ /* chunk->join of the level in play (gap 9.4/9.6): persisted so a first-visit
715
+ * persistent level aligns its stairs after a reload. Omitted when empty. */
716
+ ...(!state.isDead && state.currentJoins && state.currentJoins.length > 0
717
+ ? {
718
+ currentJoins: state.currentJoins.map((j) => ({
719
+ x: j.grid.x,
720
+ y: j.grid.y,
721
+ feat: j.feat,
722
+ /* save.c:850-866 writes x, y, feature and every SQUARE_SIZE byte. */
723
+ info: Array.from({ length: SQUARE_SIZE }, (_, i) => j.info?.[i] ?? 0),
724
+ })),
725
+ }
726
+ : {}),
727
+ ...(autoinscriptions ? { autoinscriptions } : {}),
728
+ ...(runeNotes ? { runeNotes } : {}),
729
+ /*
730
+ * Terrain-only Town cache (wr_chunks, save.c:1001-1044): C always writes
731
+ * the Town chunk even when birth_levels_persist is off, so a dungeon save
732
+ * after leaving town reloads the same shops/stairs without redrawing.
733
+ */
734
+ ...(() => {
735
+ if (state.isDead || !state.townChunk)
736
+ return {};
737
+ const tc = state.townChunk.snapshotSquares();
738
+ return {
739
+ townChunk: tc,
740
+ townFeatLegend: buildFeatLegend(tc.feats, [], ids),
741
+ };
742
+ })(),
743
+ /* Town stores + accrued daycount (wr_stores / save.c:963). Persisted so the
744
+ * home stash and shop stock survive save/load (gaps 12.1/12.2/12.3). */
745
+ ...(() => {
746
+ const stores = serializeStores(state.stores, ids);
747
+ return stores ? { stores } : {};
748
+ })(),
749
+ ...(state.daycount ? { daycount: state.daycount } : {}),
750
+ /* Minor persisted player fields (gap 12.6, wr_player). Omitted when at their
751
+ * defaults so a clean save stays clean and old saves load with 0. */
752
+ ...(state.restingTurn ? { restingTurn: state.restingTurn } : {}),
753
+ ...(state.skipCmdCoercion ? { skipCmdCoercion: state.skipCmdCoercion } : {}),
754
+ ...(state.unignoring ? { unignoring: state.unignoring } : {}),
755
+ ...(state.nameSuffix ? { nameSuffix: state.nameSuffix } : {}),
756
+ /* Running message log (gap 12.8, wr_messages): the 80 newest messages,
757
+ * oldest-first. Omitted for an empty log. */
758
+ ...(() => {
759
+ const messages = serializeMessages(state.messages);
760
+ return messages ? { messages } : {};
761
+ })(),
762
+ ...(!state.isDead
763
+ ? {
764
+ known: {
765
+ feat: knownFeat,
766
+ objects: Array.from(state.known.objects.entries()).map(([i, m]) => [
767
+ i,
768
+ { ch: m.ch, attr: m.attr },
769
+ ]),
770
+ },
771
+ }
772
+ : {}),
773
+ ...(state.arenaLevel
774
+ ? {
775
+ arena: {
776
+ oldGrid: {
777
+ x: state.oldGrid?.x ?? state.actor.grid.x,
778
+ y: state.oldGrid?.y ?? state.actor.grid.y,
779
+ },
780
+ },
781
+ }
782
+ : {}),
783
+ ignore: serializeIgnore(state.ignore.snapshot(), ids),
784
+ lore: Array.from(state.lore.entries()).map(([ridx, l]) => [
785
+ ids.raceId(ridx),
786
+ {
787
+ sights: l.sights,
788
+ deaths: l.deaths,
789
+ pkills: l.pkills,
790
+ thefts: l.thefts,
791
+ tkills: l.tkills,
792
+ wake: l.wake,
793
+ ignore: l.ignore,
794
+ dropGold: l.dropGold,
795
+ dropItem: l.dropItem,
796
+ castInnate: l.castInnate,
797
+ castSpell: l.castSpell,
798
+ blowTimesSeen: [...l.blowTimesSeen],
799
+ blowKnown: [...l.blowKnown],
800
+ flags: Array.from(l.flags.bits),
801
+ spellFlags: Array.from(l.spellFlags.bits),
802
+ allKnown: l.allKnown,
803
+ armourKnown: l.armourKnown,
804
+ dropKnown: l.dropKnown,
805
+ sleepKnown: l.sleepKnown,
806
+ spellFreqKnown: l.spellFreqKnown,
807
+ innateFreqKnown: l.innateFreqKnown,
808
+ },
809
+ ]),
810
+ };
811
+ }
812
+ /** Rebuild the monster memory (absent in older saves: none). */
813
+ export function deserializeLore(data, ids) {
814
+ const store = new Map();
815
+ if (!data)
816
+ return store;
817
+ for (const [raceId, l] of data) {
818
+ const ridx = ids.raceIndex(raceId);
819
+ if (ridx === undefined)
820
+ continue; // race gone (mod removed): drop its lore
821
+ store.set(ridx, {
822
+ sights: l.sights,
823
+ deaths: l.deaths,
824
+ pkills: l.pkills,
825
+ thefts: l.thefts,
826
+ tkills: l.tkills,
827
+ wake: l.wake,
828
+ ignore: l.ignore,
829
+ dropGold: l.dropGold,
830
+ dropItem: l.dropItem,
831
+ castInnate: l.castInnate,
832
+ castSpell: l.castSpell,
833
+ blowTimesSeen: [...l.blowTimesSeen],
834
+ blowKnown: [...l.blowKnown],
835
+ flags: new FlagSet(Uint8Array.from(l.flags)),
836
+ spellFlags: new FlagSet(Uint8Array.from(l.spellFlags)),
837
+ allKnown: l.allKnown,
838
+ armourKnown: l.armourKnown,
839
+ dropKnown: l.dropKnown,
840
+ sleepKnown: l.sleepKnown,
841
+ spellFreqKnown: l.spellFreqKnown,
842
+ innateFreqKnown: l.innateFreqKnown,
843
+ });
844
+ }
845
+ return store;
846
+ }
847
+ /**
848
+ * Serialize the per-kind autoinscription registry (obj/knowledge.ts): every
849
+ * kind with a registered note, keyed by its namespaced kind id (mod-stable,
850
+ * like serializeObject). Returns undefined when nothing is registered, so a
851
+ * clean game omits the block entirely. A kind whose id no longer resolves
852
+ * (unbound in this pack) is dropped.
853
+ */
854
+ export function serializeAutoinscriptions(registry, ids) {
855
+ const out = [];
856
+ for (const [kidx, note] of registry.entries()) {
857
+ const kindId = ids.kindIdOrNull(kidx);
858
+ if (kindId === null)
859
+ continue; // kind unbound in this pack: drop
860
+ const entry = { kindId };
861
+ if (note.aware !== undefined)
862
+ entry.aware = note.aware;
863
+ if (note.unaware !== undefined)
864
+ entry.unaware = note.unaware;
865
+ out.push(entry);
866
+ }
867
+ return out.length > 0 ? out : undefined;
868
+ }
869
+ /**
870
+ * Restore serialized autoinscriptions into a registry (absent in older saves:
871
+ * nothing to restore). A kind whose id is gone (its defining pack was removed)
872
+ * is dropped, exactly like deserializeLore drops a removed race's memory.
873
+ */
874
+ export function deserializeAutoinscriptions(data, registry, ids) {
875
+ for (const entry of data) {
876
+ const kidx = ids.kindIndex(entry.kindId);
877
+ if (kidx === undefined)
878
+ continue; // kind gone (mod removed): drop its notes
879
+ if (entry.aware !== undefined)
880
+ registry.set(kidx, entry.aware, true);
881
+ if (entry.unaware !== undefined)
882
+ registry.set(kidx, entry.unaware, false);
883
+ }
884
+ }
885
+ /**
886
+ * Convert an IgnoreSettings.snapshot() (raw kidx/eidx, the runtime keying
887
+ * upstream also uses) into the id-keyed savefile form. A kind or ego the
888
+ * running pack no longer binds is dropped, like deserializeAutoinscriptions.
889
+ */
890
+ export function serializeIgnore(data, ids) {
891
+ const ego = [];
892
+ for (const key of data.ego) {
893
+ const sep = key.indexOf(":");
894
+ const eidx = Number(key.slice(0, sep));
895
+ const itype = Number(key.slice(sep + 1));
896
+ const egoId = ids.egoIdOrNull(eidx);
897
+ if (egoId === null)
898
+ continue;
899
+ ego.push([egoId, itype]);
900
+ }
901
+ const kindIds = (kidxs) => {
902
+ const out = [];
903
+ for (const kidx of kidxs) {
904
+ const id = ids.kindIdOrNull(kidx);
905
+ if (id !== null)
906
+ out.push(id);
907
+ }
908
+ return out;
909
+ };
910
+ return {
911
+ level: [...data.level],
912
+ ego,
913
+ kindAware: kindIds(data.kindAware),
914
+ kindUnaware: kindIds(data.kindUnaware),
915
+ unignoring: data.unignoring ?? false,
916
+ };
917
+ }
918
+ /** The inverse of serializeIgnore; an id the pack no longer binds is dropped. */
919
+ export function deserializeIgnore(data, ids) {
920
+ const ego = [];
921
+ for (const [egoId, itype] of data.ego) {
922
+ const eidx = ids.egoIndex(egoId);
923
+ if (eidx === undefined)
924
+ continue;
925
+ ego.push(`${eidx}:${itype}`);
926
+ }
927
+ const kidxs = (idList) => {
928
+ const out = [];
929
+ for (const id of idList) {
930
+ const kidx = ids.kindIndex(id);
931
+ if (kidx !== undefined)
932
+ out.push(kidx);
933
+ }
934
+ return out;
935
+ };
936
+ return {
937
+ level: [...data.level],
938
+ ego,
939
+ kindAware: kidxs(data.kindAware),
940
+ kindUnaware: kidxs(data.kindUnaware),
941
+ unignoring: data.unignoring ?? false,
942
+ };
943
+ }
944
+ /**
945
+ * kind->aware / kind->tried (wr_object_memory) and kind/ego ->everseen, by id.
946
+ * Same reasoning as serializeIgnore: upstream writes them positionally, the
947
+ * port's document keys them by namespaced id.
948
+ */
949
+ function kidxSetToIds(kidxs, ids) {
950
+ const out = [];
951
+ for (const kidx of kidxs) {
952
+ const id = ids.kindIdOrNull(kidx);
953
+ if (id !== null)
954
+ out.push(id);
955
+ }
956
+ return out;
957
+ }
958
+ function idsToKidxSet(idList, ids) {
959
+ const out = [];
960
+ for (const id of idList) {
961
+ const kidx = ids.kindIndex(id);
962
+ if (kidx !== undefined)
963
+ out.push(kidx);
964
+ }
965
+ return out;
966
+ }
967
+ /** Restore the id-keyed flavor block into the raw-kidx form FlavorKnowledge takes. */
968
+ export function deserializeFlavor(data, ids) {
969
+ return {
970
+ aware: idsToKidxSet(data.aware, ids),
971
+ tried: idsToKidxSet(data.tried, ids),
972
+ };
973
+ }
974
+ /** Restore the id-keyed everseen block into the raw-index form it takes. */
975
+ export function deserializeEverseen(data, ids) {
976
+ const egos = [];
977
+ for (const id of data.egos) {
978
+ const eidx = ids.egoIndex(id);
979
+ if (eidx !== undefined)
980
+ egos.push(eidx);
981
+ }
982
+ return { kinds: idsToKidxSet(data.kinds, ids), egos };
983
+ }
984
+ /**
985
+ * Build the feature index remap from a save's legend: each saved fidx maps to
986
+ * the current pack's index for the same feature id. When the save and the
987
+ * running pack agree (the common case), every entry is the identity; the map
988
+ * is still applied so a re-ordered or extended terrain set loads correctly.
989
+ * Throws on a legend id the current pack cannot resolve (a removed terrain -
990
+ * graceful degradation is a Phase 2 quarantine concern).
991
+ */
992
+ export function buildFeatRemap(legend, ids) {
993
+ const remap = new Map();
994
+ if (!legend)
995
+ return remap;
996
+ for (const [oldFidx, id] of legend) {
997
+ const newFidx = ids.featIndex(id);
998
+ if (newFidx === undefined) {
999
+ throw new Error(`save: unknown terrain feature ${id}`);
1000
+ }
1001
+ remap.set(oldFidx, newFidx);
1002
+ }
1003
+ return remap;
1004
+ }
1005
+ /** Apply a feature remap to a terrain index array in place (identity-safe). */
1006
+ function remapFeats(feats, remap) {
1007
+ if (remap.size === 0)
1008
+ return [...feats];
1009
+ return feats.map((feat) => remap.get(feat) ?? feat);
1010
+ }
1011
+ /** Rebuild the map knowledge (absent in older saves: all unknown). */
1012
+ export function deserializeKnown(data, width, height, featRemap) {
1013
+ const known = newKnownMap(width, height);
1014
+ if (!data)
1015
+ return known;
1016
+ const feat = remapFeats(data.feat.slice(0, known.feat.length), featRemap);
1017
+ known.feat.set(feat);
1018
+ for (const [i, m] of data.objects) {
1019
+ known.objects.set(i, { ch: m.ch, attr: m.attr });
1020
+ }
1021
+ return known;
1022
+ }
1023
+ /** Rebuild a Gear store from its saved form. */
1024
+ export function deserializeGear(data, reg, ids) {
1025
+ const store = new Map();
1026
+ for (const [h, saved] of data.store) {
1027
+ store.set(h, deserializeObject(saved, reg, ids));
1028
+ }
1029
+ return { store, next: data.next, pack: [...data.pack] };
1030
+ }
1031
+ /** Rebuild the floor pile map (grid-keyed, pile order preserved). */
1032
+ export function deserializeFloor(data, reg, width, ids) {
1033
+ const floor = new Map();
1034
+ for (const entry of data ?? []) {
1035
+ floor.set(entry.y * width + entry.x, entry.objs.map((o) => deserializeObject(o, reg, ids)));
1036
+ }
1037
+ return floor;
1038
+ }
1039
+ /**
1040
+ * Rebuild the trap map from saved instances against the bound kinds. This is
1041
+ * rd_trap (load.c:359) plus its caller rd_traps_aux (L1473): the per-trap read
1042
+ * is not a separate function here because the port stores traps per grid rather
1043
+ * than as a linked list off the square.
1044
+ */
1045
+ export function deserializeTraps(data, kinds, width, ids, onDecoy) {
1046
+ const traps = new Map();
1047
+ for (const entry of data ?? []) {
1048
+ traps.set(entry.y * width + entry.x, entry.traps.map((t) => {
1049
+ const tidx = ids.trapIndex(t.trapId);
1050
+ const kind = tidx !== undefined ? kinds[tidx] : undefined;
1051
+ if (kind === undefined || tidx === undefined) {
1052
+ throw new Error(`save: unknown trap kind ${t.trapId}`);
1053
+ }
1054
+ const grid = loc(t.grid.x, t.grid.y);
1055
+ if (kind.name === "decoy" || kind.desc === "decoy")
1056
+ onDecoy?.(grid);
1057
+ return {
1058
+ tidx,
1059
+ kind,
1060
+ grid,
1061
+ power: t.power,
1062
+ timeout: t.timeout,
1063
+ flags: new FlagSet(Uint8Array.from(t.flags)),
1064
+ };
1065
+ }));
1066
+ }
1067
+ return traps;
1068
+ }
1069
+ /**
1070
+ * Serialize the live town stores (wr_stores): each shop's proprietor and stock,
1071
+ * in registry order. Returns undefined when the game has no stores yet (never
1072
+ * reached town), so a fresh dungeon-start save omits the block entirely.
1073
+ */
1074
+ export function serializeStores(stores, ids) {
1075
+ if (!stores || stores.length === 0)
1076
+ return undefined;
1077
+ return stores.map((store) => ({
1078
+ ownerIndex: store.owner.index,
1079
+ stock: store.stock.map((o) => serializeObject(o, ids)),
1080
+ }));
1081
+ }
1082
+ /**
1083
+ * Rebuild the live town stores (rd_stores): re-bind each store's immutable
1084
+ * tables from the pack (owners, stocking tables, buy list, bounds) and overlay
1085
+ * the saved proprietor + stock. Matches upstream's positional keying (store i
1086
+ * <-> saved i). Draws NO RNG - the caller has already restored the exact
1087
+ * stream, so store restore must not perturb it (decision 22). A saved store
1088
+ * beyond the current registry length is dropped; a registry store with no saved
1089
+ * counterpart keeps an empty, default-owner shell (re-stocked on town entry).
1090
+ */
1091
+ export function deserializeStores(bound, saved, reg, ids, storeInvenMax) {
1092
+ return bound.map((b, i) => {
1093
+ const s = saved?.[i];
1094
+ const owner = (s ? b.owners.find((o) => o.index === s.ownerIndex) : undefined) ??
1095
+ b.owners[0];
1096
+ if (!owner)
1097
+ throw new Error(`save: store ${b.featName} has no owners`);
1098
+ return {
1099
+ feat: b.feat,
1100
+ featName: b.featName,
1101
+ owners: b.owners,
1102
+ owner,
1103
+ alwaysTable: b.alwaysTable,
1104
+ normalTable: b.normalTable,
1105
+ buy: b.buy,
1106
+ turnover: b.turnover,
1107
+ normalStockMin: b.normalStockMin,
1108
+ normalStockMax: b.normalStockMax,
1109
+ stock: s ? s.stock.map((o) => deserializeObject(o, reg, ids)) : [],
1110
+ stockSize: storeInvenMax,
1111
+ };
1112
+ });
1113
+ }
1114
+ /** aup_info id list -> the boolean[] by aidx that ArtifactState.restore wants. */
1115
+ export function deserializeArtifactsCreated(saved, length, ids) {
1116
+ const out = new Array(length).fill(false);
1117
+ if (!saved)
1118
+ return out;
1119
+ for (const id of saved) {
1120
+ const i = ids.artifactIndex(id);
1121
+ if (i !== undefined && i < length)
1122
+ out[i] = true;
1123
+ }
1124
+ return out;
1125
+ }
1126
+ /** Restore one aup_info boolean field from stable artifact ids. */
1127
+ export function deserializeArtifactFlags(saved, length, ids) {
1128
+ const out = new Array(length).fill(false);
1129
+ for (const id of saved ?? []) {
1130
+ const i = ids.artifactIndex(id);
1131
+ if (i !== undefined && i < length)
1132
+ out[i] = true;
1133
+ }
1134
+ return out;
1135
+ }
1136
+ /**
1137
+ * Rebuild a chunk of the saved dimensions and restore its squares, remapping
1138
+ * the terrain grid through the save's feature legend so feature references
1139
+ * survive a pack change.
1140
+ */
1141
+ export function deserializeChunk(data, features, featRemap) {
1142
+ const chunk = new Chunk(features, data.height, data.width);
1143
+ /* load.c:1307-1355 decodes into a fresh cave. Keep the JSON source intact
1144
+ * while applying the equivalent feature remap to fresh data. */
1145
+ const remapped = featRemap.size > 0
1146
+ ? { ...data, feats: remapFeats(data.feats, featRemap) }
1147
+ : data;
1148
+ chunk.restoreSquares(remapped);
1149
+ return chunk;
1150
+ }
1151
+ /** Serialize one frozen level, reusing the current-level serializers. */
1152
+ function serializeStoredLevel(depth, level, ids) {
1153
+ const floor = [];
1154
+ for (const pile of level.floor.values()) {
1155
+ const head = pile[0];
1156
+ if (!head || !head.grid)
1157
+ continue;
1158
+ floor.push({
1159
+ x: head.grid.x,
1160
+ y: head.grid.y,
1161
+ objs: pile.map((o) => serializeObject(o, ids)),
1162
+ });
1163
+ }
1164
+ const traps = [];
1165
+ for (const list of level.traps.values()) {
1166
+ const head = list[0];
1167
+ if (!head)
1168
+ continue;
1169
+ traps.push({
1170
+ x: head.grid.x,
1171
+ y: head.grid.y,
1172
+ traps: list.map((t) => ({
1173
+ trapId: ids.trapId(t.tidx),
1174
+ grid: { x: t.grid.x, y: t.grid.y },
1175
+ power: t.power,
1176
+ timeout: t.timeout,
1177
+ flags: Array.from(t.flags.bits),
1178
+ })),
1179
+ });
1180
+ }
1181
+ const chunk = level.chunk.snapshotSquares();
1182
+ const knownFeat = Array.from(level.known.feat);
1183
+ return {
1184
+ depth,
1185
+ turn: level.turn,
1186
+ chunk,
1187
+ featLegend: buildFeatLegend(chunk.feats, knownFeat, ids),
1188
+ monsters: level.monsters.map((m) => (m ? serializeMonster(m, ids) : null)),
1189
+ groups: level.groups.map((g) => g ? { index: g.index, leader: g.leader, members: [...g.members] } : null),
1190
+ floor,
1191
+ traps,
1192
+ known: {
1193
+ feat: knownFeat,
1194
+ objects: Array.from(level.known.objects.entries()).map(([i, m]) => [
1195
+ i,
1196
+ { ch: m.ch, attr: m.attr },
1197
+ ]),
1198
+ },
1199
+ decoy: level.decoy ? { x: level.decoy.x, y: level.decoy.y } : null,
1200
+ join: level.join.map((j) => ({
1201
+ x: j.grid.x,
1202
+ y: j.grid.y,
1203
+ feat: j.feat,
1204
+ info: Array.from({ length: SQUARE_SIZE }, (_, i) => j.info?.[i] ?? 0),
1205
+ })),
1206
+ };
1207
+ }
1208
+ /** Serialize the whole frozen-level cache (empty / absent => omitted). */
1209
+ export function serializeLevelCache(cache, ids) {
1210
+ if (!cache || cache.size === 0)
1211
+ return undefined;
1212
+ return Array.from(cache.entries()).map(([depth, level]) => serializeStoredLevel(depth, level, ids));
1213
+ }
1214
+ /**
1215
+ * Rebuild the frozen-level cache (absent in older / default saves: empty).
1216
+ * Reuses the current-level deserializers so a cached level round-trips exactly
1217
+ * like the live one, including per-level feature-legend remapping.
1218
+ */
1219
+ export function deserializeLevelCache(data, features, monsters, objects, traps, ids) {
1220
+ const cache = new Map();
1221
+ if (!data)
1222
+ return cache;
1223
+ for (const entry of data) {
1224
+ const featRemap = buildFeatRemap(entry.featLegend, ids);
1225
+ const chunk = deserializeChunk(entry.chunk, features, featRemap);
1226
+ chunk.turn = entry.turn;
1227
+ cache.set(entry.depth, {
1228
+ chunk,
1229
+ monsters: entry.monsters.map((m) => m ? deserializeMonster(m, monsters, objects, ids) : null),
1230
+ groups: entry.groups.map((g) => g
1231
+ ? { index: g.index, leader: g.leader, members: [...g.members] }
1232
+ : null),
1233
+ floor: deserializeFloor(entry.floor, objects, chunk.width, ids),
1234
+ traps: traps
1235
+ ? deserializeTraps(entry.traps, traps, chunk.width, ids)
1236
+ : new Map(),
1237
+ known: deserializeKnown(entry.known, chunk.width, chunk.height, featRemap),
1238
+ decoy: entry.decoy ? loc(entry.decoy.x, entry.decoy.y) : null,
1239
+ turn: entry.turn,
1240
+ /* chunk->join stair connectors; tolerate absence for pre-field saves. */
1241
+ /* load.c:1366-1383 restores connector info; load.c:1653-1678 remaps
1242
+ * the saved feature through the current feature table. */
1243
+ join: (entry.join ?? []).map((j) => ({
1244
+ grid: loc(j.x, j.y),
1245
+ feat: featRemap.get(j.feat) ?? j.feat,
1246
+ ...(j.info ? { info: [...j.info] } : {}),
1247
+ })),
1248
+ });
1249
+ }
1250
+ return cache;
1251
+ }
1252
+ /* ------------------------------------------------------------------ *
1253
+ * Stamped bytes (the file/localStorage form).
1254
+ * ------------------------------------------------------------------ */
1255
+ /**
1256
+ * JSON-encode a save, optionally compress it, and stamp it with the integrity
1257
+ * trailer (16b).
1258
+ *
1259
+ * ORDER: JSON -> codec -> stamp. The digest therefore covers the bytes that are
1260
+ * actually stored, and the trailer stays findable without running a decompressor
1261
+ * first - which matters because an unknown codec must still be diagnosable.
1262
+ * Passing no codec writes the bare JSON every earlier build wrote.
1263
+ */
1264
+ export function encodeSavedGame(save, provider = fnv1aIntegrity, codec) {
1265
+ const json = new TextEncoder().encode(JSON.stringify(save));
1266
+ return stampSavefile(codec ? applyCodec(json, codec) : json, provider);
1267
+ }
1268
+ /**
1269
+ * Verify and parse stamped save bytes. A failed digest still parses (the
1270
+ * warn-and-label posture of decision 16b - the deterrent is honest, not a
1271
+ * lock), with verified=false for the caller to surface.
1272
+ *
1273
+ * `codecs` are the compressors this build can run. An uncompressed save needs
1274
+ * none, so a caller that never compresses can keep ignoring this argument.
1275
+ */
1276
+ export function decodeSavedGame(bytes, provider = fnv1aIntegrity, codecs = []) {
1277
+ const result = verifyStampedSavefile(bytes, provider);
1278
+ const { codecId, body } = stripCodec(result.payload);
1279
+ const base = {
1280
+ verified: result.verified,
1281
+ unstamped: result.unstamped ?? false,
1282
+ codecId,
1283
+ };
1284
+ let payload = body;
1285
+ if (codecId !== null) {
1286
+ const codec = findCodec(codecId, codecs);
1287
+ if (!codec)
1288
+ return { ...base, save: null, unknownCodec: codecId };
1289
+ try {
1290
+ payload = codec.decompress(body);
1291
+ }
1292
+ catch {
1293
+ /* A codec we HAVE that cannot read these bytes is genuine damage. */
1294
+ return { ...base, save: null };
1295
+ }
1296
+ }
1297
+ let save = null;
1298
+ try {
1299
+ save = JSON.parse(new TextDecoder().decode(payload));
1300
+ }
1301
+ catch {
1302
+ save = null;
1303
+ }
1304
+ return { ...base, save };
1305
+ }
1306
+ //# sourceMappingURL=save.js.map