@shipload/sdk 1.0.0-next.5 → 1.0.0-next.51
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/scan.d.ts +52 -0
- package/lib/scan.js +162 -0
- package/lib/scan.js.map +1 -0
- package/lib/scan.m.js +152 -0
- package/lib/scan.m.js.map +1 -0
- package/lib/shipload.d.ts +3167 -1353
- package/lib/shipload.js +13319 -5640
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +13091 -5589
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +1037 -0
- package/lib/testing.js +4363 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +4357 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +20 -2
- package/src/capabilities/craftable.ts +51 -0
- package/src/capabilities/crafting.test.ts +7 -0
- package/src/capabilities/crafting.ts +6 -7
- package/src/capabilities/gathering.test.ts +29 -0
- package/src/capabilities/gathering.ts +37 -19
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +22 -0
- package/src/capabilities/storage.ts +16 -1
- package/src/contracts/platform.ts +231 -3
- package/src/contracts/server.ts +1178 -511
- package/src/coordinates/address.ts +88 -0
- package/src/coordinates/constants.test.ts +15 -0
- package/src/coordinates/constants.ts +23 -0
- package/src/coordinates/index.ts +15 -0
- package/src/coordinates/memo.test.ts +47 -0
- package/src/coordinates/memo.ts +20 -0
- package/src/coordinates/permutation.ts +77 -0
- package/src/coordinates/regions.ts +48 -0
- package/src/coordinates/sectors.ts +115 -0
- package/src/data/capabilities.ts +31 -16
- package/src/data/capability-formulas.ts +21 -14
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +13 -47
- package/src/data/entities.json +154 -10
- package/src/data/item-ids.ts +31 -12
- package/src/data/items.json +192 -74
- package/src/data/kind-registry.json +131 -0
- package/src/data/kind-registry.ts +172 -0
- package/src/data/metadata.ts +166 -48
- package/src/data/recipes-runtime.ts +5 -23
- package/src/data/recipes.json +1003 -163
- package/src/derivation/build-methods.test.ts +13 -0
- package/src/derivation/build-methods.ts +48 -0
- package/src/derivation/capabilities.test.ts +151 -0
- package/src/derivation/capabilities.ts +527 -0
- package/src/derivation/capability-mappings.ts +58 -16
- package/src/derivation/crafting.ts +36 -33
- package/src/derivation/index.ts +28 -2
- package/src/derivation/recipe-usage.test.ts +81 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +98 -19
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +56 -0
- package/src/derivation/stars.test.ts +67 -0
- package/src/derivation/stars.ts +25 -0
- package/src/derivation/stats.ts +6 -6
- package/src/derivation/stratum.ts +26 -22
- package/src/derivation/tiers.ts +40 -7
- package/src/derivation/upgrades.ts +14 -0
- package/src/derivation/wormhole.ts +141 -0
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +131 -134
- package/src/entities/slot-multiplier.ts +43 -0
- package/src/errors.ts +12 -16
- package/src/format.ts +26 -4
- package/src/index-module.ts +294 -34
- package/src/managers/actions.ts +616 -105
- package/src/managers/base.ts +6 -2
- package/src/managers/cluster.test.ts +39 -0
- package/src/managers/cluster.ts +53 -0
- package/src/managers/construction-types.ts +80 -0
- package/src/managers/construction.ts +412 -0
- package/src/managers/context.ts +29 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +27 -66
- package/src/managers/epochs.ts +40 -0
- package/src/managers/flatten-gather-plan.test.ts +80 -0
- package/src/managers/index.ts +20 -1
- package/src/managers/locations.ts +25 -29
- package/src/managers/nft.test.ts +14 -0
- package/src/managers/nft.ts +70 -0
- package/src/managers/players.ts +25 -0
- package/src/managers/plot.ts +122 -0
- package/src/nft/atomicassets.abi.json +1342 -0
- package/src/nft/atomicassets.ts +237 -0
- package/src/nft/atomicdata.ts +130 -0
- package/src/nft/buildImmutableData.ts +336 -0
- package/src/nft/description.ts +104 -36
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +242 -0
- package/src/planner/planner.test.ts +325 -0
- package/src/resolution/describe-module.ts +43 -25
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.test.ts +48 -0
- package/src/resolution/resolve-item.ts +74 -47
- package/src/scan/index.ts +244 -0
- package/src/scan/scan-wasm.base64.ts +2 -0
- package/src/scheduling/accessor.ts +65 -23
- package/src/scheduling/availability.ts +108 -0
- package/src/scheduling/cancel.test.ts +348 -0
- package/src/scheduling/cancel.ts +209 -0
- package/src/scheduling/energy.ts +47 -0
- package/src/scheduling/idle-resolve.ts +45 -0
- package/src/scheduling/lane-core.ts +128 -0
- package/src/scheduling/lanes.test.ts +249 -0
- package/src/scheduling/lanes.ts +198 -0
- package/src/scheduling/projection.ts +210 -107
- package/src/scheduling/schedule.ts +240 -117
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/scheduling/unwrap.test.ts +86 -0
- package/src/scheduling/unwrap.ts +190 -0
- package/src/shipload.ts +26 -1
- package/src/subscriptions/manager.cluster.test.ts +51 -0
- package/src/subscriptions/manager.ts +245 -172
- package/src/subscriptions/mappers.ts +5 -8
- package/src/subscriptions/types.ts +28 -3
- package/src/testing/catalog-hash.ts +19 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/projection-parity.ts +167 -0
- package/src/travel/reach.ts +23 -0
- package/src/travel/route-planner.ts +277 -0
- package/src/travel/route-simulator.ts +174 -0
- package/src/travel/travel.ts +175 -118
- package/src/types/capabilities.ts +29 -6
- package/src/types/entity.ts +3 -3
- package/src/types/index.ts +0 -1
- package/src/types.ts +39 -14
- package/src/utils/cargo.test.ts +14 -0
- package/src/utils/cargo.ts +29 -0
- package/src/utils/display-name.ts +70 -0
- package/src/utils/system.ts +36 -24
- package/src/capabilities/loading.ts +0 -8
- package/src/entities/container.ts +0 -123
- package/src/entities/ship-deploy.ts +0 -295
- package/src/entities/ship.ts +0 -221
- package/src/entities/warehouse.ts +0 -127
- package/src/types/entity-traits.ts +0 -69
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {describe, expect, test} from 'bun:test'
|
|
2
|
+
import {availableBuildMethods} from './build-methods'
|
|
3
|
+
import {ITEM_HUB_T1_PACKED, ITEM_WAREHOUSE_T1_PACKED} from '../data/item-ids'
|
|
4
|
+
|
|
5
|
+
describe('availableBuildMethods', () => {
|
|
6
|
+
test('orbital structures build via craft+deploy or plot', () => {
|
|
7
|
+
expect(availableBuildMethods(ITEM_WAREHOUSE_T1_PACKED)).toEqual(['craft+deploy', 'plot'])
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('hub is craft+deploy only — excluded from the plot path', () => {
|
|
11
|
+
expect(availableBuildMethods(ITEM_HUB_T1_PACKED)).toEqual(['craft+deploy'])
|
|
12
|
+
})
|
|
13
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {ENTITY_HUB, EntityClass, getKindMeta, getTemplateMeta} from '../data/kind-registry'
|
|
2
|
+
import {getRecipe} from '../data/recipes-runtime'
|
|
3
|
+
import {getItems} from '../data/catalog'
|
|
4
|
+
import type {Item} from '../types'
|
|
5
|
+
|
|
6
|
+
export type BuildMethod = 'craft+deploy' | 'plot'
|
|
7
|
+
|
|
8
|
+
export function availableBuildMethods(itemId: number): BuildMethod[] {
|
|
9
|
+
const recipe = getRecipe(itemId)
|
|
10
|
+
if (!recipe) return []
|
|
11
|
+
|
|
12
|
+
const template = getTemplateMeta(itemId)
|
|
13
|
+
if (!template) return ['craft+deploy']
|
|
14
|
+
|
|
15
|
+
const kindMeta = getKindMeta(template.kind)
|
|
16
|
+
if (!kindMeta) return ['craft+deploy']
|
|
17
|
+
|
|
18
|
+
if (
|
|
19
|
+
kindMeta.classification === EntityClass.OrbitalStructure &&
|
|
20
|
+
!kindMeta.kind.equals(ENTITY_HUB)
|
|
21
|
+
) {
|
|
22
|
+
return ['craft+deploy', 'plot']
|
|
23
|
+
}
|
|
24
|
+
return ['craft+deploy']
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isBuildable(itemId: number): boolean {
|
|
28
|
+
return availableBuildMethods(itemId).length > 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function isPlotBuildable(itemId: number): boolean {
|
|
32
|
+
return availableBuildMethods(itemId).includes('plot')
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function filterByBuildMethod<T extends {itemId: number}>(
|
|
36
|
+
items: T[],
|
|
37
|
+
method: BuildMethod
|
|
38
|
+
): T[] {
|
|
39
|
+
return items.filter((i) => availableBuildMethods(i.itemId).includes(method))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function allBuildableItems(): Item[] {
|
|
43
|
+
return getItems().filter((item) => isBuildable(item.id))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function allPlotBuildableItems(): Item[] {
|
|
47
|
+
return getItems().filter((item) => isPlotBuildable(item.id))
|
|
48
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {expect, test} from 'bun:test'
|
|
2
|
+
import {
|
|
3
|
+
computeEntityCapabilities,
|
|
4
|
+
computeGathererCapabilities,
|
|
5
|
+
computeCrafterCapabilities,
|
|
6
|
+
computeLoaderCapabilities,
|
|
7
|
+
computeBaseCapacity,
|
|
8
|
+
computeContainerCapabilities,
|
|
9
|
+
} from './capabilities'
|
|
10
|
+
import {applySlotMultiplier, U16_MAX} from '../entities/slot-multiplier'
|
|
11
|
+
import {encodeStats} from './crafting'
|
|
12
|
+
import {
|
|
13
|
+
ITEM_EXTRACTOR_T1_PACKED,
|
|
14
|
+
ITEM_FACTORY_T1_PACKED,
|
|
15
|
+
ITEM_MASS_DRIVER_T1_PACKED,
|
|
16
|
+
ITEM_MASS_CATCHER_T1_PACKED,
|
|
17
|
+
ITEM_GATHERER_T1,
|
|
18
|
+
ITEM_CRAFTER_T1,
|
|
19
|
+
ITEM_LOADER_T1,
|
|
20
|
+
} from '../data/item-ids'
|
|
21
|
+
import type {InstalledModule} from '../entities/slot-multiplier'
|
|
22
|
+
import type {EntitySlot} from '../data/recipes-runtime'
|
|
23
|
+
|
|
24
|
+
function makeGathererStats(strength: number, hardness: number, saturation: number): bigint {
|
|
25
|
+
return encodeStats([strength, hardness, saturation, 0])
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function makeCrafterStats(fineness: number, conductivity: number): bigint {
|
|
29
|
+
return encodeStats([fineness, conductivity])
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeLoaderStats(insulation: number, plasticity: number): bigint {
|
|
33
|
+
return encodeStats([insulation, plasticity])
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
test('computeBaseCapacity uses container formula for all container-class entities', () => {
|
|
37
|
+
const stats = {strength: 300, hardness: 400, density: 100}
|
|
38
|
+
const expected = computeContainerCapabilities(stats).capacity
|
|
39
|
+
for (const itemId of [
|
|
40
|
+
ITEM_EXTRACTOR_T1_PACKED,
|
|
41
|
+
ITEM_FACTORY_T1_PACKED,
|
|
42
|
+
ITEM_MASS_DRIVER_T1_PACKED,
|
|
43
|
+
ITEM_MASS_CATCHER_T1_PACKED,
|
|
44
|
+
]) {
|
|
45
|
+
expect(computeBaseCapacity(itemId, stats)).toBe(expected)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('computeEntityCapabilities emits gathererLanes alongside legacy gatherer sum', () => {
|
|
50
|
+
// Two gatherers with distinct stats in separate slots, amp=100 for both
|
|
51
|
+
const gathStats1 = makeGathererStats(300, 200, 400)
|
|
52
|
+
const gathStats2 = makeGathererStats(500, 100, 300)
|
|
53
|
+
|
|
54
|
+
const modules: InstalledModule[] = [
|
|
55
|
+
{slotIndex: 0, itemId: ITEM_GATHERER_T1, stats: gathStats1},
|
|
56
|
+
{slotIndex: 1, itemId: ITEM_GATHERER_T1, stats: gathStats2},
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
const layout: EntitySlot[] = [
|
|
60
|
+
{type: 'gatherer', outputPct: 100, maxTier: 1},
|
|
61
|
+
{type: 'gatherer', outputPct: 100, maxTier: 1},
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
const result = computeEntityCapabilities({}, ITEM_EXTRACTOR_T1_PACKED, modules, layout)
|
|
65
|
+
|
|
66
|
+
// Lane lists must exist
|
|
67
|
+
expect(result.gathererLanes).toBeDefined()
|
|
68
|
+
expect(result.gathererLanes!.length).toBe(2)
|
|
69
|
+
|
|
70
|
+
// Each lane has the right slotIndex
|
|
71
|
+
expect(result.gathererLanes![0].slotIndex).toBe(0)
|
|
72
|
+
expect(result.gathererLanes![1].slotIndex).toBe(1)
|
|
73
|
+
|
|
74
|
+
// Yields are amp-scaled and distinct
|
|
75
|
+
const caps1 = computeGathererCapabilities({strength: 300, hardness: 200, saturation: 400}, 1)
|
|
76
|
+
const caps2 = computeGathererCapabilities({strength: 500, hardness: 100, saturation: 300}, 1)
|
|
77
|
+
const expectedYield1 = applySlotMultiplier(caps1.yield, 100)
|
|
78
|
+
const expectedYield2 = applySlotMultiplier(caps2.yield, 100)
|
|
79
|
+
expect(result.gathererLanes![0].yield).toBe(expectedYield1)
|
|
80
|
+
expect(result.gathererLanes![1].yield).toBe(expectedYield2)
|
|
81
|
+
expect(result.gathererLanes![0].yield).not.toBe(result.gathererLanes![1].yield)
|
|
82
|
+
|
|
83
|
+
// Unscaled per-module drain and depth carried verbatim from the compute helper
|
|
84
|
+
expect(result.gathererLanes![0].drain).toBe(caps1.drain)
|
|
85
|
+
expect(result.gathererLanes![1].drain).toBe(caps2.drain)
|
|
86
|
+
expect(result.gathererLanes![0].depth).toBe(caps1.depth)
|
|
87
|
+
expect(result.gathererLanes![1].depth).toBe(caps2.depth)
|
|
88
|
+
|
|
89
|
+
// outputPct reflects the slot amp
|
|
90
|
+
expect(result.gathererLanes![0].outputPct).toBe(100)
|
|
91
|
+
expect(result.gathererLanes![1].outputPct).toBe(100)
|
|
92
|
+
|
|
93
|
+
// Legacy sum still equals sum of both lane yields
|
|
94
|
+
expect(result.gatherer).toBeDefined()
|
|
95
|
+
expect(result.gatherer!.yield).toBe(expectedYield1 + expectedYield2)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('computeEntityCapabilities emits crafterLanes alongside legacy crafter sum', () => {
|
|
99
|
+
const crafterStats = makeCrafterStats(400, 300)
|
|
100
|
+
|
|
101
|
+
const modules: InstalledModule[] = [
|
|
102
|
+
{slotIndex: 0, itemId: ITEM_CRAFTER_T1, stats: crafterStats},
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
const layout: EntitySlot[] = [{type: 'crafter', outputPct: 120, maxTier: 1}]
|
|
106
|
+
|
|
107
|
+
const result = computeEntityCapabilities({}, ITEM_EXTRACTOR_T1_PACKED, modules, layout)
|
|
108
|
+
|
|
109
|
+
expect(result.crafterLanes).toBeDefined()
|
|
110
|
+
expect(result.crafterLanes!.length).toBe(1)
|
|
111
|
+
expect(result.crafterLanes![0].slotIndex).toBe(0)
|
|
112
|
+
|
|
113
|
+
const caps = computeCrafterCapabilities({fineness: 400, conductivity: 300})
|
|
114
|
+
const expectedSpeed = applySlotMultiplier(caps.speed, 120)
|
|
115
|
+
expect(result.crafterLanes![0].speed).toBe(expectedSpeed)
|
|
116
|
+
expect(result.crafterLanes![0].drain).toBe(caps.drain)
|
|
117
|
+
expect(result.crafterLanes![0].outputPct).toBe(120)
|
|
118
|
+
|
|
119
|
+
// Legacy crafter speed equals single-lane speed
|
|
120
|
+
expect(result.crafter).toBeDefined()
|
|
121
|
+
expect(result.crafter!.speed).toBe(expectedSpeed)
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
test('computeEntityCapabilities emits loaderLanes alongside legacy loaders sum', () => {
|
|
125
|
+
const loaderStats = makeLoaderStats(600, 500)
|
|
126
|
+
|
|
127
|
+
const modules: InstalledModule[] = [{slotIndex: 0, itemId: ITEM_LOADER_T1, stats: loaderStats}]
|
|
128
|
+
|
|
129
|
+
const layout: EntitySlot[] = [{type: 'loader', outputPct: 80, maxTier: 1}]
|
|
130
|
+
|
|
131
|
+
const result = computeEntityCapabilities({}, ITEM_EXTRACTOR_T1_PACKED, modules, layout)
|
|
132
|
+
|
|
133
|
+
expect(result.loaderLanes).toBeDefined()
|
|
134
|
+
expect(result.loaderLanes!.length).toBe(1)
|
|
135
|
+
expect(result.loaderLanes![0].slotIndex).toBe(0)
|
|
136
|
+
|
|
137
|
+
const caps = computeLoaderCapabilities({insulation: 600, plasticity: 500})
|
|
138
|
+
// mass is unscaled (raw); thrust is amp-scaled
|
|
139
|
+
expect(result.loaderLanes![0].mass).toBe(caps.mass)
|
|
140
|
+
expect(result.loaderLanes![0].thrust).toBe(applySlotMultiplier(caps.thrust, 80))
|
|
141
|
+
expect(result.loaderLanes![0].outputPct).toBe(80)
|
|
142
|
+
|
|
143
|
+
// Legacy loaders.mass is total (same as single-lane raw mass here)
|
|
144
|
+
expect(result.loaders).toBeDefined()
|
|
145
|
+
expect(result.loaders!.mass).toBe(caps.mass)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
test('per-lane amp-scaled stats clamp to UInt16, matching the contract clamp_to_uint16', () => {
|
|
149
|
+
expect(applySlotMultiplier(60000, 200)).toBe(U16_MAX)
|
|
150
|
+
expect(applySlotMultiplier(1000, 150)).toBe(1500)
|
|
151
|
+
})
|