Zannick / logic-graph

Tools for video game logic representation and analysis, particularly routing and beatability checks for speedruns and randomizers.
MIT License
3 stars 0 forks source link

Update observations after modifications #166

Closed Zannick closed 1 month ago

Zannick commented 1 month ago

Since we look at observations in reverse order of step execution, we may see the following things:

  1. Step N costs 100 energy.
  2. Step N-1 costs 100 energy.
  3. At step N-2, we do an action that refills our energy.
  4. At step N-3, we do something that costs 50 energy.

The observations we should have are:

  1. Immediately prior to step N, we have at least 100 energy.
  2. Immediately prior to step N-1, we have at least 200 energy.
  3. Immediately prior to step N-2, we don't have any need of energy.
  4. Immediately prior to step N-3, we have at least 50 energy.

This means that within actions and prices, modifications must apply to observations:

What we have right now:

I believe this may mean we have this:

  1. At step N+1, we have no observation on energy.
  2. At step N, we update our observations based on the difference between the states before and after step N, which spent 100 energy. We still have no observation. Then we observe the requirements to perform step N, and observe that we have to have at least 100 energy.
  3. At step N-1, we update our observations... step N-1 spent 100 energy, so we observe we need at least 200 energy. Then we observe our requirements of having at least 100 energy, which is already fulfilled by our observation of at least 200 energy.
  4. At step N-2, we update our observations... step N-2 set our energy to 300, which adds energy based on our previous usage. If we were at 250 energy, then this would appear the same as picking up a 50-energy refill. Our observation says we need at least 150 energy. Then we observe the Set which does nothing.
  5. At step N-3, we update our observations... step N-3 spent 50 energy, so we observe we need at least 200 energy. Then we observe our requirements...

We may need to add a observation debug output to see for sure. Even if we modify in Set, it's still kind of convoluted that affordability observation is calculated one way for the first observation only (step N) and another way for every other one (step N-1 etc state diff updates).

Zannick commented 1 month ago

That last change fixed another issue we hadn't noticed at all: with an Option, insert replaces the stored value with the one provided, so every observation bitflag was actually only one flag ever.

Zannick commented 1 month ago

This fix actually has a large negative impact on performance... sometimes... which I take to mean there's more contention on updating the trie or the solution collector. The program is still quite good otherwise: I had a peak of 28k/s throughput for 100000-200000, but when it has solutions to process it gets much slower, down into the hundreds per 100k step.

I imagine we should treat collecting singleton items like Set, to reduce the number of flags in earlier steps.

Zannick commented 1 month ago

Actually, it may be that we're running out of states to process... I see threads blocked in rayon waiting for work and not for a lock in axiom_verge2. That probably means we haven't put enough in the queue and what's actually there is being held by threads who grab several at a time to work on. So this is technically okay although I would like to speed up part of the initial solution processing (the mutations for example could be immediately put in instead of waiting for all of them... if it were easier to write a generator function).

Zannick commented 1 month ago

I believe this is working, although there are still not-quite-ideal quirks showing up in the best solution that will be investigated in another issue.