@shipload/sdk 1.0.0-next.27 → 1.0.0-next.28

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shipload/sdk",
3
3
  "description": "SDKs for Shipload",
4
- "version": "1.0.0-next.27",
4
+ "version": "1.0.0-next.28",
5
5
  "homepage": "https://github.com/shipload/toolkit/tree/master/packages/sdk",
6
6
  "repository": {
7
7
  "type": "git",
@@ -34,7 +34,7 @@ export const itemAbbreviations: Record<number, string> = {
34
34
  10007: 'PM',
35
35
  10008: 'CR',
36
36
  10009: 'RX',
37
- 10010: 'EM',
37
+ 10010: 'RE',
38
38
  10100: 'EN',
39
39
  10101: 'GN',
40
40
  10102: 'EX',
@@ -59,7 +59,7 @@ export const ITEM_SENSOR = 10006
59
59
  export const ITEM_POLYMER = 10007
60
60
  export const ITEM_CERAMIC = 10008
61
61
  export const ITEM_REACTOR = 10009
62
- export const ITEM_EMITTER = 10010
62
+ export const ITEM_RESIN = 10010
63
63
  export const ITEM_ENGINE_T1 = 10100
64
64
  export const ITEM_GENERATOR_T1 = 10101
65
65
  export const ITEM_GATHERER_T1 = 10102
@@ -163,10 +163,10 @@ export const itemMetadata: Record<number, ItemMetadata> = {
163
163
  color: '#B877FF',
164
164
  },
165
165
  10010: {
166
- name: 'Emitter',
166
+ name: 'Resin',
167
167
  description:
168
- 'Precision-formed crystal emitter array. Routes energy efficiently to a target lock.',
169
- color: '#4ADBFF',
168
+ 'Saturated organic binder cured from biomass. A pliable matrix for haulage and field components.',
169
+ color: '#5A8B3E',
170
170
  },
171
171
 
172
172
  // === Modules (T1) ===
@@ -53,8 +53,8 @@
53
53
  {
54
54
  "sources": [
55
55
  {
56
- "inputIndex": 1,
57
- "statIndex": 2
56
+ "inputIndex": 0,
57
+ "statIndex": 0
58
58
  }
59
59
  ]
60
60
  }
@@ -99,7 +99,7 @@
99
99
  "quantity": 6
100
100
  },
101
101
  {
102
- "itemId": 501,
102
+ "itemId": 101,
103
103
  "quantity": 9
104
104
  }
105
105
  ],
@@ -281,11 +281,11 @@
281
281
  "outputMass": 6000,
282
282
  "inputs": [
283
283
  {
284
- "itemId": 201,
284
+ "itemId": 501,
285
285
  "quantity": 6
286
286
  },
287
287
  {
288
- "itemId": 101,
288
+ "itemId": 201,
289
289
  "quantity": 9
290
290
  }
291
291
  ],
@@ -294,7 +294,7 @@
294
294
  "sources": [
295
295
  {
296
296
  "inputIndex": 0,
297
- "statIndex": 0
297
+ "statIndex": 2
298
298
  }
299
299
  ]
300
300
  },
@@ -302,7 +302,7 @@
302
302
  "sources": [
303
303
  {
304
304
  "inputIndex": 0,
305
- "statIndex": 1
305
+ "statIndex": 0
306
306
  }
307
307
  ]
308
308
  }
@@ -553,7 +553,7 @@
553
553
  "sources": [
554
554
  {
555
555
  "inputIndex": 1,
556
- "statIndex": 0
556
+ "statIndex": 1
557
557
  }
558
558
  ]
559
559
  },
@@ -573,7 +573,7 @@
573
573
  "outputMass": 1400000,
574
574
  "inputs": [
575
575
  {
576
- "itemId": 10010,
576
+ "itemId": 10004,
577
577
  "quantity": 300
578
578
  },
579
579
  {
@@ -586,7 +586,7 @@
586
586
  "sources": [
587
587
  {
588
588
  "inputIndex": 0,
589
- "statIndex": 1
589
+ "statIndex": 0
590
590
  },
591
591
  {
592
592
  "inputIndex": 1,
@@ -6,7 +6,7 @@ export function computeShipHullCapabilities(stats: Record<string, number>): {
6
6
  hullmass: number
7
7
  capacity: number
8
8
  } {
9
- const statSum = stats.strength + stats.hardness + stats.saturation
9
+ const statSum = stats.strength + stats.hardness + stats.cohesion
10
10
  const exponent = statSum / 2997.0
11
11
  return {
12
12
  hullmass: computeBaseHullmass(stats),
@@ -121,12 +121,12 @@ export function computeHaulerCapabilities(stats: Record<string, number>): {
121
121
  drain: number
122
122
  } {
123
123
  const resonance = stats.resonance
124
- const conductivity = stats.conductivity
124
+ const plasticity = stats.plasticity
125
125
  const reflectivity = stats.reflectivity
126
126
 
127
127
  return {
128
128
  capacity: Math.max(1, 1 + Math.floor(resonance / 400)),
129
- efficiency: 2000 + conductivity * 6,
129
+ efficiency: 2000 + plasticity * 6,
130
130
  drain: Math.max(3, 15 - Math.floor(reflectivity / 80)),
131
131
  }
132
132
  }
@@ -140,9 +140,9 @@ export function computeStorageCapabilities(
140
140
  const strength = stats.strength
141
141
  const density = stats.density
142
142
  const hardness = stats.hardness
143
- const saturation = stats.saturation
143
+ const cohesion = stats.cohesion
144
144
 
145
- const statSum = strength + density + hardness + saturation
145
+ const statSum = strength + density + hardness + cohesion
146
146
  const capacityBonus = Math.floor(
147
147
  (baseCapacity * (10 + Math.floor((statSum * 10) / 2997))) / 100
148
148
  )
@@ -201,15 +201,15 @@ export function computeBaseCapacity(itemId: number, stats: Record<string, number
201
201
  export function computeWarpCapabilities(stats: Record<string, number>): {
202
202
  range: number
203
203
  } {
204
- const res = stats.resonance
205
- return {range: 100 + res * 3}
204
+ const resonance = stats.resonance
205
+ return {range: 100 + resonance * 3}
206
206
  }
207
207
 
208
208
  export function computeWarehouseHullCapabilities(stats: Record<string, number>): {
209
209
  hullmass: number
210
210
  capacity: number
211
211
  } {
212
- const statSum = stats.strength + stats.hardness + stats.saturation
212
+ const statSum = stats.strength + stats.hardness + stats.cohesion
213
213
  const exponent = statSum / 2997.0
214
214
  return {
215
215
  hullmass: computeBaseHullmass(stats),
@@ -388,7 +388,7 @@ export function computeContainerCapabilities(stats: Record<string, number>): {
388
388
  hullmass: number
389
389
  capacity: number
390
390
  } {
391
- const statSum = stats.strength + stats.hardness + stats.saturation
391
+ const statSum = stats.strength + stats.hardness + stats.cohesion
392
392
  const exponent = statSum / 2997.0
393
393
  return {
394
394
  hullmass: computeBaseHullmass(stats),
@@ -403,11 +403,11 @@ export function computeContainerT2Capabilities(stats: Record<string, number>): {
403
403
  const strength = stats.strength
404
404
  const density = stats.density
405
405
  const hardness = stats.hardness
406
- const saturation = stats.saturation
406
+ const cohesion = stats.cohesion
407
407
 
408
408
  const hullmass = 70000 - 50 * density
409
409
 
410
- const statSum = strength + hardness + saturation
410
+ const statSum = strength + hardness + cohesion
411
411
  const exponent = statSum / 2947
412
412
  const capacity = Math.floor(24000000 * 6 ** exponent)
413
413
 
@@ -36,3 +36,12 @@ export type {EffectiveReserveInput} from './reserve-regen'
36
36
 
37
37
  export * from './stats'
38
38
  export * from './crafting'
39
+
40
+ export {
41
+ STAR_STEP,
42
+ MAX_STARS_PER_STAT,
43
+ MAX_STAR_RATING,
44
+ starsForStat,
45
+ starRating,
46
+ statMagnitude,
47
+ } from './stars'
@@ -0,0 +1,51 @@
1
+ import {expect, test} from 'bun:test'
2
+ import {
3
+ MAX_STARS_PER_STAT,
4
+ MAX_STAR_RATING,
5
+ starRating,
6
+ starsForStat,
7
+ statMagnitude,
8
+ STAR_STEP,
9
+ } from './stars'
10
+
11
+ test('starsForStat bands at the 250 boundaries', () => {
12
+ expect(starsForStat(0)).toBe(0)
13
+ expect(starsForStat(1)).toBe(0)
14
+ expect(starsForStat(249)).toBe(0)
15
+ expect(starsForStat(250)).toBe(1)
16
+ expect(starsForStat(499)).toBe(1)
17
+ expect(starsForStat(500)).toBe(2)
18
+ expect(starsForStat(749)).toBe(2)
19
+ expect(starsForStat(750)).toBe(3)
20
+ })
21
+
22
+ test('starsForStat clamps to MAX_STARS_PER_STAT', () => {
23
+ expect(starsForStat(999)).toBe(MAX_STARS_PER_STAT)
24
+ expect(starsForStat(1000)).toBe(MAX_STARS_PER_STAT)
25
+ expect(starsForStat(10_000)).toBe(MAX_STARS_PER_STAT)
26
+ })
27
+
28
+ test('starsForStat never goes negative', () => {
29
+ expect(starsForStat(-50)).toBe(0)
30
+ })
31
+
32
+ test('starRating sums per-stat stars to a 0-9 grade', () => {
33
+ expect(starRating(0, 0, 0)).toBe(0)
34
+ expect(starRating(250, 0, 0)).toBe(1)
35
+ expect(starRating(750, 750, 750)).toBe(MAX_STAR_RATING)
36
+ expect(starRating(999, 999, 999)).toBe(MAX_STAR_RATING)
37
+ expect(starRating(599, 599, 599)).toBe(6)
38
+ expect(starRating(251, 251, 251)).toBe(3)
39
+ })
40
+
41
+ test('statMagnitude sums raw values for tiebreaking', () => {
42
+ expect(statMagnitude(599, 599, 599)).toBe(1797)
43
+ expect(statMagnitude(251, 251, 251)).toBe(753)
44
+ expect(statMagnitude(599, 599, 599)).toBeGreaterThan(statMagnitude(251, 251, 251))
45
+ })
46
+
47
+ test('constants hold their documented values', () => {
48
+ expect(STAR_STEP).toBe(250)
49
+ expect(MAX_STARS_PER_STAT).toBe(3)
50
+ expect(MAX_STAR_RATING).toBe(9)
51
+ })
@@ -0,0 +1,15 @@
1
+ export const STAR_STEP = 250
2
+ export const MAX_STARS_PER_STAT = 3
3
+ export const MAX_STAR_RATING = MAX_STARS_PER_STAT * 3
4
+
5
+ export function starsForStat(value: number): number {
6
+ return Math.max(0, Math.min(MAX_STARS_PER_STAT, Math.floor(value / STAR_STEP)))
7
+ }
8
+
9
+ export function starRating(stat1: number, stat2: number, stat3: number): number {
10
+ return starsForStat(stat1) + starsForStat(stat2) + starsForStat(stat3)
11
+ }
12
+
13
+ export function statMagnitude(stat1: number, stat2: number, stat3: number): number {
14
+ return stat1 + stat2 + stat3
15
+ }
@@ -73,10 +73,11 @@ const GAS_STATS: StatDefinition[] = [
73
73
 
74
74
  const REGOLITH_STATS: StatDefinition[] = [
75
75
  {
76
- key: 'composition',
77
- label: 'Composition',
78
- abbreviation: 'COM',
79
- purpose: 'Mineral/metal mix — drives sensor, chip, and optic crafting quality',
76
+ key: 'cohesion',
77
+ label: 'Cohesion',
78
+ abbreviation: 'COH',
79
+ purpose:
80
+ 'Binding strength of the loose aggregate; higher cohesion yields more rigid frames and hulls',
80
81
  },
81
82
  {
82
83
  key: 'hardness',
@@ -75,7 +75,7 @@ const ZERO_HULL_STATS: Record<string, number> = {
75
75
  density: 0,
76
76
  strength: 0,
77
77
  hardness: 0,
78
- saturation: 0,
78
+ cohesion: 0,
79
79
  }
80
80
 
81
81
  export function makeEntity(packedItemId: number, state: EntityStateInput): Entity {
@@ -133,6 +133,15 @@ export type {EffectiveReserveInput} from './derivation'
133
133
  export {getStatDefinitions, getStatName, resolveStats} from './derivation'
134
134
  export type {StatDefinition, NamedStats} from './derivation'
135
135
 
136
+ export {
137
+ STAR_STEP,
138
+ MAX_STARS_PER_STAT,
139
+ MAX_STAR_RATING,
140
+ starsForStat,
141
+ starRating,
142
+ statMagnitude,
143
+ } from './derivation'
144
+
136
145
  export {hash, hash512} from './utils/hash'
137
146
 
138
147
  export {
@@ -224,21 +224,23 @@ export function buildModuleImmutable(
224
224
  }
225
225
  case MODULE_CRAFTER: {
226
226
  const rea = decodeStat(stats, 0)
227
- const com = decodeStat(stats, 1)
227
+ const fin = decodeStat(stats, 1)
228
228
  base.push({first: 'reactivity', second: ['uint16', rea]})
229
- base.push({first: 'composition', second: ['uint16', com]})
229
+ base.push({first: 'fineness', second: ['uint16', fin]})
230
230
  base.push({first: 'speed', second: ['uint16', computeCrafterSpeed(rea)]})
231
- base.push({first: 'drain', second: ['uint16', computeCrafterDrain(com)]})
231
+ base.push({first: 'drain', second: ['uint16', computeCrafterDrain(fin)]})
232
232
  break
233
233
  }
234
234
  case MODULE_STORAGE: {
235
235
  const str = decodeStat(stats, 0)
236
- const fin = decodeStat(stats, 1)
237
- const sat = decodeStat(stats, 2)
238
- const sum = str + fin + sat
236
+ const den = decodeStat(stats, 1)
237
+ const hrd = decodeStat(stats, 2)
238
+ const com = decodeStat(stats, 3)
239
+ const sum = str + den + hrd + com
239
240
  base.push({first: 'strength', second: ['uint16', str]})
240
- base.push({first: 'fineness', second: ['uint16', fin]})
241
- base.push({first: 'saturation', second: ['uint16', sat]})
241
+ base.push({first: 'density', second: ['uint16', den]})
242
+ base.push({first: 'hardness', second: ['uint16', hrd]})
243
+ base.push({first: 'cohesion', second: ['uint16', com]})
242
244
  base.push({
243
245
  first: 'capacity_bonus_pct',
244
246
  second: ['uint16', 10 + Math.floor((sum * 10) / 2997)],
@@ -247,13 +249,13 @@ export function buildModuleImmutable(
247
249
  }
248
250
  case MODULE_HAULER: {
249
251
  const res = decodeStat(stats, 0)
250
- const con = decodeStat(stats, 1)
252
+ const pla = decodeStat(stats, 1)
251
253
  const ref = decodeStat(stats, 2)
252
254
  base.push({first: 'resonance', second: ['uint16', res]})
253
- base.push({first: 'conductivity', second: ['uint16', con]})
255
+ base.push({first: 'plasticity', second: ['uint16', pla]})
254
256
  base.push({first: 'reflectivity', second: ['uint16', ref]})
255
257
  base.push({first: 'capacity', second: ['uint8', computeHaulerCapacity(res)]})
256
- base.push({first: 'efficiency', second: ['uint16', computeHaulerEfficiency(con)]})
258
+ base.push({first: 'efficiency', second: ['uint16', computeHaulerEfficiency(pla)]})
257
259
  base.push({first: 'drain', second: ['uint16', computeHaulerDrain(ref)]})
258
260
  break
259
261
  }
@@ -162,9 +162,9 @@ export function formatModuleLine(slot: number, itemId: number, stats: bigint): s
162
162
  }
163
163
  case MODULE_HAULER: {
164
164
  const res = decodeStat(stats, 0)
165
- const con = decodeStat(stats, 1)
165
+ const pla = decodeStat(stats, 1)
166
166
  const ref = decodeStat(stats, 2)
167
- out += ` Capacity ${computeHaulerCapacity(res)} Efficiency ${computeHaulerEfficiency(con)} Drain ${computeHaulerDrain(ref)}`
167
+ out += ` Capacity ${computeHaulerCapacity(res)} Efficiency ${computeHaulerEfficiency(pla)} Drain ${computeHaulerDrain(ref)}`
168
168
  break
169
169
  }
170
170
  case MODULE_WARP: {
@@ -222,8 +222,8 @@ function computeCapabilityGroup(
222
222
  const str = stats.strength
223
223
  const den = stats.density
224
224
  const hrd = stats.hardness
225
- const sat = stats.saturation
226
- const statSum = str + den + hrd + sat
225
+ const com = stats.cohesion
226
+ const statSum = str + den + hrd + com
227
227
  const pct = 10 + Math.floor((statSum * 10) / 2997)
228
228
  return {capability: 'Storage', attributes: [{label: 'Capacity Bonus', value: pct}]}
229
229
  }