@shipload/sdk 1.0.0-next.52 → 1.0.0-next.53
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/lib/shipload.d.ts +3 -3
- package/lib/shipload.js +41 -23
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +41 -23
- package/lib/shipload.m.js.map +1 -1
- package/package.json +1 -1
- package/src/data/capabilities.ts +7 -0
- package/src/data/capability-formulas.ts +5 -0
- package/src/data/recipes.json +12 -5
- package/src/derivation/capabilities.test.ts +24 -0
- package/src/derivation/capabilities.ts +4 -4
- package/src/derivation/capability-mappings.ts +2 -0
- package/src/nft/buildImmutableData.ts +6 -6
- package/src/nft/description.ts +6 -6
- package/src/scheduling/lanes.ts +4 -4
package/package.json
CHANGED
package/src/data/capabilities.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const capabilityNames: string[] = [
|
|
|
27
27
|
'Gathering',
|
|
28
28
|
'Warp',
|
|
29
29
|
'Crafting',
|
|
30
|
+
'Build',
|
|
30
31
|
'Launch',
|
|
31
32
|
'Hauling',
|
|
32
33
|
]
|
|
@@ -73,6 +74,12 @@ export const capabilityAttributes: CapabilityAttribute[] = [
|
|
|
73
74
|
description: 'Energy consumed per second while crafting',
|
|
74
75
|
},
|
|
75
76
|
{capability: 'Crafting', attribute: 'quality', description: 'Modifier on output quality'},
|
|
77
|
+
{capability: 'Build', attribute: 'speed', description: 'Build progress per second'},
|
|
78
|
+
{
|
|
79
|
+
capability: 'Build',
|
|
80
|
+
attribute: 'drain',
|
|
81
|
+
description: 'Energy consumed per second while building',
|
|
82
|
+
},
|
|
76
83
|
{capability: 'Launch', attribute: 'range', description: 'Maximum launch distance'},
|
|
77
84
|
{capability: 'Launch', attribute: 'capacity', description: 'Maximum mass per launch'},
|
|
78
85
|
{capability: 'Launch', attribute: 'drain', description: 'Energy consumed per launch'},
|
|
@@ -9,6 +9,7 @@ export type SlotConsumerKind =
|
|
|
9
9
|
| 'gatherer'
|
|
10
10
|
| 'loader'
|
|
11
11
|
| 'crafter'
|
|
12
|
+
| 'builder'
|
|
12
13
|
| 'storage'
|
|
13
14
|
| 'hauler'
|
|
14
15
|
| 'warp'
|
|
@@ -47,6 +48,10 @@ export const SLOT_FORMULAS: Record<SlotConsumerKind, Record<number, SlotConsumer
|
|
|
47
48
|
0: {capability: 'Crafting', attribute: 'speed'},
|
|
48
49
|
1: {capability: 'Crafting', attribute: 'drain'},
|
|
49
50
|
},
|
|
51
|
+
builder: {
|
|
52
|
+
0: {capability: 'Build', attribute: 'speed'},
|
|
53
|
+
1: {capability: 'Build', attribute: 'drain'},
|
|
54
|
+
},
|
|
50
55
|
storage: {
|
|
51
56
|
0: {capability: 'Storage', attribute: 'capacity'},
|
|
52
57
|
1: {capability: 'Storage', attribute: 'capacity'},
|
package/src/data/recipes.json
CHANGED
|
@@ -777,33 +777,40 @@
|
|
|
777
777
|
"outputMass": 960000,
|
|
778
778
|
"inputs": [
|
|
779
779
|
{
|
|
780
|
-
"itemId":
|
|
780
|
+
"itemId": 10006,
|
|
781
781
|
"quantity": 300
|
|
782
782
|
},
|
|
783
783
|
{
|
|
784
|
-
"itemId":
|
|
784
|
+
"itemId": 10008,
|
|
785
785
|
"quantity": 300
|
|
786
786
|
}
|
|
787
787
|
],
|
|
788
788
|
"statSlots": [
|
|
789
789
|
{
|
|
790
790
|
"sources": [
|
|
791
|
+
{
|
|
792
|
+
"inputIndex": 0,
|
|
793
|
+
"statIndex": 2
|
|
794
|
+
},
|
|
791
795
|
{
|
|
792
796
|
"inputIndex": 1,
|
|
793
|
-
"statIndex":
|
|
797
|
+
"statIndex": 0
|
|
794
798
|
}
|
|
795
799
|
]
|
|
796
800
|
},
|
|
797
801
|
{
|
|
798
802
|
"sources": [
|
|
799
803
|
{
|
|
800
|
-
"inputIndex":
|
|
804
|
+
"inputIndex": 1,
|
|
801
805
|
"statIndex": 1
|
|
802
806
|
}
|
|
803
807
|
]
|
|
804
808
|
}
|
|
805
809
|
],
|
|
806
|
-
"blendWeights": [
|
|
810
|
+
"blendWeights": [
|
|
811
|
+
1,
|
|
812
|
+
1
|
|
813
|
+
]
|
|
807
814
|
},
|
|
808
815
|
{
|
|
809
816
|
"outputItemId": 10200,
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
computeGathererCapabilities,
|
|
6
6
|
computeGeneratorCapabilities,
|
|
7
7
|
computeCrafterCapabilities,
|
|
8
|
+
computeBuilderCapabilities,
|
|
8
9
|
computeLoaderCapabilities,
|
|
9
10
|
computeBaseCapacity,
|
|
10
11
|
computeContainerCapabilities,
|
|
@@ -30,6 +31,7 @@ import {
|
|
|
30
31
|
ITEM_WRIGHT_T1_PACKED,
|
|
31
32
|
ITEM_ENGINE_T1,
|
|
32
33
|
ITEM_GENERATOR_T1,
|
|
34
|
+
ITEM_BUILDER_T1,
|
|
33
35
|
} from '../data/item-ids'
|
|
34
36
|
import type {InstalledModule} from '../entities/slot-multiplier'
|
|
35
37
|
import type {EntitySlot} from '../data/recipes-runtime'
|
|
@@ -48,6 +50,10 @@ function makeLoaderStats(insulation: number, plasticity: number): bigint {
|
|
|
48
50
|
return encodeStats([insulation, plasticity])
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
function makeBuilderStats(resonance: number, fineness: number): bigint {
|
|
54
|
+
return encodeStats([resonance, fineness])
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
test('computeBaseCapacity uses container formula for all container-class entities', () => {
|
|
52
58
|
const stats = {strength: 300, hardness: 400, density: 100}
|
|
53
59
|
const expected = computeContainerCapabilities(stats).capacity
|
|
@@ -154,6 +160,24 @@ test('computeEntityCapabilities emits crafterLanes alongside legacy crafter sum'
|
|
|
154
160
|
expect(result.crafter!.speed).toBe(expectedSpeed)
|
|
155
161
|
})
|
|
156
162
|
|
|
163
|
+
test('builder capabilities read canonical resonance and fineness slots', () => {
|
|
164
|
+
expect(computeBuilderCapabilities({resonance: 500, fineness: 330})).toEqual({
|
|
165
|
+
speed: 500,
|
|
166
|
+
drain: 20_000,
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
test('computeEntityCapabilities emits a Builder lane from resonance and fineness', () => {
|
|
171
|
+
const modules: InstalledModule[] = [
|
|
172
|
+
{slotIndex: 0, itemId: ITEM_BUILDER_T1, stats: makeBuilderStats(500, 330)},
|
|
173
|
+
]
|
|
174
|
+
const layout: EntitySlot[] = [{type: 'builder', outputPct: 80, maxTier: 1}]
|
|
175
|
+
const result = computeEntityCapabilities({}, ITEM_EXTRACTOR_T1_PACKED, modules, layout)
|
|
176
|
+
|
|
177
|
+
expect(result.builderLanes).toEqual([{slotIndex: 0, speed: 400, drain: 20_000, outputPct: 80}])
|
|
178
|
+
expect(result.builder).toEqual({speed: 400, drain: 20_000})
|
|
179
|
+
})
|
|
180
|
+
|
|
157
181
|
test('computeEntityCapabilities emits loaderLanes alongside legacy loaders sum', () => {
|
|
158
182
|
const loaderStats = makeLoaderStats(600, 500)
|
|
159
183
|
|
|
@@ -147,12 +147,12 @@ export function computeBuilderCapabilities(stats: Record<string, number>): {
|
|
|
147
147
|
speed: number
|
|
148
148
|
drain: number
|
|
149
149
|
} {
|
|
150
|
-
const
|
|
151
|
-
const
|
|
150
|
+
const resonance = stats.resonance
|
|
151
|
+
const fineness = stats.fineness
|
|
152
152
|
|
|
153
153
|
return {
|
|
154
|
-
speed: 100 + Math.floor((
|
|
155
|
-
drain: Math.max(5000, 30000 - Math.floor((
|
|
154
|
+
speed: 100 + Math.floor((resonance * 4) / 5),
|
|
155
|
+
drain: Math.max(5000, 30000 - Math.floor((fineness * 1000) / 33)),
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ITEM_GATHERER_T1,
|
|
10
10
|
ITEM_LOADER_T1,
|
|
11
11
|
ITEM_CRAFTER_T1,
|
|
12
|
+
ITEM_BUILDER_T1,
|
|
12
13
|
ITEM_STORAGE_T1,
|
|
13
14
|
ITEM_HAULER_T1,
|
|
14
15
|
ITEM_WARP_T1,
|
|
@@ -27,6 +28,7 @@ export const KIND_TO_ITEM_ID: Record<SlotConsumerKind, number> = {
|
|
|
27
28
|
gatherer: ITEM_GATHERER_T1,
|
|
28
29
|
loader: ITEM_LOADER_T1,
|
|
29
30
|
crafter: ITEM_CRAFTER_T1,
|
|
31
|
+
builder: ITEM_BUILDER_T1,
|
|
30
32
|
storage: ITEM_STORAGE_T1,
|
|
31
33
|
hauler: ITEM_HAULER_T1,
|
|
32
34
|
warp: ITEM_WARP_T1,
|
|
@@ -263,12 +263,12 @@ export function buildModuleImmutable(
|
|
|
263
263
|
break
|
|
264
264
|
}
|
|
265
265
|
case MODULE_BUILDER: {
|
|
266
|
-
const
|
|
267
|
-
const
|
|
268
|
-
base.push({first: '
|
|
269
|
-
base.push({first: '
|
|
270
|
-
base.push({first: 'speed', second: ['uint16', computeBuilderSpeed(
|
|
271
|
-
base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeBuilderDrain(
|
|
266
|
+
const res = decodeStat(stats, 0)
|
|
267
|
+
const fin = decodeStat(stats, 1)
|
|
268
|
+
base.push({first: 'resonance', second: ['uint16', res]})
|
|
269
|
+
base.push({first: 'fineness', second: ['uint16', fin]})
|
|
270
|
+
base.push({first: 'speed', second: ['uint16', computeBuilderSpeed(res)]})
|
|
271
|
+
base.push({first: 'drain', second: ['uint16', toWholeEnergy(computeBuilderDrain(fin))]})
|
|
272
272
|
break
|
|
273
273
|
}
|
|
274
274
|
case MODULE_STORAGE: {
|
package/src/nft/description.ts
CHANGED
|
@@ -114,9 +114,9 @@ export const computeLoaderThrust = (pla: number): number => 1 + idiv(pla * pla,
|
|
|
114
114
|
export const computeCrafterSpeed = (rea: number): number => 100 + idiv(rea * 4, 5)
|
|
115
115
|
export const computeCrafterDrain = (fin: number): number =>
|
|
116
116
|
Math.max(5000, 30000 - idiv(fin * 1000, 33))
|
|
117
|
-
export const computeBuilderSpeed = (
|
|
118
|
-
export const computeBuilderDrain = (
|
|
119
|
-
Math.max(5000, 30000 - idiv(
|
|
117
|
+
export const computeBuilderSpeed = (resonance: number): number => 100 + idiv(resonance * 4, 5)
|
|
118
|
+
export const computeBuilderDrain = (fineness: number): number =>
|
|
119
|
+
Math.max(5000, 30000 - idiv(fineness * 1000, 33))
|
|
120
120
|
export const computeHaulerCapacity = (fin: number, tier: number): number =>
|
|
121
121
|
Math.max(tier, tier + idiv(fin, 400))
|
|
122
122
|
export const computeHaulerEfficiency = (con: number): number => 2000 + con * 6
|
|
@@ -260,9 +260,9 @@ export function formatModuleLine(slot: number, itemId: number, stats: bigint): s
|
|
|
260
260
|
break
|
|
261
261
|
}
|
|
262
262
|
case MODULE_BUILDER: {
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
out += ` Speed ${computeBuilderSpeed(
|
|
263
|
+
const res = decodeStat(stats, 0)
|
|
264
|
+
const fin = decodeStat(stats, 1)
|
|
265
|
+
out += ` Speed ${computeBuilderSpeed(res)} Drain ${toWholeEnergy(computeBuilderDrain(fin))}`
|
|
266
266
|
break
|
|
267
267
|
}
|
|
268
268
|
case MODULE_STORAGE: {
|
package/src/scheduling/lanes.ts
CHANGED
|
@@ -130,12 +130,12 @@ export function resolveLaneBuilder(
|
|
|
130
130
|
const item = getItem(Number(installed.item_id.value ?? installed.item_id))
|
|
131
131
|
if (item.moduleType !== 'builder') throw new Error('lane module is not a builder')
|
|
132
132
|
const stats = BigInt(installed.stats.toString())
|
|
133
|
-
const
|
|
134
|
-
const
|
|
133
|
+
const res = decodeStat(stats, 0)
|
|
134
|
+
const fin = decodeStat(stats, 1)
|
|
135
135
|
const layout = getEntityLayout(entityItemId)?.slots ?? []
|
|
136
136
|
const amp = getSlotAmp(layout, idx)
|
|
137
|
-
const speed = applySlotMultiplier(computeBuilderSpeed(
|
|
138
|
-
const drain = computeBuilderDrain(
|
|
137
|
+
const speed = applySlotMultiplier(computeBuilderSpeed(res), amp)
|
|
138
|
+
const drain = computeBuilderDrain(fin)
|
|
139
139
|
return {slotIndex: idx, speed, drain, outputPct: amp}
|
|
140
140
|
}
|
|
141
141
|
|