@shipload/sdk 1.0.0-next.4 → 1.0.0-next.41
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 +34 -0
- package/lib/scan.js +136 -0
- package/lib/scan.js.map +1 -0
- package/lib/scan.m.js +129 -0
- package/lib/scan.m.js.map +1 -0
- package/lib/shipload.d.ts +2473 -973
- package/lib/shipload.js +11529 -5211
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +11338 -5162
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +970 -0
- package/lib/testing.js +4013 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +4007 -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 +5 -6
- package/src/capabilities/gathering.test.ts +16 -0
- package/src/capabilities/gathering.ts +35 -18
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/modules.ts +9 -0
- package/src/capabilities/storage.ts +16 -1
- package/src/contracts/platform.ts +231 -3
- package/src/contracts/server.ts +1021 -481
- 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 +12 -5
- package/src/data/capability-formulas.ts +14 -7
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +14 -47
- package/src/data/entities.json +76 -10
- package/src/data/item-ids.ts +18 -12
- package/src/data/items.json +321 -38
- package/src/data/kind-registry.json +109 -0
- package/src/data/kind-registry.ts +165 -0
- package/src/data/metadata.ts +119 -33
- package/src/data/recipes-runtime.ts +3 -23
- package/src/data/recipes.json +238 -117
- package/src/derivation/build-methods.ts +45 -0
- package/src/derivation/capabilities.test.ts +151 -0
- package/src/derivation/capabilities.ts +512 -0
- package/src/derivation/capability-mappings.ts +9 -12
- package/src/derivation/crafting.ts +23 -24
- package/src/derivation/index.ts +25 -2
- package/src/derivation/recipe-usage.test.ts +78 -0
- package/src/derivation/recipe-usage.ts +141 -0
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +125 -38
- package/src/derivation/rollups.test.ts +55 -0
- package/src/derivation/rollups.ts +56 -0
- package/src/derivation/stars.test.ts +51 -0
- package/src/derivation/stars.ts +15 -0
- package/src/derivation/stats.ts +6 -6
- package/src/derivation/stratum.ts +17 -20
- package/src/derivation/tiers.ts +40 -7
- package/src/derivation/wormhole.ts +136 -0
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +124 -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 +267 -47
- package/src/managers/actions.ts +528 -95
- package/src/managers/base.ts +6 -2
- package/src/managers/construction-types.ts +80 -0
- package/src/managers/construction.ts +412 -0
- package/src/managers/context.ts +20 -1
- package/src/managers/coordinates.ts +14 -0
- package/src/managers/entities.ts +18 -66
- package/src/managers/epochs.ts +40 -0
- package/src/managers/index.ts +17 -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/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 +338 -0
- package/src/nft/description.ts +98 -24
- package/src/nft/index.ts +3 -0
- package/src/planner/index.ts +127 -0
- package/src/planner/planner.test.ts +319 -0
- package/src/resolution/describe-module.ts +18 -13
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.test.ts +37 -0
- package/src/resolution/resolve-item.ts +55 -24
- package/src/scan/index.ts +180 -0
- package/src/scan/scan-wasm.base64.ts +2 -0
- package/src/scheduling/accessor.ts +68 -22
- 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 +209 -105
- package/src/scheduling/schedule.ts +241 -104
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/shipload.ts +21 -1
- package/src/subscriptions/manager.ts +229 -142
- package/src/subscriptions/mappers.ts +5 -8
- package/src/subscriptions/types.ts +11 -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 +196 -0
- package/src/travel/travel.ts +200 -112
- 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 +28 -13
- package/src/utils/cargo.ts +27 -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 -108
- package/src/entities/ship-deploy.ts +0 -259
- package/src/entities/ship.ts +0 -204
- package/src/entities/warehouse.ts +0 -119
- package/src/types/entity-traits.ts +0 -69
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type {ServerContract} from '../contracts'
|
|
2
|
+
import {getItem} from '../data/catalog'
|
|
3
|
+
import {getEntityLayout} from '../data/recipes-runtime'
|
|
4
|
+
import {decodeStat} from '../derivation/crafting'
|
|
5
|
+
import {gathererDepthForTier} from '../derivation/capabilities'
|
|
6
|
+
import {applySlotMultiplier, getSlotAmp} from '../entities/slot-multiplier'
|
|
7
|
+
import {
|
|
8
|
+
computeGathererYield,
|
|
9
|
+
computeGathererDrain,
|
|
10
|
+
computeLoaderThrust,
|
|
11
|
+
computeLoaderMass,
|
|
12
|
+
computeCrafterSpeed,
|
|
13
|
+
computeCrafterDrain,
|
|
14
|
+
} from '../nft/description'
|
|
15
|
+
import type {ModuleType} from '../types'
|
|
16
|
+
import {getLane, LANE_MOBILITY, type ScheduleData} from './schedule'
|
|
17
|
+
|
|
18
|
+
type ModuleEntry = ServerContract.Types.module_entry
|
|
19
|
+
type Lane = ServerContract.Types.lane
|
|
20
|
+
type Schedule = ServerContract.Types.schedule
|
|
21
|
+
|
|
22
|
+
export interface ResolvedGathererLane {
|
|
23
|
+
slotIndex: number
|
|
24
|
+
yield: number
|
|
25
|
+
drain: number
|
|
26
|
+
depth: number
|
|
27
|
+
outputPct: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ResolvedCrafterLane {
|
|
31
|
+
slotIndex: number
|
|
32
|
+
speed: number
|
|
33
|
+
drain: number
|
|
34
|
+
outputPct: number
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ResolvedLoaderLane {
|
|
38
|
+
slotIndex: number
|
|
39
|
+
thrust: number
|
|
40
|
+
mass: number
|
|
41
|
+
outputPct: number
|
|
42
|
+
valid: boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function laneKeyForModule(slotIndex: number): number {
|
|
46
|
+
return slotIndex + 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function laneIsFree(lanes: Lane[], laneKey: number): boolean {
|
|
50
|
+
const lane = lanes.find((entry) => entry.lane_key.toNumber() === laneKey)
|
|
51
|
+
return lane ? lane.schedule.tasks.length === 0 : true
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function resolveLaneGatherer(
|
|
55
|
+
modules: ModuleEntry[],
|
|
56
|
+
entityItemId: number,
|
|
57
|
+
laneKey: number
|
|
58
|
+
): ResolvedGathererLane {
|
|
59
|
+
const idx = laneKey - 1
|
|
60
|
+
const installed = idx >= 0 && idx < modules.length ? modules[idx].installed : undefined
|
|
61
|
+
if (!installed) throw new Error('gatherer lane has no module')
|
|
62
|
+
const item = getItem(Number(installed.item_id.value ?? installed.item_id))
|
|
63
|
+
if (item.moduleType !== 'gatherer') throw new Error('lane module is not a gatherer')
|
|
64
|
+
const stats = BigInt(installed.stats.toString())
|
|
65
|
+
const str = decodeStat(stats, 0)
|
|
66
|
+
const tol = decodeStat(stats, 1)
|
|
67
|
+
const con = decodeStat(stats, 2)
|
|
68
|
+
const layout = getEntityLayout(entityItemId)?.slots ?? []
|
|
69
|
+
const amp = getSlotAmp(layout, idx)
|
|
70
|
+
const yieldVal = applySlotMultiplier(computeGathererYield(str), amp)
|
|
71
|
+
const drain = computeGathererDrain(con)
|
|
72
|
+
const depth = gathererDepthForTier(tol, item.tier ?? 1)
|
|
73
|
+
return {slotIndex: idx, yield: yieldVal, drain, depth, outputPct: amp}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Encapsulates the gather handler's lane selection (gathering.cpp:108-112): both error paths.
|
|
77
|
+
export function selectGatherLane(
|
|
78
|
+
modules: ModuleEntry[],
|
|
79
|
+
entityItemId: number,
|
|
80
|
+
lanes: Lane[],
|
|
81
|
+
stratum: number,
|
|
82
|
+
explicitSlot?: number
|
|
83
|
+
): number {
|
|
84
|
+
if (explicitSlot !== undefined) {
|
|
85
|
+
const laneKey = laneKeyForModule(explicitSlot)
|
|
86
|
+
const lane = resolveLaneGatherer(modules, entityItemId, laneKey)
|
|
87
|
+
if (stratum > lane.depth) throw new Error('stratum exceeds gatherer depth')
|
|
88
|
+
return laneKey
|
|
89
|
+
}
|
|
90
|
+
return workerLaneKey(modules, 'gatherer', lanes, stratum)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function resolveLaneCrafter(
|
|
94
|
+
modules: ModuleEntry[],
|
|
95
|
+
entityItemId: number,
|
|
96
|
+
laneKey: number
|
|
97
|
+
): ResolvedCrafterLane {
|
|
98
|
+
const idx = laneKey - 1
|
|
99
|
+
const installed = idx >= 0 && idx < modules.length ? modules[idx].installed : undefined
|
|
100
|
+
if (!installed) throw new Error('crafter lane has no module')
|
|
101
|
+
const item = getItem(Number(installed.item_id.value ?? installed.item_id))
|
|
102
|
+
if (item.moduleType !== 'crafter') throw new Error('lane module is not a crafter')
|
|
103
|
+
const stats = BigInt(installed.stats.toString())
|
|
104
|
+
const rea = decodeStat(stats, 0)
|
|
105
|
+
const fin = decodeStat(stats, 1)
|
|
106
|
+
const layout = getEntityLayout(entityItemId)?.slots ?? []
|
|
107
|
+
const amp = getSlotAmp(layout, idx)
|
|
108
|
+
const speed = applySlotMultiplier(computeCrafterSpeed(rea), amp)
|
|
109
|
+
const drain = computeCrafterDrain(fin)
|
|
110
|
+
return {slotIndex: idx, speed, drain, outputPct: amp}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// LANE_MOBILITY or a missing module soft-returns valid=false (never throws); callers check `valid`.
|
|
114
|
+
export function resolveLaneLoader(
|
|
115
|
+
modules: ModuleEntry[],
|
|
116
|
+
entityItemId: number,
|
|
117
|
+
laneKey: number
|
|
118
|
+
): ResolvedLoaderLane {
|
|
119
|
+
if (laneKey === LANE_MOBILITY) {
|
|
120
|
+
return {slotIndex: -1, thrust: 0, mass: 0, outputPct: 0, valid: false}
|
|
121
|
+
}
|
|
122
|
+
const idx = laneKey - 1
|
|
123
|
+
const installed = idx >= 0 && idx < modules.length ? modules[idx].installed : undefined
|
|
124
|
+
if (!installed) {
|
|
125
|
+
return {slotIndex: idx, thrust: 0, mass: 0, outputPct: 0, valid: false}
|
|
126
|
+
}
|
|
127
|
+
const stats = BigInt(installed.stats.toString())
|
|
128
|
+
const ins = decodeStat(stats, 0)
|
|
129
|
+
const pla = decodeStat(stats, 1)
|
|
130
|
+
const layout = getEntityLayout(entityItemId)?.slots ?? []
|
|
131
|
+
const amp = getSlotAmp(layout, idx)
|
|
132
|
+
const thrust = applySlotMultiplier(computeLoaderThrust(pla), amp)
|
|
133
|
+
const mass = computeLoaderMass(ins)
|
|
134
|
+
return {slotIndex: idx, thrust, mass, outputPct: amp, valid: true}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function workerLaneKey(
|
|
138
|
+
modules: ModuleEntry[],
|
|
139
|
+
moduleSubtype: ModuleType,
|
|
140
|
+
lanes: Lane[],
|
|
141
|
+
stratum?: number
|
|
142
|
+
): number {
|
|
143
|
+
if (moduleSubtype === 'gatherer' && stratum !== undefined) {
|
|
144
|
+
let lowestReaching: number | undefined
|
|
145
|
+
for (let i = 0; i < modules.length; i++) {
|
|
146
|
+
const installed = modules[i].installed
|
|
147
|
+
if (!installed) continue
|
|
148
|
+
const item = getItem(Number(installed.item_id.value ?? installed.item_id))
|
|
149
|
+
if (item.moduleType !== 'gatherer') continue
|
|
150
|
+
const stats = BigInt(installed.stats.toString())
|
|
151
|
+
const tol = decodeStat(stats, 1)
|
|
152
|
+
const depth = gathererDepthForTier(tol, item.tier ?? 1)
|
|
153
|
+
if (depth < stratum) continue
|
|
154
|
+
const laneKey = laneKeyForModule(i)
|
|
155
|
+
if (lowestReaching === undefined) lowestReaching = laneKey
|
|
156
|
+
if (laneIsFree(lanes, laneKey)) return laneKey
|
|
157
|
+
}
|
|
158
|
+
if (lowestReaching === undefined) throw new Error('no gatherer reaches this stratum')
|
|
159
|
+
return lowestReaching
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const occupiedMatchingLaneKeys: number[] = []
|
|
163
|
+
|
|
164
|
+
for (let slotIndex = 0; slotIndex < modules.length; slotIndex++) {
|
|
165
|
+
const installed = modules[slotIndex].installed
|
|
166
|
+
if (!installed) continue
|
|
167
|
+
if (getItem(installed.item_id).moduleType !== moduleSubtype) continue
|
|
168
|
+
|
|
169
|
+
const laneKey = laneKeyForModule(slotIndex)
|
|
170
|
+
if (laneIsFree(lanes, laneKey)) return laneKey
|
|
171
|
+
occupiedMatchingLaneKeys.push(laneKey)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (occupiedMatchingLaneKeys.length > 0) {
|
|
175
|
+
return Math.min(...occupiedMatchingLaneKeys)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
throw new Error(`No installed ${moduleSubtype} worker module`)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function rawScheduleEnd(schedule: Schedule): Date {
|
|
182
|
+
const durationSec = schedule.tasks.reduce((sum, task) => sum + task.duration.toNumber(), 0)
|
|
183
|
+
return new Date(schedule.started.toDate().getTime() + durationSec * 1000)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function candidateLaneCompletesAt(
|
|
187
|
+
entity: ScheduleData,
|
|
188
|
+
laneKey: number,
|
|
189
|
+
durationSec: number,
|
|
190
|
+
now: Date
|
|
191
|
+
): Date {
|
|
192
|
+
const lane = getLane(entity, laneKey)
|
|
193
|
+
const startMs = lane
|
|
194
|
+
? Math.max(rawScheduleEnd(lane.schedule).getTime(), now.getTime())
|
|
195
|
+
: now.getTime()
|
|
196
|
+
|
|
197
|
+
return new Date(startMs + durationSec * 1000)
|
|
198
|
+
}
|