@shipload/sdk 2.0.0-rc1 → 2.0.0-rc11

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 (74) hide show
  1. package/lib/shipload.d.ts +1701 -1183
  2. package/lib/shipload.js +6746 -3447
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +6429 -3229
  5. package/lib/shipload.m.js.map +1 -1
  6. package/package.json +6 -6
  7. package/src/capabilities/crafting.ts +26 -0
  8. package/src/capabilities/gathering.ts +36 -0
  9. package/src/capabilities/guards.ts +38 -0
  10. package/src/capabilities/hauling.ts +22 -0
  11. package/src/capabilities/index.ts +8 -0
  12. package/src/capabilities/loading.ts +8 -0
  13. package/src/capabilities/modules.ts +57 -0
  14. package/src/capabilities/movement.ts +29 -0
  15. package/src/capabilities/storage.ts +72 -0
  16. package/src/contracts/server.ts +932 -314
  17. package/src/data/capabilities.ts +408 -0
  18. package/src/data/categories.ts +58 -0
  19. package/src/data/colors.ts +53 -0
  20. package/src/data/items.json +17 -0
  21. package/src/data/locations.ts +53 -0
  22. package/src/data/nebula-adjectives.json +211 -0
  23. package/src/data/nebula-nouns.json +151 -0
  24. package/src/data/recipes.ts +571 -0
  25. package/src/data/syllables.json +1386 -780
  26. package/src/data/tiers.ts +45 -0
  27. package/src/derivation/crafting.ts +197 -0
  28. package/src/derivation/index.ts +28 -0
  29. package/src/derivation/location-size.ts +15 -0
  30. package/src/derivation/resources.ts +142 -0
  31. package/src/derivation/stats.ts +146 -0
  32. package/src/derivation/stratum.ts +124 -0
  33. package/src/entities/cargo-utils.ts +46 -9
  34. package/src/entities/container.ts +106 -0
  35. package/src/entities/entity-inventory.ts +13 -13
  36. package/src/entities/inventory-accessor.ts +42 -0
  37. package/src/entities/location.ts +7 -188
  38. package/src/entities/makers.ts +72 -0
  39. package/src/entities/player.ts +1 -273
  40. package/src/entities/ship-deploy.ts +263 -0
  41. package/src/entities/ship.ts +93 -453
  42. package/src/entities/warehouse.ts +34 -148
  43. package/src/errors.ts +4 -4
  44. package/src/index-module.ts +226 -42
  45. package/src/managers/actions.ts +111 -79
  46. package/src/managers/context.ts +0 -9
  47. package/src/managers/entities.ts +22 -5
  48. package/src/managers/index.ts +0 -1
  49. package/src/managers/locations.ts +15 -79
  50. package/src/market/items.ts +30 -0
  51. package/src/nft/description.ts +175 -0
  52. package/src/nft/deserializers.ts +81 -0
  53. package/src/nft/index.ts +2 -0
  54. package/src/resolution/resolve-item.ts +313 -0
  55. package/src/scheduling/accessor.ts +82 -0
  56. package/src/scheduling/projection.ts +158 -54
  57. package/src/scheduling/schedule.ts +24 -0
  58. package/src/shipload.ts +0 -5
  59. package/src/travel/travel.ts +93 -19
  60. package/src/types/capabilities.ts +71 -0
  61. package/src/types/entity-traits.ts +69 -0
  62. package/src/types/entity.ts +39 -0
  63. package/src/types/index.ts +3 -0
  64. package/src/types.ts +76 -33
  65. package/src/utils/hash.ts +1 -1
  66. package/src/utils/system.ts +148 -11
  67. package/src/data/goods.json +0 -23
  68. package/src/managers/trades.ts +0 -119
  69. package/src/market/goods.ts +0 -31
  70. package/src/market/market.ts +0 -209
  71. package/src/market/rolls.ts +0 -8
  72. package/src/trading/collect.ts +0 -939
  73. package/src/trading/deal.ts +0 -208
  74. package/src/trading/trade.ts +0 -203
@@ -1,208 +0,0 @@
1
- import {Int64, UInt16, UInt32, UInt64, UInt64Type} from '@wharfkit/antelope'
2
- import {Coordinates, GoodPrice, PRECISION, ShipLike} from '../types'
3
- import {Location} from '../entities/location'
4
- import {Ship} from '../entities/ship'
5
- import {
6
- distanceBetweenCoordinates,
7
- type EstimatedTravelTime,
8
- estimateTravelTime,
9
- hasEnergyForDistance,
10
- } from '../travel/travel'
11
- import {calculateProfitPerSecond, calculateTradeProfit, isProfitable} from './trade'
12
-
13
- /**
14
- * Trading deal interface representing a profitable trade opportunity
15
- */
16
- export interface Deal {
17
- /** Origin location */
18
- origin: Location
19
- /** Destination location */
20
- destination: Location
21
- /** Good to trade */
22
- good: GoodPrice
23
- /** Distance between origin and destination */
24
- distance: UInt64
25
- /** Available supply at origin */
26
- supply: UInt16
27
- /** Buy price at origin */
28
- buyPrice: UInt32
29
- /** Sell price at destination */
30
- sellPrice: UInt32
31
- /** Profit per unit */
32
- profitPerUnit: UInt32
33
- /** Maximum quantity that can be traded */
34
- maxQuantity: UInt32
35
- /** Total profit for max quantity */
36
- totalProfit: Int64
37
- /** Estimated travel time in seconds */
38
- travelTime: UInt32
39
- /** Detailed breakdown of travel time components */
40
- travelTimeBreakdown: EstimatedTravelTime
41
- /** Profit per second (floating point for UI display) */
42
- profitPerSecond: number
43
- /** Profit margin percentage (floating point for UI display) */
44
- marginPercent: number
45
- }
46
-
47
- /**
48
- * Options for finding deals
49
- */
50
- export interface FindDealsOptions {
51
- /** Maximum number of deals to return */
52
- maxDeals?: number
53
- /** Maximum search distance */
54
- maxDistance?: number
55
- /** Player's current balance (for affordability filtering) */
56
- playerBalance?: UInt64Type
57
- /** Minimum profit per second threshold */
58
- minProfitPerSecond?: number
59
- /** Minimum profit margin percentage */
60
- minMarginPercent?: number
61
- /** Override available cargo space (in mass units). If provided, uses this instead of calculating from ship's current cargo. */
62
- availableSpace?: number
63
- }
64
-
65
- /**
66
- * Calculate deals for a ship from a specific origin location
67
- */
68
- export async function findDealsForShip(
69
- ship: Ship,
70
- originLocation: Coordinates,
71
- getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
72
- getMarketPrices: (location: Coordinates) => Promise<GoodPrice[]>,
73
- options: FindDealsOptions = {}
74
- ): Promise<Deal[]> {
75
- const {
76
- maxDeals = 10,
77
- maxDistance = 20 * PRECISION,
78
- playerBalance,
79
- minProfitPerSecond = 0,
80
- minMarginPercent = 0,
81
- availableSpace,
82
- } = options
83
-
84
- const balance = playerBalance !== undefined ? UInt64.from(playerBalance) : undefined
85
-
86
- const origin = Location.from(originLocation)
87
- const originPrices = await getMarketPrices(originLocation)
88
- origin.setMarketPrices(originPrices)
89
-
90
- // Get nearby locations
91
- const nearbyLocations = await getNearbyLocations(originLocation, maxDistance)
92
-
93
- const deals: Deal[] = []
94
- const currentMass = ship.totalMass
95
- const shipCapacity = ship.maxCapacity
96
- const effectiveAvailableMass =
97
- availableSpace !== undefined
98
- ? UInt64.from(availableSpace)
99
- : currentMass.lt(shipCapacity)
100
- ? shipCapacity.subtracting(currentMass)
101
- : UInt64.zero
102
-
103
- // Check each nearby location
104
- for (const destLocation of nearbyLocations) {
105
- const destinationPrices = await getMarketPrices(destLocation.coordinates)
106
- destLocation.setMarketPrices(destinationPrices)
107
-
108
- const distance = distanceBetweenCoordinates(originLocation, destLocation.coordinates)
109
-
110
- // Compare prices for each good
111
- for (const originGood of originPrices) {
112
- const destGood = destinationPrices.find((g) => g.id.equals(originGood.id))
113
- if (!destGood) continue
114
-
115
- if (
116
- !isProfitable(originGood.price, destGood.price) ||
117
- originGood.supply.equals(UInt16.from(0))
118
- ) {
119
- continue
120
- }
121
-
122
- // Calculate max quantity based on balance, cargo space, and supply
123
- const canAfford =
124
- balance !== undefined
125
- ? balance.dividing(originGood.price)
126
- : UInt64.from(Number.MAX_SAFE_INTEGER)
127
- const canHaul = effectiveAvailableMass.dividing(originGood.good.mass)
128
- const supplyLimit = UInt64.from(originGood.supply)
129
-
130
- // Find minimum of canAfford, canHaul, supplyLimit
131
- let maxQuantity = canAfford
132
- if (canHaul.lt(maxQuantity)) maxQuantity = canHaul
133
- if (supplyLimit.lt(maxQuantity)) maxQuantity = supplyLimit
134
-
135
- if (maxQuantity.equals(UInt64.zero)) continue
136
-
137
- // Calculate travel time with cargo (includes recharge + load time)
138
- const cargoMass = originGood.good.mass.multiplying(maxQuantity)
139
- const availableSpaceUInt = UInt64.from(availableSpace)
140
- const baseMass =
141
- availableSpace !== undefined
142
- ? shipCapacity.gte(availableSpaceUInt)
143
- ? shipCapacity.subtracting(availableSpaceUInt)
144
- : UInt64.zero
145
- : currentMass
146
- const totalMass = baseMass.adding(cargoMass)
147
- const needsRecharge = !ship.hasEnergyFor(distance)
148
- const travelEstimate = estimateTravelTime(ship as ShipLike, totalMass, distance, {
149
- needsRecharge,
150
- loadMass: Number(cargoMass),
151
- })
152
-
153
- // Calculate profitability metrics using trade.ts functions
154
- const tradeCalc = calculateTradeProfit(maxQuantity, originGood.price, destGood.price)
155
- const profitPerUnit = destGood.price.subtracting(originGood.price)
156
- const profitPerSecond = calculateProfitPerSecond(tradeCalc.profit, travelEstimate.total)
157
-
158
- // Apply filters
159
- if (profitPerSecond < minProfitPerSecond) continue
160
- if (tradeCalc.margin < minMarginPercent) continue
161
-
162
- deals.push({
163
- origin,
164
- destination: destLocation,
165
- good: originGood,
166
- distance,
167
- supply: originGood.supply,
168
- buyPrice: originGood.price,
169
- sellPrice: destGood.price,
170
- profitPerUnit,
171
- maxQuantity: UInt32.from(maxQuantity),
172
- totalProfit: tradeCalc.profit,
173
- travelTime: travelEstimate.total,
174
- travelTimeBreakdown: travelEstimate,
175
- profitPerSecond,
176
- marginPercent: tradeCalc.margin,
177
- })
178
- }
179
- }
180
-
181
- // Sort by profit per second (descending)
182
- deals.sort((a, b) => b.profitPerSecond - a.profitPerSecond)
183
-
184
- return deals.slice(0, maxDeals)
185
- }
186
-
187
- /**
188
- * Find the single best deal for a ship from a specific origin location
189
- */
190
- export async function findBestDeal(
191
- ship: Ship,
192
- originLocation: Coordinates,
193
- getNearbyLocations: (origin: Coordinates, maxDistance: number) => Promise<Location[]>,
194
- getMarketPrices: (location: Coordinates) => Promise<GoodPrice[]>,
195
- options: FindDealsOptions = {}
196
- ): Promise<Deal | undefined> {
197
- const deals = await findDealsForShip(
198
- ship,
199
- originLocation,
200
- getNearbyLocations,
201
- getMarketPrices,
202
- {
203
- ...options,
204
- maxDeals: 1,
205
- }
206
- )
207
- return deals[0]
208
- }
@@ -1,203 +0,0 @@
1
- import {Int64, Int64Type, UInt32, UInt32Type, UInt64} from '@wharfkit/antelope'
2
- import {Ship} from '../entities/ship'
3
- import {Player} from '../entities/player'
4
- import {GoodPrice} from '../types'
5
-
6
- /**
7
- * Trade calculation result
8
- */
9
- export interface TradeCalculation {
10
- maxQuantity: number
11
- totalCost: number
12
- totalMass: UInt64
13
- affordableQuantity: number
14
- spaceForQuantity: number
15
- }
16
-
17
- /**
18
- * Calculate updated weighted average cargo cost after purchase.
19
- * Matches contract logic: (paid * owned + cost) / (owned + quantity)
20
- *
21
- * @param currentPaid - Current average cost per unit (from cargo.paid)
22
- * @param currentOwned - Current owned quantity
23
- * @param purchaseCost - Total cost of new purchase (price * quantity)
24
- * @param purchaseQuantity - Quantity being purchased
25
- * @returns New weighted average cost per unit
26
- *
27
- * @example
28
- * // Owned 10 units at 100 each, buying 5 more at 120 each
29
- * const newPaid = calculateUpdatedCargoCost(
30
- * UInt64.from(100),
31
- * UInt32.from(10),
32
- * UInt64.from(600),
33
- * UInt32.from(5)
34
- * )
35
- * // Result: (100*10 + 600) / (10+5) = 106.67 per unit
36
- */
37
- export function calculateUpdatedCargoCost(
38
- currentPaid: UInt64,
39
- currentOwned: UInt32,
40
- purchaseCost: UInt64,
41
- purchaseQuantity: UInt32
42
- ): UInt64 {
43
- // Match contract: (paid * owned + cost) / (owned + quantity)
44
- const numerator = currentPaid.multiplying(currentOwned).adding(purchaseCost)
45
- const denominator = UInt32.from(currentOwned).adding(purchaseQuantity)
46
- return numerator.dividing(denominator)
47
- }
48
-
49
- /**
50
- * Calculate the maximum quantity of a good a ship can buy
51
- * considering both space and player balance
52
- */
53
- export function calculateMaxTradeQuantity(
54
- ship: Ship,
55
- player: Player,
56
- goodPrice: GoodPrice
57
- ): TradeCalculation {
58
- const pricePerUnit = UInt32.from(goodPrice.price)
59
- const massPerUnit = UInt32.from(goodPrice.good.mass)
60
-
61
- const spaceForQuantity = ship.availableCapacity.dividing(massPerUnit)
62
- const affordableQuantity = player.balance.dividing(pricePerUnit)
63
- const maxQuantity = spaceForQuantity.lt(affordableQuantity)
64
- ? spaceForQuantity
65
- : affordableQuantity
66
-
67
- return {
68
- maxQuantity: Number(maxQuantity),
69
- totalCost: Number(maxQuantity.multiplying(pricePerUnit)),
70
- totalMass: UInt64.from(maxQuantity.multiplying(massPerUnit)),
71
- affordableQuantity: Number(affordableQuantity),
72
- spaceForQuantity: Number(spaceForQuantity),
73
- }
74
- }
75
-
76
- /**
77
- * Trade profit calculation result
78
- */
79
- export interface TradeProfitResult {
80
- revenue: UInt64
81
- cost: UInt64
82
- profit: Int64
83
- margin: number
84
- }
85
-
86
- /**
87
- * Calculate profit for a trade route
88
- */
89
- export function calculateTradeProfit(
90
- quantity: UInt32Type,
91
- buyPrice: UInt32Type,
92
- sellPrice: UInt32Type
93
- ): TradeProfitResult {
94
- const qty = UInt32.from(quantity)
95
- const buy = UInt32.from(buyPrice)
96
- const sell = UInt32.from(sellPrice)
97
-
98
- const cost = UInt64.from(qty).multiplying(buy)
99
- const revenue = UInt64.from(qty).multiplying(sell)
100
- const profit = Int64.from(revenue).subtracting(cost)
101
- const margin = cost.gt(UInt64.zero) ? (Number(profit) / Number(cost)) * 100 : 0
102
-
103
- return {revenue, cost, profit, margin}
104
- }
105
-
106
- /**
107
- * Calculate profit per unit of mass
108
- */
109
- export function calculateProfitPerMass(
110
- quantity: number,
111
- buyPrice: number,
112
- sellPrice: number,
113
- massPerUnit: number
114
- ): number {
115
- const profit = (sellPrice - buyPrice) * quantity
116
- const totalMass = quantity * massPerUnit
117
- return totalMass > 0 ? profit / totalMass : 0
118
- }
119
-
120
- /**
121
- * Calculate profit per second for a trade route
122
- */
123
- export function calculateProfitPerSecond(profit: Int64Type, travelTimeSeconds: UInt32Type): number {
124
- const t = UInt32.from(travelTimeSeconds)
125
- return t.gt(UInt32.zero) ? Number(profit) / Number(t) : 0
126
- }
127
-
128
- /**
129
- * Find the best good to trade between two locations
130
- */
131
- export function findBestGoodToTrade(
132
- ship: Ship,
133
- player: Player,
134
- originPrices: GoodPrice[],
135
- destPrices: GoodPrice[],
136
- travelTimeSeconds: UInt32Type
137
- ): {
138
- good: GoodPrice
139
- quantity: number
140
- profit: number
141
- profitPerSecond: number
142
- margin: number
143
- } | null {
144
- let bestTrade: {
145
- good: GoodPrice
146
- quantity: number
147
- profit: number
148
- profitPerSecond: number
149
- margin: number
150
- } | null = null
151
- let bestProfitPerSecond = 0
152
-
153
- for (const originPrice of originPrices) {
154
- const destPrice = destPrices.find((p) => p.id.equals(originPrice.id))
155
- if (!destPrice) continue
156
-
157
- if (!isProfitable(originPrice.price, destPrice.price)) continue
158
-
159
- const calc = calculateMaxTradeQuantity(ship, player, originPrice)
160
- if (calc.maxQuantity === 0) continue
161
-
162
- const tradeResult = calculateTradeProfit(
163
- calc.maxQuantity,
164
- originPrice.price,
165
- destPrice.price
166
- )
167
- const profitPerSecond = calculateProfitPerSecond(tradeResult.profit, travelTimeSeconds)
168
-
169
- if (profitPerSecond > bestProfitPerSecond) {
170
- bestProfitPerSecond = profitPerSecond
171
- bestTrade = {
172
- good: originPrice,
173
- quantity: calc.maxQuantity,
174
- profit: Number(tradeResult.profit),
175
- profitPerSecond,
176
- margin: tradeResult.margin,
177
- }
178
- }
179
- }
180
-
181
- return bestTrade
182
- }
183
-
184
- /**
185
- * Calculate break-even price for selling cargo
186
- */
187
- export function calculateBreakEvenPrice(costPaid: number, quantity: number): number {
188
- return quantity > 0 ? costPaid / quantity : 0
189
- }
190
-
191
- /**
192
- * Check if a trade is profitable
193
- */
194
- export function isProfitable(buyPrice: UInt32Type, sellPrice: UInt32Type): boolean {
195
- return UInt32.from(sellPrice).gt(UInt32.from(buyPrice))
196
- }
197
-
198
- /**
199
- * Calculate return on investment percentage
200
- */
201
- export function calculateROI(cost: number, profit: number): number {
202
- return cost > 0 ? (profit / cost) * 100 : 0
203
- }