Zezombye / overpy

High-level language for the Overwatch Workshop with support for compilation and decompilation.
GNU General Public License v3.0
175 stars 25 forks source link

Non-deterministic Augmented Assignment gets miscompiled. #348

Closed Artikae closed 5 months ago

Artikae commented 8 months ago

When compiling a += n, OverPy seems to convert it to the form: a = a + n. For most cases this is fine. However, if a results in a different variable each time it is evaluated, this transformation is incorrect.

For example, this workshop action adds 5 to a random player's A variable.

Random Value In Array(All Players(All Teams)).A += 5;

It gets decompiled to this:

random.choice(getAllPlayers()).A += 5

Re-compiling the above produces ##this:

Set Player Variable(Random Value In Array(All Players(All Teams)), A, Add((Random Value In Array(All Players(All Teams))).A, 5));

Now, the action picks a random player, and sets their A to another random player's A, plus 5.

CactusPuppy commented 8 months ago

The solution here would be to compile this example to use Modify Player Variable. Some discussion is happening internally with contributors to implement this.

netux commented 8 months ago

Let's put them in the known:

  1. +=, -=, etc. gets Ast'd into Set Player Variable because then we can do some optimizations to get back Modify Player Variable
  2. However, these optimizations have a limit for functions like random.choice
  3. The solution we are thinking of is to just check if there is any random.xyz function in use, and Ast the operation to Modify Player Variable, skipping any further optimizations.
CactusPuppy commented 5 months ago

Regressed with version 7.0.1