fa icon indicating copy to clipboard operation
fa copied to clipboard

Refactor the syncing of regen of units

Open Garanas opened this issue 3 years ago • 0 comments

Description

This issue is an introduction to what needs to happen in https://github.com/FAForever/fa/pull/4135, if you do not intend to do https://github.com/FAForever/fa/issues/4135 too then please leave this issue for someone who does

The regeneration rate can be adjusted in the simulation. This is particularly noticeable when a units gains a level via experience. This is synced to the UI via the sync table. This includes some additional baggage, including:

    1. A complicated (and expensive) indexing approach for syncing the data with the UI
    1. A lot of table and field allocations with regard to the UnitData table

For 1, note that this is the meta table of self.Sync as set here. As a consequence, all the index calls run via these functions.

Course of action

We'll take a similar approach to https://github.com/FAForever/fa/pull/3916, where we use the recently found Unit:GetStat and Unit:SetStat functions. These allow for direct communication with the UI, without using the sync. As a result we'll need to make the following changes:

    1. Instead of storing the intermediate status in self.Sync, we store it in separate values that we keep track of in self
    1. We initialize all required values during OnCreate, unless the unit does not support keeping track of experience. This includes the amount of experience and the amount required for the next level
    1. We initialize the stats by calling unit:GetStat during OnCreate
    1. We update all functions related to adjusting regen rate, including:
    • Unit:SetRegen
    1. We update the UI to use UserUnit:GetStat when we want to view the current experience values

Note that 1 and 2 should closely resemble how it works in https://github.com/FAForever/fa/pull/3916, and that 3 is required to prevent an engine bug. We need to try and get the stat (as that prepares the statistic in the engine) before we can set it (which crashes if it tries to read a value that does not exist).

Test plan

The functionality of the regen rate should remain the same. Technically you should be able to play a replay without desyncing, as the computation is not adjusted (just the information we send to the UI is). In practice this is impossible due to floating point inaccuracy, however.

Sanity checklist:

  • At no point can the game do a Unit:SetStat on a value that has not been prepared using Unit:GetStat

Learning goals

Tackle small refactoring that spans across the sim to the UI.

Garanas avatar Aug 17 '22 18:08 Garanas