@shipload/sdk 1.0.0-next.16 → 1.0.0-next.18

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 (41) hide show
  1. package/lib/shipload.d.ts +111 -26
  2. package/lib/shipload.js +3443 -2896
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +3416 -2884
  5. package/lib/shipload.m.js.map +1 -1
  6. package/lib/testing.d.ts +3 -2
  7. package/lib/testing.js +65 -50
  8. package/lib/testing.js.map +1 -1
  9. package/lib/testing.m.js +66 -51
  10. package/lib/testing.m.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/capabilities/gathering.ts +17 -7
  13. package/src/capabilities/modules.ts +6 -0
  14. package/src/contracts/server.ts +7 -4
  15. package/src/data/capabilities.ts +6 -1
  16. package/src/data/capability-formulas.ts +7 -1
  17. package/src/data/colors.ts +12 -12
  18. package/src/data/item-ids.ts +13 -12
  19. package/src/data/items.json +30 -23
  20. package/src/data/metadata.ts +36 -23
  21. package/src/data/recipes.json +111 -46
  22. package/src/derivation/capabilities.ts +18 -7
  23. package/src/derivation/capability-mappings.ts +2 -0
  24. package/src/derivation/index.ts +7 -2
  25. package/src/derivation/reserve-regen.ts +34 -0
  26. package/src/derivation/resources.ts +9 -1
  27. package/src/derivation/stratum.ts +15 -19
  28. package/src/derivation/tiers.ts +28 -7
  29. package/src/index-module.ts +25 -3
  30. package/src/managers/actions.ts +104 -12
  31. package/src/managers/context.ts +9 -0
  32. package/src/managers/index.ts +2 -0
  33. package/src/managers/nft.ts +28 -0
  34. package/src/nft/atomicassets.ts +124 -1
  35. package/src/nft/buildImmutableData.ts +316 -0
  36. package/src/nft/description.ts +1 -3
  37. package/src/nft/index.ts +1 -0
  38. package/src/resolution/describe-module.ts +3 -4
  39. package/src/resolution/resolve-item.ts +0 -1
  40. package/src/shipload.ts +5 -0
  41. package/src/types.ts +1 -0
@@ -109,56 +109,63 @@ export const itemMetadata: Record<number, ItemMetadata> = {
109
109
 
110
110
  // === Components (T1) ===
111
111
  10001: {
112
- name: 'Hull Plates',
113
- description: 'Structural plating formed from ore. Used in hulls, containers, and frames.',
112
+ name: 'Plate',
113
+ description:
114
+ 'Structural plating formed from ore. Used in hulls, containers, and storage modules.',
114
115
  color: '#7B8D9E',
115
116
  },
116
117
  10002: {
117
- name: 'Cargo Lining',
118
+ name: 'Frame',
118
119
  description:
119
- 'Composite lining formed from fine regolith bound in biomass polymer. Dense enough to seal cargo holds, flexible enough to absorb vibration.',
120
+ 'Composite framing formed from fine regolith bound in biomass polymer. Dense enough to seal cargo holds, flexible enough to absorb vibration.',
120
121
  color: '#C4A57B',
121
122
  },
122
123
  10003: {
123
- name: 'Thruster Core',
124
- description: 'High-energy propulsion component formed from volatile gases.',
124
+ name: 'Plasma Cell',
125
+ description:
126
+ 'High-energy gaseous storage cell. Volatile gas held under controlled thermal conditions.',
125
127
  color: '#E86344',
126
128
  },
127
129
  10004: {
128
- name: 'Power Cell',
130
+ name: 'Resonator',
129
131
  description:
130
- 'Crystalline energy storage matrix. Resonant lattices retain and release charge.',
132
+ 'Crystalline resonance lattice. Stores and releases charge through coherent oscillation.',
131
133
  color: '#4ADBFF',
132
134
  },
133
135
  10005: {
134
- name: 'Matter Conduit',
135
- description: 'Heavy-duty ore shaft used in gathering equipment.',
136
+ name: 'Beam',
137
+ description:
138
+ 'Heavy-duty structural beam machined from refined ore. Strong enough to bear load, tolerant enough to survive harsh environments.',
136
139
  color: '#7B8D9E',
137
140
  },
138
141
  10006: {
139
- name: 'Survey Probe',
140
- description: 'Crystal-lattice sensor array for deep resource detection.',
142
+ name: 'Sensor',
143
+ description:
144
+ 'Crystal-lattice sensing element with conductive and reflective properties. Reads signal and surface alike.',
141
145
  color: '#4ADBFF',
142
146
  },
143
147
  10007: {
144
- name: 'Cargo Arm',
145
- description: 'Flexible biomass composite arm for cargo handling.',
148
+ name: 'Polymer',
149
+ description:
150
+ 'Pliable biomass-derived polymer with high insulation. Flexible, durable, electrically inert.',
146
151
  color: '#5A8B3E',
147
152
  },
148
153
  10008: {
149
- name: 'Tool Bit',
150
- description: 'Dense regolith cutting head for crafting operations.',
154
+ name: 'Ceramic',
155
+ description:
156
+ 'Hardened fine-grained ceramic refined from regolith. Hard enough to cut, fine enough to finish.',
151
157
  color: '#C4A57B',
152
158
  },
153
159
  10009: {
154
- name: 'Reaction Chamber',
155
- description: 'Gas-pressurized vessel for controlled crafting reactions.',
160
+ name: 'Reactor',
161
+ description:
162
+ 'Gas-pressurized vessel for controlled reactions. Vents heat and contains volatility.',
156
163
  color: '#B8E4A0',
157
164
  },
158
165
  10010: {
159
- name: 'Focusing Array',
166
+ name: 'Emitter',
160
167
  description:
161
- "Precision-formed crystal lens array. Routes the haul beam's energy efficiently to the target lock.",
168
+ 'Precision-formed crystal emitter array. Routes energy efficiently to a target lock.',
162
169
  color: '#4ADBFF',
163
170
  },
164
171
 
@@ -206,6 +213,12 @@ export const itemMetadata: Record<number, ItemMetadata> = {
206
213
  'Folds local space-time around the hull, projecting the ship across vast distances in a single discharge of the entire energy reserve.',
207
214
  color: '#9be4ff',
208
215
  },
216
+ 10108: {
217
+ name: 'Battery',
218
+ description:
219
+ 'Extends energy capacity. Stores additional charge produced by generators, letting builds chain more high-drain actions between recharges.',
220
+ color: '#4ADBFF',
221
+ },
209
222
 
210
223
  // === Entities (packed, T1) ===
211
224
  10200: {
@@ -237,14 +250,14 @@ export const itemMetadata: Record<number, ItemMetadata> = {
237
250
 
238
251
  // === Components (T2) ===
239
252
  20001: {
240
- name: 'Hull Plates',
253
+ name: 'Plate',
241
254
  description: 'Advanced structural plating reinforced with tier 2 ore.',
242
255
  color: '#9BADB8',
243
256
  },
244
257
  20002: {
245
- name: 'Cargo Lining',
258
+ name: 'Frame',
246
259
  description:
247
- 'Advanced composite lining reinforced with tier 2 regolith and biomass polymer.',
260
+ 'Advanced composite framing reinforced with tier 2 regolith and biomass polymer.',
248
261
  color: '#C4A57B',
249
262
  },
250
263
 
@@ -1,12 +1,12 @@
1
1
  [
2
2
  {
3
3
  "outputItemId": 10001,
4
- "outputMass": 50000,
4
+ "outputMass": 420000,
5
5
  "inputs": [
6
6
  {
7
7
  "category": "ore",
8
8
  "tier": 1,
9
- "quantity": 15
9
+ "quantity": 20
10
10
  }
11
11
  ],
12
12
  "statSlots": [
@@ -31,12 +31,12 @@
31
31
  },
32
32
  {
33
33
  "outputItemId": 10002,
34
- "outputMass": 30000,
34
+ "outputMass": 600000,
35
35
  "inputs": [
36
36
  {
37
37
  "category": "regolith",
38
38
  "tier": 1,
39
- "quantity": 10
39
+ "quantity": 30
40
40
  },
41
41
  {
42
42
  "category": "biomass",
@@ -66,12 +66,12 @@
66
66
  },
67
67
  {
68
68
  "outputItemId": 10003,
69
- "outputMass": 50000,
69
+ "outputMass": 390000,
70
70
  "inputs": [
71
71
  {
72
72
  "category": "gas",
73
73
  "tier": 1,
74
- "quantity": 32
74
+ "quantity": 65
75
75
  }
76
76
  ],
77
77
  "statSlots": [
@@ -96,12 +96,17 @@
96
96
  },
97
97
  {
98
98
  "outputItemId": 10004,
99
- "outputMass": 30000,
99
+ "outputMass": 600000,
100
100
  "inputs": [
101
101
  {
102
102
  "category": "crystal",
103
103
  "tier": 1,
104
- "quantity": 20
104
+ "quantity": 25
105
+ },
106
+ {
107
+ "category": "biomass",
108
+ "tier": 1,
109
+ "quantity": 15
105
110
  }
106
111
  ],
107
112
  "statSlots": [
@@ -126,12 +131,17 @@
126
131
  },
127
132
  {
128
133
  "outputItemId": 10005,
129
- "outputMass": 50000,
134
+ "outputMass": 600000,
130
135
  "inputs": [
131
136
  {
132
137
  "category": "ore",
133
138
  "tier": 1,
134
- "quantity": 15
139
+ "quantity": 20
140
+ },
141
+ {
142
+ "category": "gas",
143
+ "tier": 1,
144
+ "quantity": 30
135
145
  }
136
146
  ],
137
147
  "statSlots": [
@@ -156,12 +166,12 @@
156
166
  },
157
167
  {
158
168
  "outputItemId": 10006,
159
- "outputMass": 30000,
169
+ "outputMass": 420000,
160
170
  "inputs": [
161
171
  {
162
172
  "category": "crystal",
163
173
  "tier": 1,
164
- "quantity": 10
174
+ "quantity": 30
165
175
  }
166
176
  ],
167
177
  "statSlots": [
@@ -186,12 +196,12 @@
186
196
  },
187
197
  {
188
198
  "outputItemId": 10007,
189
- "outputMass": 30000,
199
+ "outputMass": 420000,
190
200
  "inputs": [
191
201
  {
192
202
  "category": "biomass",
193
203
  "tier": 1,
194
- "quantity": 32
204
+ "quantity": 25
195
205
  }
196
206
  ],
197
207
  "statSlots": [
@@ -216,12 +226,12 @@
216
226
  },
217
227
  {
218
228
  "outputItemId": 10008,
219
- "outputMass": 30000,
229
+ "outputMass": 400000,
220
230
  "inputs": [
221
231
  {
222
232
  "category": "regolith",
223
233
  "tier": 1,
224
- "quantity": 20
234
+ "quantity": 45
225
235
  }
226
236
  ],
227
237
  "statSlots": [
@@ -246,12 +256,17 @@
246
256
  },
247
257
  {
248
258
  "outputItemId": 10009,
249
- "outputMass": 50000,
259
+ "outputMass": 590000,
250
260
  "inputs": [
251
261
  {
252
262
  "category": "gas",
253
263
  "tier": 1,
254
- "quantity": 32
264
+ "quantity": 40
265
+ },
266
+ {
267
+ "category": "regolith",
268
+ "tier": 1,
269
+ "quantity": 40
255
270
  }
256
271
  ],
257
272
  "statSlots": [
@@ -276,12 +291,17 @@
276
291
  },
277
292
  {
278
293
  "outputItemId": 10010,
279
- "outputMass": 40000,
294
+ "outputMass": 590000,
280
295
  "inputs": [
281
296
  {
282
297
  "category": "crystal",
283
298
  "tier": 1,
284
- "quantity": 25
299
+ "quantity": 20
300
+ },
301
+ {
302
+ "category": "ore",
303
+ "tier": 1,
304
+ "quantity": 15
285
305
  }
286
306
  ],
287
307
  "statSlots": [
@@ -306,7 +326,7 @@
306
326
  },
307
327
  {
308
328
  "outputItemId": 10100,
309
- "outputMass": 150000,
329
+ "outputMass": 940000,
310
330
  "inputs": [
311
331
  {
312
332
  "itemId": 10003,
@@ -335,11 +355,11 @@
335
355
  },
336
356
  {
337
357
  "outputItemId": 10101,
338
- "outputMass": 75000,
358
+ "outputMass": 1440000,
339
359
  "inputs": [
340
360
  {
341
361
  "itemId": 10004,
342
- "quantity": 5
362
+ "quantity": 6
343
363
  }
344
364
  ],
345
365
  "statSlots": [
@@ -364,11 +384,11 @@
364
384
  },
365
385
  {
366
386
  "outputItemId": 10102,
367
- "outputMass": 145000,
387
+ "outputMass": 1220000,
368
388
  "inputs": [
369
389
  {
370
390
  "itemId": 10005,
371
- "quantity": 4
391
+ "quantity": 3
372
392
  },
373
393
  {
374
394
  "itemId": 10006,
@@ -416,22 +436,18 @@
416
436
  },
417
437
  {
418
438
  "outputItemId": 10103,
419
- "outputMass": 90000,
439
+ "outputMass": 1010000,
420
440
  "inputs": [
421
- {
422
- "itemId": 10002,
423
- "quantity": 3
424
- },
425
441
  {
426
442
  "itemId": 10007,
427
- "quantity": 3
443
+ "quantity": 6
428
444
  }
429
445
  ],
430
446
  "statSlots": [
431
447
  {
432
448
  "sources": [
433
449
  {
434
- "inputIndex": 1,
450
+ "inputIndex": 0,
435
451
  "statIndex": 1
436
452
  }
437
453
  ]
@@ -439,7 +455,7 @@
439
455
  {
440
456
  "sources": [
441
457
  {
442
- "inputIndex": 1,
458
+ "inputIndex": 0,
443
459
  "statIndex": 0
444
460
  }
445
461
  ]
@@ -449,7 +465,7 @@
449
465
  },
450
466
  {
451
467
  "outputItemId": 10104,
452
- "outputMass": 120000,
468
+ "outputMass": 1190000,
453
469
  "inputs": [
454
470
  {
455
471
  "itemId": 10008,
@@ -482,15 +498,15 @@
482
498
  },
483
499
  {
484
500
  "outputItemId": 10105,
485
- "outputMass": 100000,
501
+ "outputMass": 1220000,
486
502
  "inputs": [
487
503
  {
488
504
  "itemId": 10001,
489
- "quantity": 8
505
+ "quantity": 3
490
506
  },
491
507
  {
492
508
  "itemId": 10002,
493
- "quantity": 4
509
+ "quantity": 3
494
510
  }
495
511
  ],
496
512
  "statSlots": [
@@ -531,7 +547,7 @@
531
547
  },
532
548
  {
533
549
  "outputItemId": 10106,
534
- "outputMass": 120000,
550
+ "outputMass": 1430000,
535
551
  "inputs": [
536
552
  {
537
553
  "itemId": 10004,
@@ -575,15 +591,15 @@
575
591
  },
576
592
  {
577
593
  "outputItemId": 10107,
578
- "outputMass": 180000,
594
+ "outputMass": 1420000,
579
595
  "inputs": [
580
596
  {
581
597
  "itemId": 10010,
582
- "quantity": 6
598
+ "quantity": 3
583
599
  },
584
600
  {
585
601
  "itemId": 10009,
586
- "quantity": 4
602
+ "quantity": 3
587
603
  }
588
604
  ],
589
605
  "statSlots": [
@@ -605,9 +621,58 @@
605
621
  1
606
622
  ]
607
623
  },
624
+ {
625
+ "outputItemId": 10108,
626
+ "outputMass": 970000,
627
+ "inputs": [
628
+ {
629
+ "itemId": 10003,
630
+ "quantity": 3
631
+ },
632
+ {
633
+ "itemId": 10007,
634
+ "quantity": 3
635
+ }
636
+ ],
637
+ "statSlots": [
638
+ {
639
+ "sources": [
640
+ {
641
+ "inputIndex": 0,
642
+ "statIndex": 0
643
+ }
644
+ ]
645
+ },
646
+ {
647
+ "sources": [
648
+ {
649
+ "inputIndex": 0,
650
+ "statIndex": 1
651
+ }
652
+ ]
653
+ },
654
+ {
655
+ "sources": [
656
+ {
657
+ "inputIndex": 1,
658
+ "statIndex": 0
659
+ }
660
+ ]
661
+ },
662
+ {
663
+ "sources": [
664
+ {
665
+ "inputIndex": 1,
666
+ "statIndex": 1
667
+ }
668
+ ]
669
+ }
670
+ ],
671
+ "blendWeights": []
672
+ },
608
673
  {
609
674
  "outputItemId": 10200,
610
- "outputMass": 80000,
675
+ "outputMass": 1490000,
611
676
  "inputs": [
612
677
  {
613
678
  "itemId": 10001,
@@ -656,7 +721,7 @@
656
721
  },
657
722
  {
658
723
  "outputItemId": 10201,
659
- "outputMass": 100000,
724
+ "outputMass": 2300000,
660
725
  "inputs": [
661
726
  {
662
727
  "itemId": 10001,
@@ -705,7 +770,7 @@
705
770
  },
706
771
  {
707
772
  "outputItemId": 10202,
708
- "outputMass": 1300000,
773
+ "outputMass": 5760000,
709
774
  "inputs": [
710
775
  {
711
776
  "itemId": 10001,
@@ -754,7 +819,7 @@
754
819
  },
755
820
  {
756
821
  "outputItemId": 10203,
757
- "outputMass": 800000,
822
+ "outputMass": 4440000,
758
823
  "inputs": [
759
824
  {
760
825
  "itemId": 10001,
@@ -803,7 +868,7 @@
803
868
  },
804
869
  {
805
870
  "outputItemId": 10204,
806
- "outputMass": 800000,
871
+ "outputMass": 5540000,
807
872
  "inputs": [
808
873
  {
809
874
  "itemId": 10001,
@@ -75,18 +75,15 @@ export function computeGathererCapabilities(
75
75
  yield: number
76
76
  drain: number
77
77
  depth: number
78
- speed: number
79
78
  } {
80
79
  const str = stats.strength
81
80
  const con = stats.conductivity
82
- const ref = stats.reflectivity
83
81
  const tol = stats.tolerance
84
82
 
85
83
  return {
86
84
  yield: 200 + str,
87
85
  drain: Math.max(250, 1250 - Math.floor((con * 25) / 20)),
88
86
  depth: gathererDepthForTier(tol, tier),
89
- speed: 100 + Math.floor((ref * 4) / 5),
90
87
  }
91
88
  }
92
89
 
@@ -163,6 +160,7 @@ import {
163
160
  } from '../data/item-ids'
164
161
  import {
165
162
  getModuleCapabilityType,
163
+ MODULE_BATTERY,
166
164
  MODULE_ENGINE,
167
165
  MODULE_GENERATOR,
168
166
  MODULE_GATHERER,
@@ -222,7 +220,7 @@ export interface ComputedCapabilities {
222
220
  capacity: number
223
221
  engines?: {thrust: number; drain: number}
224
222
  generator?: {capacity: number; recharge: number}
225
- gatherer?: {yield: number; drain: number; depth: number; speed: number}
223
+ gatherer?: {yield: number; drain: number; depth: number}
226
224
  loaders?: {mass: number; thrust: number; quantity: number}
227
225
  crafter?: {speed: number; drain: number}
228
226
  hauler?: {capacity: number; efficiency: number; drain: number}
@@ -251,7 +249,6 @@ export function computeEntityCapabilities(
251
249
  let totalGathYield = 0
252
250
  let totalGathDrain = 0
253
251
  let maxGathDepth = 0
254
- let totalGathSpeed = 0
255
252
  let hasGatherer = false
256
253
 
257
254
  let totalStorageBonus = 0
@@ -270,6 +267,9 @@ export function computeEntityCapabilities(
270
267
  let totalWarpRange = 0
271
268
  let hasWarp = false
272
269
 
270
+ let totalBatteryStatSum = 0
271
+ let batteryCount = 0
272
+
273
273
  for (const mod of modules) {
274
274
  const item = getItem(mod.itemId)
275
275
  const modType = getModuleCapabilityType(mod.itemId)
@@ -294,7 +294,6 @@ export function computeEntityCapabilities(
294
294
  totalGathYield += applySlotMultiplier(caps.yield, amp)
295
295
  totalGathDrain += caps.drain
296
296
  if (caps.depth > maxGathDepth) maxGathDepth = caps.depth
297
- totalGathSpeed += applySlotMultiplier(caps.speed, amp)
298
297
  } else if (modType === MODULE_LOADER) {
299
298
  hasLoader = true
300
299
  const caps = computeLoaderCapabilities(decodedStats)
@@ -320,9 +319,22 @@ export function computeEntityCapabilities(
320
319
  hasWarp = true
321
320
  const caps = computeWarpCapabilities(decodedStats)
322
321
  totalWarpRange += applySlotMultiplier(caps.range, amp)
322
+ } else if (modType === MODULE_BATTERY) {
323
+ batteryCount++
324
+ const vol = decodedStats.volatility ?? 0
325
+ const thm = decodedStats.thermal ?? 0
326
+ const pla = decodedStats.plasticity ?? 0
327
+ const ins = decodedStats.insulation ?? 0
328
+ totalBatteryStatSum += vol + thm + pla + ins
323
329
  }
324
330
  }
325
331
 
332
+ if (hasGenerator && batteryCount > 0) {
333
+ const genCapBase = totalGenCapacity
334
+ const bonusPctNum = 10 * batteryCount + Math.floor((totalBatteryStatSum * 10) / 2997)
335
+ totalGenCapacity += Math.floor((genCapBase * bonusPctNum) / 100)
336
+ }
337
+
326
338
  const result: ComputedCapabilities = {
327
339
  hullmass: computeBaseHullmass(stats) + installedModuleMass,
328
340
  capacity: baseCapacity + totalStorageBonus,
@@ -342,7 +354,6 @@ export function computeEntityCapabilities(
342
354
  yield: clampUint16(totalGathYield),
343
355
  drain: totalGathDrain,
344
356
  depth: maxGathDepth,
345
- speed: clampUint16(totalGathSpeed),
346
357
  }
347
358
  }
348
359
  if (hasLoader) {
@@ -16,6 +16,7 @@ import {
16
16
  ITEM_STORAGE_T1,
17
17
  ITEM_HAULER_T1,
18
18
  ITEM_WARP_T1,
19
+ ITEM_BATTERY_T1,
19
20
  ITEM_SHIP_T1_PACKED,
20
21
  ITEM_CONTAINER_T1_PACKED,
21
22
  ITEM_WAREHOUSE_T1_PACKED,
@@ -32,6 +33,7 @@ export const KIND_TO_ITEM_ID: Record<SlotConsumerKind, number> = {
32
33
  storage: ITEM_STORAGE_T1,
33
34
  hauler: ITEM_HAULER_T1,
34
35
  warp: ITEM_WARP_T1,
36
+ battery: ITEM_BATTERY_T1,
35
37
  'ship-t1': ITEM_SHIP_T1_PACKED,
36
38
  'container-t1': ITEM_CONTAINER_T1_PACKED,
37
39
  'warehouse-t1': ITEM_WAREHOUSE_T1_PACKED,
@@ -17,7 +17,9 @@ export {
17
17
  DEPTH_THRESHOLD_T5,
18
18
  LOCATION_MIN_DEPTH,
19
19
  LOCATION_MAX_DEPTH,
20
- YIELD_THRESHOLD,
20
+ yieldThresholdAt,
21
+ YIELD_FRACTION_SHALLOW,
22
+ YIELD_FRACTION_DEEP,
21
23
  PLANET_SUBTYPE_GAS_GIANT,
22
24
  PLANET_SUBTYPE_ROCKY,
23
25
  PLANET_SUBTYPE_TERRESTRIAL,
@@ -26,8 +28,11 @@ export {
26
28
  PLANET_SUBTYPE_INDUSTRIAL,
27
29
  } from './resources'
28
30
 
29
- export {RESERVE_TIERS, TIER_ROLL_MAX, rollTier, rollWithinTier} from './tiers'
31
+ export {RESERVE_TIERS, TIER_ROLL_MAX, tierOfReserve, rollTier, rollWithinTier} from './tiers'
30
32
  export type {ReserveTier, TierRange} from './tiers'
31
33
 
34
+ export {getEffectiveReserve} from './reserve-regen'
35
+ export type {EffectiveReserveInput} from './reserve-regen'
36
+
32
37
  export * from './stats'
33
38
  export * from './crafting'
@@ -0,0 +1,34 @@
1
+ import type {BlockTimestamp, UInt32} from '@wharfkit/antelope'
2
+
3
+ export interface EffectiveReserveInput {
4
+ remaining: UInt32 | number
5
+ max_reserve: UInt32 | number
6
+ last_block: BlockTimestamp
7
+ }
8
+
9
+ function toNumber(value: UInt32 | number): number {
10
+ return typeof value === 'number' ? value : Number(value)
11
+ }
12
+
13
+ function slotsBetween(now: BlockTimestamp, last: BlockTimestamp): number {
14
+ const nowMs = now.toMilliseconds()
15
+ const lastMs = last.toMilliseconds()
16
+ if (nowMs <= lastMs) return 0
17
+ return Math.floor((nowMs - lastMs) / 500)
18
+ }
19
+
20
+ export function getEffectiveReserve(
21
+ row: EffectiveReserveInput,
22
+ now: BlockTimestamp,
23
+ epochSeconds: number
24
+ ): number {
25
+ const remaining = toNumber(row.remaining)
26
+ const max = toNumber(row.max_reserve)
27
+ if (remaining >= max) return max
28
+ const epochSlots = epochSeconds * 2
29
+ if (epochSlots === 0) return remaining
30
+ const elapsed = slotsBetween(now, row.last_block)
31
+ const regen = Math.floor((max * elapsed) / epochSlots)
32
+ const effective = remaining + regen
33
+ return effective >= max ? max : effective
34
+ }
@@ -15,7 +15,15 @@ export const DEPTH_THRESHOLD_T10 = 63000
15
15
  export const LOCATION_MIN_DEPTH = 500
16
16
  export const LOCATION_MAX_DEPTH = 65535
17
17
 
18
- export const YIELD_THRESHOLD = Math.floor(0.001 * 0xffffffff)
18
+ export const YIELD_FRACTION_SHALLOW = 0.0025
19
+ export const YIELD_FRACTION_DEEP = 0.0005
20
+
21
+ export function yieldThresholdAt(stratum: number): number {
22
+ const clamped = stratum > 65535 ? 65535 : stratum
23
+ const t = clamped / 65535
24
+ const fraction = YIELD_FRACTION_SHALLOW + (YIELD_FRACTION_DEEP - YIELD_FRACTION_SHALLOW) * t
25
+ return Math.floor(fraction * 0xffffffff)
26
+ }
19
27
 
20
28
  export const PLANET_SUBTYPE_GAS_GIANT = 0
21
29
  export const PLANET_SUBTYPE_ROCKY = 1