@shipload/sdk 2.0.0-rc5 → 2.0.0-rc7

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 (52) hide show
  1. package/README.md +1 -349
  2. package/lib/shipload.d.ts +607 -1113
  3. package/lib/shipload.js +1482 -2077
  4. package/lib/shipload.js.map +1 -1
  5. package/lib/shipload.m.js +1421 -2038
  6. package/lib/shipload.m.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/capabilities/crafting.ts +28 -0
  9. package/src/capabilities/extraction.ts +14 -8
  10. package/src/capabilities/guards.ts +0 -5
  11. package/src/capabilities/index.ts +2 -0
  12. package/src/capabilities/modules.ts +49 -0
  13. package/src/capabilities/storage.ts +0 -8
  14. package/src/contracts/server.ts +231 -313
  15. package/src/data/colors.ts +28 -0
  16. package/src/data/items.json +15 -15
  17. package/src/data/recipes.ts +351 -0
  18. package/src/derivation/crafting.ts +142 -0
  19. package/src/derivation/index.ts +1 -0
  20. package/src/derivation/stats.ts +91 -15
  21. package/src/derivation/stratum.ts +2 -2
  22. package/src/entities/cargo-utils.ts +6 -64
  23. package/src/entities/container.ts +18 -0
  24. package/src/entities/entity-inventory.ts +0 -4
  25. package/src/entities/inventory-accessor.ts +0 -4
  26. package/src/entities/location.ts +2 -197
  27. package/src/entities/makers.ts +10 -9
  28. package/src/entities/player.ts +1 -274
  29. package/src/entities/ship-deploy.ts +89 -0
  30. package/src/entities/ship.ts +14 -27
  31. package/src/entities/warehouse.ts +0 -4
  32. package/src/index-module.ts +66 -41
  33. package/src/managers/actions.ts +77 -88
  34. package/src/managers/context.ts +0 -9
  35. package/src/managers/index.ts +0 -1
  36. package/src/managers/locations.ts +2 -85
  37. package/src/market/items.ts +0 -1
  38. package/src/resolution/resolve-item.ts +242 -0
  39. package/src/scheduling/projection.ts +0 -10
  40. package/src/shipload.ts +0 -5
  41. package/src/travel/travel.ts +3 -3
  42. package/src/types/capabilities.ts +1 -9
  43. package/src/types/entity-traits.ts +3 -4
  44. package/src/types/entity.ts +3 -4
  45. package/src/types.ts +6 -43
  46. package/src/utils/system.ts +5 -4
  47. package/src/managers/trades.ts +0 -119
  48. package/src/market/market.ts +0 -195
  49. package/src/market/rolls.ts +0 -8
  50. package/src/trading/collect.ts +0 -938
  51. package/src/trading/deal.ts +0 -207
  52. package/src/trading/trade.ts +0 -203
@@ -20,10 +20,6 @@ export interface LoaderCapability {
20
20
  loaders: ServerContract.Types.loader_stats
21
21
  }
22
22
 
23
- export interface TradeCapability {
24
- trade: ServerContract.Types.trade_stats
25
- }
26
-
27
23
  export interface ExtractorCapability {
28
24
  extractor: ServerContract.Types.extractor_stats
29
25
  }
@@ -42,8 +38,8 @@ export interface EntityCapabilities {
42
38
  engines?: ServerContract.Types.movement_stats
43
39
  generator?: ServerContract.Types.energy_stats
44
40
  loaders?: ServerContract.Types.loader_stats
45
- trade?: ServerContract.Types.trade_stats
46
41
  extractor?: ServerContract.Types.extractor_stats
42
+ crafter?: ServerContract.Types.crafter_stats
47
43
  }
48
44
 
49
45
  export interface EntityState {
@@ -66,10 +62,6 @@ export function capsHasLoaders(caps: EntityCapabilities): boolean {
66
62
  return caps.loaders !== undefined
67
63
  }
68
64
 
69
- export function capsHasTrade(caps: EntityCapabilities): boolean {
70
- return caps.trade !== undefined
71
- }
72
-
73
65
  export function capsHasExtractor(caps: EntityCapabilities): boolean {
74
66
  return caps.extractor !== undefined
75
67
  }
@@ -11,7 +11,6 @@ export interface EntityTraits {
11
11
  isMovable: boolean
12
12
  hasEnergy: boolean
13
13
  hasLoaders: boolean
14
- hasTrade: boolean
15
14
  notFoundError: string
16
15
  }
17
16
 
@@ -20,7 +19,7 @@ export const shipTraits: EntityTraits = {
20
19
  isMovable: true,
21
20
  hasEnergy: true,
22
21
  hasLoaders: true,
23
- hasTrade: true,
22
+
24
23
  notFoundError: 'ship not found',
25
24
  }
26
25
 
@@ -29,7 +28,7 @@ export const warehouseTraits: EntityTraits = {
29
28
  isMovable: false,
30
29
  hasEnergy: false,
31
30
  hasLoaders: true,
32
- hasTrade: false,
31
+
33
32
  notFoundError: 'warehouse not found',
34
33
  }
35
34
 
@@ -38,7 +37,7 @@ export const containerTraits: EntityTraits = {
38
37
  isMovable: true,
39
38
  hasEnergy: false,
40
39
  hasLoaders: false,
41
- hasTrade: false,
40
+
42
41
  notFoundError: 'container not found',
43
42
  }
44
43
 
@@ -19,13 +19,12 @@ export interface Entity {
19
19
  }
20
20
 
21
21
  export type ShipEntity = Entity &
22
- MovementCapability &
23
- EnergyCapability &
22
+ Partial<MovementCapability> &
23
+ Partial<EnergyCapability> &
24
24
  StorageCapability &
25
- LoaderCapability &
25
+ Partial<LoaderCapability> &
26
26
  MassCapability &
27
27
  ScheduleCapability & {
28
- trade?: ServerContract.Types.trade_stats
29
28
  extractor?: ServerContract.Types.extractor_stats
30
29
  }
31
30
 
package/src/types.ts CHANGED
@@ -12,44 +12,19 @@ import {ServerContract} from './contracts'
12
12
 
13
13
  export const PRECISION = 10000
14
14
 
15
- // Ship constants
16
- export const INITIAL_SHIP_GENERATOR_CAPACITY = 350
17
- export const INITIAL_SHIP_DRAIN = 25
18
- export const INITIAL_SHIP_ENERGY = 350
19
- export const INITIAL_SHIP_HULLMASS = 100000
20
- export const INITIAL_SHIP_CAPACITY = 500000
21
- export const INITIAL_SHIP_Z = 800
22
- export const INITIAL_SHIP_RECHARGE = 10
23
- export const INITIAL_SHIP_THRUST = 250
24
-
25
- // Loader constants
26
- export const INITIAL_LOADER_MASS = 1000
27
- export const INITIAL_LOADER_QUANTITY = 1
28
- export const INITIAL_LOADER_THRUST = 1
29
-
30
- // Warehouse constants
31
15
  export const WAREHOUSE_Z = 500
32
16
  export const INITIAL_WAREHOUSE_CAPACITY = 10000000
33
17
 
34
- // Container constants
35
18
  export const CONTAINER_Z = 300
36
19
  export const INITIAL_CONTAINER_HULLMASS = 50000
37
20
  export const INITIAL_CONTAINER_CAPACITY = 2000000
38
21
 
39
- // Mechanics
40
22
  export const TRAVEL_MAX_DURATION = 86400
41
23
 
42
- // Altitude limits (for UI/calculations)
43
24
  export const MIN_ORBITAL_ALTITUDE = 800
44
25
  export const MAX_ORBITAL_ALTITUDE = 3000
45
26
 
46
- // Legacy alias (deprecated, use INITIAL_SHIP_CAPACITY)
47
- export const INITIAL_SHIP_MASS = 500000
48
-
49
- // Extractor constants
50
- export const INITIAL_EXTRACTOR_RATE = 700
51
- export const INITIAL_EXTRACTOR_DRAIN = 2500
52
- export const INITIAL_EXTRACTOR_EFFICIENCY = 5000
27
+ export const BASE_ORBITAL_MASS = 100000
53
28
 
54
29
  export interface ShipLike {
55
30
  coordinates: ServerContract.Types.coordinates
@@ -74,6 +49,8 @@ export enum TaskType {
74
49
  UNLOAD = 4,
75
50
  EXTRACT = 5,
76
51
  WARP = 6,
52
+ CRAFT = 7,
53
+ DEPLOY = 8,
77
54
  }
78
55
 
79
56
  export enum LocationType {
@@ -84,9 +61,9 @@ export enum LocationType {
84
61
  }
85
62
 
86
63
  export enum TaskCancelable {
87
- NEVER = 0, // Task cannot be cancelled
88
- BEFORE_START = 1, // Task can only be cancelled before it starts
89
- ALWAYS = 2, // Task can always be cancelled
64
+ NEVER = 0,
65
+ BEFORE_START = 1,
66
+ ALWAYS = 2,
90
67
  }
91
68
 
92
69
  export const EntityType = {
@@ -144,8 +121,6 @@ export class Item extends Struct {
144
121
  @Struct.field('string')
145
122
  description!: string
146
123
  @Struct.field(UInt32)
147
- base_price!: UInt32
148
- @Struct.field(UInt32)
149
124
  mass!: UInt32
150
125
  @Struct.field('string')
151
126
  category!: ResourceCategory
@@ -154,15 +129,3 @@ export class Item extends Struct {
154
129
  @Struct.field('string')
155
130
  color!: string
156
131
  }
157
-
158
- @Struct.type('ItemPrice')
159
- export class ItemPrice extends Struct {
160
- @Struct.field(UInt16)
161
- id!: UInt16
162
- @Struct.field(Item)
163
- item!: Item
164
- @Struct.field(UInt32)
165
- price!: UInt32
166
- @Struct.field(UInt16)
167
- supply!: UInt16
168
- }
@@ -2,6 +2,7 @@ import {Checksum256, Checksum256Type, Checksum512, UInt8} from '@wharfkit/antelo
2
2
  import {hash512} from './hash'
3
3
  import {Coordinates, CoordinatesType, LocationType} from '../types'
4
4
  import {ServerContract} from '../contracts'
5
+ import {deriveLocationSize} from '../derivation/location-size'
5
6
  import syllables from '../data/syllables.json'
6
7
  import nebulaAdjectives from '../data/nebula-adjectives.json'
7
8
  import nebulaNouns from '../data/nebula-nouns.json'
@@ -116,9 +117,7 @@ export function deriveLocationStatic(
116
117
  }
117
118
 
118
119
  loc.subtype = UInt8.from(
119
- Number(loc.type) === LocationType.PLANET
120
- ? hashResult.array[2] % 6
121
- : hashResult.array[2]
120
+ Number(loc.type) === LocationType.PLANET ? hashResult.array[2] % 6 : hashResult.array[2]
122
121
  )
123
122
  loc.seed0 = UInt8.from(hashResult.array[3])
124
123
  loc.seed1 = UInt8.from(hashResult.array[4])
@@ -147,8 +146,10 @@ export function deriveLocation(
147
146
  epochSeed: Checksum256Type,
148
147
  coordinates: CoordinatesType
149
148
  ): ServerContract.Types.location_derived {
149
+ const staticProps = deriveLocationStatic(gameSeed, coordinates)
150
150
  return ServerContract.Types.location_derived.from({
151
- static_props: deriveLocationStatic(gameSeed, coordinates),
151
+ static_props: staticProps,
152
152
  epoch_props: deriveLocationEpoch(epochSeed, coordinates),
153
+ size: deriveLocationSize(staticProps),
153
154
  })
154
155
  }
@@ -1,119 +0,0 @@
1
- import {UInt64} from '@wharfkit/antelope'
2
- import {BaseManager} from './base'
3
- import {Ship} from '../entities/ship'
4
- import {Deal, findDealsForShip, FindDealsOptions} from '../trading/deal'
5
- import {
6
- analyzeCollectOptions,
7
- CollectAnalysis,
8
- CollectAnalysisCallbacks,
9
- CollectAnalysisOptions,
10
- } from '../trading/collect'
11
- import {Coordinates, ItemPrice} from '../types'
12
- import {Location, toLocation} from '../entities/location'
13
- import {findNearbyPlanets} from '../travel/travel'
14
- import {getCurrentEpoch} from '../scheduling/epoch'
15
-
16
- export class TradesManager extends BaseManager {
17
- private priceCache = new Map<string, ItemPrice[]>()
18
- private priceCacheEpoch: UInt64 | undefined
19
-
20
- private makePriceCacheKey(location: Coordinates): string {
21
- return `${location.x},${location.y}`
22
- }
23
-
24
- private async createCallbacks(): Promise<CollectAnalysisCallbacks> {
25
- const game = await this.getGame()
26
- const serverState = await this.getState()
27
- const currentEpoch = getCurrentEpoch(game)
28
-
29
- if (!this.priceCacheEpoch || !this.priceCacheEpoch.equals(currentEpoch)) {
30
- this.priceCache.clear()
31
- this.priceCacheEpoch = currentEpoch
32
- }
33
-
34
- const getNearbyLocations = async (
35
- origin: Coordinates,
36
- maxDistance: number
37
- ): Promise<Location[]> => {
38
- const nearby = findNearbyPlanets(game.config.seed, origin, maxDistance)
39
- return nearby.map((d) => toLocation(d.destination))
40
- }
41
-
42
- const getMarketPrices = async (location: Coordinates): Promise<ItemPrice[]> => {
43
- const cacheKey = this.makePriceCacheKey(location)
44
- const cached = this.priceCache.get(cacheKey)
45
- if (cached) {
46
- return cached
47
- }
48
-
49
- const locationWithSupply = await this.context.locations.getLocationComplete(location)
50
- const prices = locationWithSupply.marketPrices || []
51
-
52
- const result = prices.map((price) => {
53
- const actualSupply = locationWithSupply.getSupply(price.id)
54
-
55
- if (actualSupply !== undefined) {
56
- return ItemPrice.from({
57
- id: price.id,
58
- item: price.item,
59
- price: price.price,
60
- supply: actualSupply,
61
- })
62
- }
63
- return price
64
- })
65
-
66
- this.priceCache.set(cacheKey, result)
67
- return result
68
- }
69
-
70
- const getGameSeed = () => game.config.seed
71
- const getState = () => serverState
72
-
73
- return {getNearbyLocations, getMarketPrices, getGameSeed, getState}
74
- }
75
-
76
- clearPriceCache(): void {
77
- this.priceCache.clear()
78
- this.priceCacheEpoch = undefined
79
- }
80
-
81
- async findDeals(
82
- ship: Ship,
83
- originLocation?: Coordinates,
84
- options: FindDealsOptions = {}
85
- ): Promise<Deal[]> {
86
- const origin = originLocation || Coordinates.from(ship.coordinates)
87
- const callbacks = await this.createCallbacks()
88
-
89
- const deals = await findDealsForShip(
90
- ship,
91
- origin,
92
- callbacks.getNearbyLocations,
93
- callbacks.getMarketPrices,
94
- options
95
- )
96
-
97
- return deals
98
- }
99
-
100
- async findBestDeal(
101
- ship: Ship,
102
- originLocation?: Coordinates,
103
- options: FindDealsOptions = {}
104
- ): Promise<Deal | undefined> {
105
- const deals = await this.findDeals(ship, originLocation, {...options, maxDeals: 1})
106
- return deals[0]
107
- }
108
-
109
- async getCollectOptions(
110
- ship: Ship,
111
- arrivedAt?: Coordinates,
112
- options: CollectAnalysisOptions = {}
113
- ): Promise<CollectAnalysis> {
114
- const location = arrivedAt || Coordinates.from(ship.coordinates)
115
- const callbacks = await this.createCallbacks()
116
-
117
- return analyzeCollectOptions(ship, location, callbacks, options)
118
- }
119
- }
@@ -1,195 +0,0 @@
1
- import {CoordinatesType, ItemPrice} from '../types'
2
- import {getItem, getItems} from './items'
3
- import {Checksum256Type, UInt16, UInt16Type, UInt32} from '@wharfkit/antelope'
4
- import {roll} from './rolls'
5
- import {ServerContract} from '../contracts'
6
-
7
- export enum Rarities {
8
- legendary = 'LEGENDARY',
9
- epic = 'EPIC',
10
- rare = 'RARE',
11
- uncommon = 'UNCOMMON',
12
- common = 'COMMON',
13
- trash = 'TRASH',
14
- }
15
-
16
- export interface Rarity {
17
- rarity: Rarities
18
- minMultiplier: number
19
- maxMultiplier: number
20
- }
21
-
22
- export function getRarity(
23
- gameSeed: Checksum256Type,
24
- epochSeed: Checksum256Type,
25
- location: CoordinatesType,
26
- goodId: UInt16Type
27
- ): Rarity {
28
- const seed = `${epochSeed}${location.x}${location.y}${goodId}rarity`
29
- const rarityRoll = roll(gameSeed, seed)
30
-
31
- if (rarityRoll < 13) {
32
- return {
33
- rarity: Rarities.legendary,
34
- minMultiplier: 2.25,
35
- maxMultiplier: 3.0,
36
- }
37
- } else if (rarityRoll < 176) {
38
- return {
39
- rarity: Rarities.epic,
40
- minMultiplier: 1.75,
41
- maxMultiplier: 2.25,
42
- }
43
- } else if (rarityRoll < 996) {
44
- return {
45
- rarity: Rarities.rare,
46
- minMultiplier: 1.4,
47
- maxMultiplier: 1.75,
48
- }
49
- } else if (rarityRoll < 2966) {
50
- return {
51
- rarity: Rarities.uncommon,
52
- minMultiplier: 1.225,
53
- maxMultiplier: 1.4,
54
- }
55
- } else if (rarityRoll < 19568) {
56
- return {
57
- rarity: Rarities.common,
58
- minMultiplier: 1.07,
59
- maxMultiplier: 1.225,
60
- }
61
- } else if (rarityRoll < 45988) {
62
- return {
63
- rarity: Rarities.trash,
64
- minMultiplier: 1,
65
- maxMultiplier: 1.07,
66
- }
67
- } else if (rarityRoll < 62508) {
68
- return {
69
- rarity: Rarities.common,
70
- minMultiplier: 0.925,
71
- maxMultiplier: 1,
72
- }
73
- } else if (rarityRoll < 64518) {
74
- return {
75
- rarity: Rarities.uncommon,
76
- minMultiplier: 0.77,
77
- maxMultiplier: 0.925,
78
- }
79
- } else if (rarityRoll < 65437) {
80
- return {
81
- rarity: Rarities.rare,
82
- minMultiplier: 0.595,
83
- maxMultiplier: 0.77,
84
- }
85
- } else if (rarityRoll < 65523) {
86
- return {
87
- rarity: Rarities.epic,
88
- minMultiplier: 0.41,
89
- maxMultiplier: 0.595,
90
- }
91
- } else {
92
- return {
93
- rarity: Rarities.legendary,
94
- minMultiplier: 0.285,
95
- maxMultiplier: 0.41,
96
- }
97
- }
98
- }
99
-
100
- export function getRarityMultiplier(
101
- gameSeed: Checksum256Type,
102
- epochSeed: Checksum256Type,
103
- location: CoordinatesType,
104
- goodId: UInt16Type
105
- ): number {
106
- const rarity = getRarity(gameSeed, epochSeed, location, goodId)
107
- const range = rarity.maxMultiplier - rarity.minMultiplier
108
- const seed = `${epochSeed}${location.x}${location.y}${goodId}raritymultiplier`
109
- const r = roll(gameSeed, seed)
110
- return rarity.minMultiplier + (r / 65535) * range
111
- }
112
-
113
- export function getLocationMultiplier(
114
- gameSeed: Checksum256Type,
115
- location: CoordinatesType,
116
- goodId: UInt16Type
117
- ): number {
118
- const seed = `${location.x}${location.y}${goodId}locationmultiplier`
119
- const r = roll(gameSeed, seed)
120
- if (r < 13) {
121
- return 0.75
122
- } else if (r < 176) {
123
- return 0.8
124
- } else if (r < 996) {
125
- return 0.85
126
- } else if (r < 2966) {
127
- return 0.9
128
- } else if (r < 19568) {
129
- return 0.95
130
- } else if (r < 45988) {
131
- return 1
132
- } else if (r < 62508) {
133
- return 1.05
134
- } else if (r < 64518) {
135
- return 1.1
136
- } else if (r < 65437) {
137
- return 1.15
138
- } else if (r < 65523) {
139
- return 1.2
140
- } else {
141
- return 1.25
142
- }
143
- }
144
-
145
- export function getSupply(
146
- gameSeed: Checksum256Type,
147
- state: ServerContract.Types.state_row,
148
- location: CoordinatesType,
149
- goodId: UInt16Type
150
- ): number {
151
- const seed = `${state.seed}${location.x}${location.y}${goodId}supply`
152
- const r = roll(gameSeed, seed)
153
- const percent = r / 65535
154
- const epoch = 1 + Number(state.epoch) / 90
155
- const ship = 1
156
- const goodIdNum = Number(goodId)
157
- const base = Math.floor(128 / goodIdNum)
158
- return Math.floor(base * percent * ship * epoch)
159
- }
160
-
161
- export function marketPrice(
162
- location: ServerContract.ActionParams.Type.coordinates,
163
- goodId: UInt16Type,
164
- gameSeed: Checksum256Type,
165
- state: ServerContract.Types.state_row
166
- ): ItemPrice {
167
- const item = getItem(goodId)
168
- let price = Number(item.base_price)
169
-
170
- const rarityMultiplier = getRarityMultiplier(gameSeed, state.seed, location, goodId)
171
- price *= rarityMultiplier
172
-
173
- // Location multiplier of the deal (static, based on game seed)
174
- // Small impact range on price, from 1.0x to 1.5x
175
- const locationMultiplier = getLocationMultiplier(gameSeed, location, goodId)
176
- price *= locationMultiplier
177
-
178
- // Determine the current supply of the good at the location
179
- const supply = getSupply(gameSeed, state, location, goodId)
180
-
181
- return ItemPrice.from({
182
- id: goodId,
183
- item,
184
- price: UInt32.from(price),
185
- supply: UInt16.from(supply),
186
- })
187
- }
188
-
189
- export function marketPrices(
190
- location: ServerContract.ActionParams.Type.coordinates,
191
- gameSeed: Checksum256Type,
192
- state: ServerContract.Types.state_row
193
- ): ItemPrice[] {
194
- return getItems().map((item) => marketPrice(location, item.id, gameSeed, state))
195
- }
@@ -1,8 +0,0 @@
1
- import {Checksum256Type} from '@wharfkit/antelope'
2
- import {hash512} from '../utils/hash'
3
-
4
- export function roll(gameSeed: Checksum256Type, rollSeed: string): number {
5
- const hash = hash512(gameSeed, rollSeed)
6
- // Combine the first two bytes to form a uint16_t value
7
- return (hash.array[0] << 8) | hash.array[1]
8
- }