Trade failure error reasoncode 32

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Scripting / Modding Moderators, Moderators for English X Forum

DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Trade failure error reasoncode 32

Post by DeadAirRT »

I've been trying to track down an error that started with 7.0 in modded set up and need help with an error code that doesn't exist anywhere in the files.

Traders are docking at a station to buy, failing the trade, finding the trade again, and repeating.
The portion of code giving the error is after several checks so the following are not possible reasons:

Code: Select all

ERR_TRADEDEAL_NONEXISTENT
ERR_TRADEPARTNER_NOT_OPERATIONAL
ERR_NO_TRANSPORT_UNITS
TRADEPARTNER_BLACKLISTED
ERR_NOTHING_TO_SELL
ERR_TRADEOFFER_INVALID
ERR_TARGET_INVALID
ERR_NO_CARGO_SPACE
ERR_BUYER_NO_MONEY
ERR_SELLER_NO_CARGO
ERR_CANNOT_DOCK
ERR_TRADEOFFER_INVALID ($tradeoffer.available)
and it is reaching:

Code: Select all

<execute_trade tradeoffer="$tradedeal" tradepartner="this.ship" amount="$amount" result="$traderesult" custom="true" comment="Deal with fixed price" />
When it is a player owned ship not piloted by the player:

Code: Select all

[=ERROR=] 16783.73 Error in AI script order.trade.perform on entity 0xe074: TradeID 32494: trade 158 Hull Parts between Tethys (SENTINEL-SHORT) and PAR Hull Part Factory failed with reasoncode 32 (0x20 - 0000000000000000000000000100000b)!
* Action: <execute_trade>, line 429
When the player themselves is piloting the ship:

Code: Select all

[Scripts] 16860.12 *** aicontext<order.trade.perform,0x14e21>: 16860.124 'Tethys (SENTINEL-SHORT)'(OXU-761, job: '') TRADE RUN FAILED! Error: ERR_EXECUTE_FAIL
[Scripts] 16860.12 *** aicontext<player.interaction.tradefailed,0x14e21>: Trade (selloffer) failure for player trade! trade not available...
Does anyone know what reasoncode 32 is for?
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

More background info for the bug that may be applicable:

The prices of the two wares I've encountered the bug on are

Code: Select all

Graphene: Min="120" Average="240" Max="520"
Hull Parts: Min="108" Average="216" Max="468"
The min price is exactly 50% of the average which may be applicable to the bug for how discounts are being done
The first report of the bug was from a player where the UI was showing the price for hullparts as: 54Cr
The second report of the bug (and verified in the save) the traders were reserving a trade for graphene for: 60Cr

Both are exactly 50% of the minimum price
Both prices are actually impossible to reach with the discounts.

Discount map from notifications.xml for MAX relation bonus is: 25% (both players only had a 15% discount)
The highest unlockable discount for graphene is: 14% (which was not active in save)
The highest unlockable discount for hull parts (generic discount) is: 10%
The hacking discount is: 10% (which neither player had)

This means the maximum discount for hullparts is 45% and graphene is 49%
The minimum price possible for graphene should be 61.2Cr which could be rounded to 61Cr.
The minimum price possible for hull parts should be 59.4Cr which could be rounded to 59Cr.
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

Welp, pricing formula makes zero sense to me.

A station selling wares for minprice (which is no longer the actual minprice in game, since it goes below minprice)

Hull Parts: Min="108" Average="216" Max="468"
High supply (PriceModifier): -50%
Prized Investor (Discount): -25%

For some reason, the price is being calculated as:

Code: Select all

AveragePrice * (1.0 - (PriceModifier + Discount))

Code: Select all

216 * (1.0 - (0.5 + 0.25)) = 54
Which already seems off, as the expected math would be something like:

Code: Select all

AveragePrice * (1.0 - PriceModifier) * (1.0 - Discount)

Code: Select all

216 * (1.0 - 0.5) * (1.0 - 0.25) = 81
But even then, why is minprice not minprice? Is that potentially causing the error since the price being requested by player ships is lower than actual minprice (which non-player owned are respecting)?

This is what I would expect the actual formula to look like (note I'm not familiar with C at all so this may be wrong syntax):

Code: Select all

Math.Max(AveragePrice * (1.0 - PriceModifier) * (1.0 - Discount),MinPrice)
Vectorial1024
Posts: 304
Joined: Mon, 30. Jul 18, 04:16
x4

Re: Trade failure error reasoncode 32

Post by Vectorial1024 »

I think the discounts are kinda "working as intended". If you look at the in-game trade UI, it e.g. can look like this:

Code: Select all

Ware            |      | ???
High Supply     | -30% | ???
Prized Investor | -20% | ???
----------------+------+----
                | -50% | ???
Clearly, the discounts are additive. This is the same way discounts are calculated in X Rebirth, so I do not think there is anything new in X4 in this regard.

One very interesting observation back in XR is that, in DeVries, if you get +30 rep with Republic of Cantera (RoC), and decides to buy energy cells from the Solar Energistics (owned by RoC), the high supply of energy cells (minprice 2cr, avgprice 5cr; i.e. -60%) [1] will stack with the rep effect (-25%) [2] to create a -85% sell offer of energy cells, which sells them at 0.75cr each. Combined with smalltalk rewards (-15%) [3] it has a chance to reach 0 (-100%), although I think the game will force a guaranteed price of at least 0.01cr. And at this point, the game will wrongly think you are doing self-to-self trade and will refuse to print the expected profits from trades even if you are trying to trade with an NPC station with e.g. +5% "small shortage".

This indicates the game internal system somehow rounds down the value to do things.

Ref:

[1] Roguey X Rebirth: Energy Cells https://roguey.co.uk/xrebirth/wares/ware-31/

[2] X Rebirth faction rep effects https://wiki.egosoft.com:1337/X%20Rebir ... 20effects/

[3] X Rebirth smalltalk rewards https://wiki.egosoft.com:1337/X%20Rebir ... purchases/
The future awaits.

X4 Foundations mods:
Civilian Fleets: (Obsolete for X4 7.0+) Managing your civilian ships has never been easier.
Station Logistics: Managing your station networks has never been easier.
Market Discovery: Find Black Market Traders; also rerolls them.
Logistics Optimization: Improve your station traders; improve your trade stations!
Vectorial1024
Posts: 304
Joined: Mon, 30. Jul 18, 04:16
x4

Re: Trade failure error reasoncode 32

Post by Vectorial1024 »

The forum ate my reply because I spent too much time typing it, so I will just split my text into several replies to avoid the session expiry.

I think 7.0 has touched trade discounts in some ways:

Ref https://steamcommunity.com/app/392160/d ... 209819239/
  • Fixed trade discounts not being taken into account when traders are looking for trades.
And we have some reddit complaint posts:
The future awaits.

X4 Foundations mods:
Civilian Fleets: (Obsolete for X4 7.0+) Managing your civilian ships has never been easier.
Station Logistics: Managing your station networks has never been easier.
Market Discovery: Find Black Market Traders; also rerolls them.
Logistics Optimization: Improve your station traders; improve your trade stations!
Vectorial1024
Posts: 304
Joined: Mon, 30. Jul 18, 04:16
x4

Re: Trade failure error reasoncode 32

Post by Vectorial1024 »

To trade wares, station managers first look at the situation (eg stock level, past trades, production run/stall, etc) to decide the base price of wares; this base price can shift, but must be within the minprice and maxprice defined in each wares' definition, and this is the minprice and maxprice of the script property.

Then, this base price passes through the discount/commission system and is confirmed as the unit price. This actual tradeable price range is different from the minprice/maxprice range.

In X Rebirth, we can see the unit price down to the Credit-cent (0.01Cr), and precision is preserved until the very final step of calculating the total price (round down). But in X4, due to GUI magic, every displayed unit price is an int (this guarantees the total must be also an int), and this seemingly may cause problems when the displayed unit price is out of range from the internally calculated/allowed price range. (I read this somewhere from reddit)

I can then guess this is not actually a round down, but a C-style int cast from float, because it is just too convenient and also fast.
The future awaits.

X4 Foundations mods:
Civilian Fleets: (Obsolete for X4 7.0+) Managing your civilian ships has never been easier.
Station Logistics: Managing your station networks has never been easier.
Market Discovery: Find Black Market Traders; also rerolls them.
Logistics Optimization: Improve your station traders; improve your trade stations!
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

Vectorial1024 wrote: Thu, 27. Jun 24, 21:58 To trade wares, station managers first look at the situation (eg stock level, past trades, production run/stall, etc) to decide the base price of wares; this base price can shift, but must be within the minprice and maxprice defined in each wares' definition, and this is the minprice and maxprice of the script property.

Then, this base price passes through the discount/commission system and is confirmed as the unit price. This actual tradeable price range is different from the minprice/maxprice range.

In X Rebirth, we can see the unit price down to the Credit-cent (0.01Cr), and precision is preserved until the very final step of calculating the total price (round down). But in X4, due to GUI magic, every displayed unit price is an int (this guarantees the total must be also an int), and this seemingly may cause problems when the displayed unit price is out of range from the internally calculated/allowed price range. (I read this somewhere from reddit)

I can then guess this is not actually a round down, but a C-style int cast from float, because it is just too convenient and also fast.
I did not play XR but that is not exactly inspiring confidence that the discount system has been done this way since then.

The way the math is done, I would not say that it is calculating the price then applying the discounts. That would imply that it is calculating the price based on storage (minprice) THEN multiplying it by the discounts. This would result in a different number since the Supply modifier would be multiplicative instead of additive. Prior to 7.0 there wasn't even any protection from negative priced trades as I already had to change my values to compensate for that bug.

This post is mostly about whatever code they changed/added in the function execute_trade that is causing trades to fail that did not exist in 6.2. If they even documented that trades below a certain threshold percentage of average price are blocked / fail, it would be better than now. Right now, I have something that should actually be working better than in 6.2 failing for code that is not seen and no breaking changes / any guidelines have been documented. I get that the devs are working hard and very busy with the DLC/7.0 coming out, but this is just another example of where giving the modders any documentation on a formula used in the background would save tons of headaches.
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

Welp, still no luck finding anything that could be contributing to this problem in any visible scripts/code. For now I have disabled faction relation discounts to minimize the issue.
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

So, thanks to some insight from devs on reasoncode 32:

The problem was a rounding accuracy loss that did not account for discounts affecting the unitprice in order.trade.perform. It checked if the container had the appropriate amount of Cr but due to recent changes that made discounts visible to traders, it was unable to catch when the trader was short by less than 1Cr.

Code is in order.trade.perform line 420

Code: Select all

<do_if value="$tradedeal.seller.exists and (not $tradedeal.buyfree) and (($tradedeal.unitprice * $amount)/1Cr gt this.container.money/1Cr)">
This is the last check in order.trade.perform before execute_trade is reached and is supposed to reduce the amount when the ship does not have enough money for the trade.

It can be fixed by removing the forced conversion, since $tradedeal.unitprice and this.container.money are both in cents(ct).

This fix will potentially result in a lot of trades being reduced by 1 amount, so I instead added logic to transfer 1Cr to the ship from the owners account. I believe both solutions are better than trades failing (that can often repeat unless RNG is introduced like in vanilla autotrader since the trade will likely be found again after failure)

Just thought I'd post my findings in case anyone runs into this issue in the future.
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

Welp, got a bit ahead of myself.

So the price rounding issue was present, but it most likely has some background handling in <execute_trade> that rounds the price down to an interger so it isn't the reason for failures still.

I am however still getting:

Code: Select all

reasoncode 32 (0x20 - 0000000000000000000000000100000b)!
* Action: <execute_trade>, line 429
I've checked basically every possible data available in the script properties of the trade deal, the trader partners, and am running into a dead end. Here is a debug output just prior to a failing <execute_trade> and the error itself:

Code: Select all

TradeInfo -- $tradedeal.buyer: null(null) -- $tradedeal.seller: CAL Hull Part Factory(PLS-073) -- $tradedeal.ware: Hull Parts
 $tradedeal.amount: 1640 -- $tradedeal.unitprice(ct): 5400 -- OriginalCost(ct)($tradedeal.amount * $tradedeal.unitprice): 8856000
 $amount: 1640 -- $tradedeal.unitprice(ct): 5400 -- Cost(ct)($amount * $tradedeal.unitprice): 8856000
 this.container.money(ct): 8856000 -- @$tradedeal.seller.money(ct): 75681298296832
 $buyer: TM-AMR-MERC02(CRF-266)(0x27c6d) -- $seller: CAL Hull Part Factory(PLS-073)(0x7cbae) -- buyfree: 0 -- wareexchange: 0 -- $internalorder: 0
 $tradedeal.seller.cargo.{$tradedeal.ware}.count: 134651 -- this.container.cargo.{$tradedeal.ware}.free: 1640

Code: Select all

Error in AI script order.trade.perform on entity 0x27c76: TradeID 37295: trade 1640 Hull Parts between TM-AMR-MERC02 and CAL Hull Part Factory failed with reasoncode 32 (0x20 - 0000000000000000000000000100000b)!
Vectorial1024
Posts: 304
Joined: Mon, 30. Jul 18, 04:16
x4

Re: Trade failure error reasoncode 32

Post by Vectorial1024 »

Indeed, I saw something on Reddit that talked about off-by-one rounding problems, but it was buried somewhere in the comment section.

It seems the trading system in X4 Foundations work exactly like X Rebirth: unit prices are shown in cents (my previous statement about "shown in integers" was inaccurate; the map view UI indeed showed as int, but the trade details still showed as float), and then after everything (discounts etc), the total gets processed into an integer for nice printing. The unknown remaining is whether it is a round down (float -> int cast? truncate?) or a round up.
The future awaits.

X4 Foundations mods:
Civilian Fleets: (Obsolete for X4 7.0+) Managing your civilian ships has never been easier.
Station Logistics: Managing your station networks has never been easier.
Market Discovery: Find Black Market Traders; also rerolls them.
Logistics Optimization: Improve your station traders; improve your trade stations!
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

So the problem is eliminated at the exact same station by removing the reputation discounts. The only conclusion that I can come to is that it's code that's not accessible to modders that is having an issue when the price has a large variance between minimum price and average price.
User avatar
BurnIt!
EGOSOFT
EGOSOFT
Posts: 5116
Joined: Wed, 6. Nov 02, 20:31
x4

Re: Trade failure error reasoncode 32

Post by BurnIt! »

We have identified an issue that could occur with a high price range and large discounts resulting in certain calculations even ending up with negative prices which could explain trade failures of all kinds.
This doesn't usually happen in vanilla games as the maximum range and discounts typically avoid that edge case but it was still worth fixing.
Please test your scenario with the next 7.10 beta build (not out yet at the time of this post) and let me know if it fixes the issue or there's still something wrong.
BurnIt!
In der Ruhe liegt die Kraft. / In peace lies strength.
DeadAirRT
Posts: 1124
Joined: Fri, 25. Jan 19, 03:26
x4

Re: Trade failure error reasoncode 32

Post by DeadAirRT »

BurnIt! wrote: Tue, 9. Jul 24, 11:37 We have identified an issue that could occur with a high price range and large discounts resulting in certain calculations even ending up with negative prices which could explain trade failures of all kinds.
This doesn't usually happen in vanilla games as the maximum range and discounts typically avoid that edge case but it was still worth fixing.
Please test your scenario with the next 7.10 beta build (not out yet at the time of this post) and let me know if it fixes the issue or there's still something wrong.
Thank you very much for looking into it and spending the time to fix it. I appreciate it and am looking forward to testing the next beta build :D

Return to “X4: Foundations - Scripts and Modding”