armoha / euddraft

System for pluginizing eudplib codes.
Other
29 stars 4 forks source link

CUnit handle #93

Open armoha opened 1 year ago

armoha commented 1 year ago

AlphaID is CUnit handle StarCraft uses on hotkeyed unit, unit in transport, command packet etc. CUnit is 1700-sized generational arena (pool).

alphaID = (uniquenessIdentifier << 11) | index (See: http://farty1billion.dyndns.org/euddb/?pg=entry&id=557 )

Handle is similar to pointer but has following benefits:

By each handle and CUnit sharing special field (CUnit::uniquenessIdentifier = targetOrderSpecial on +0xA5, sized u8), SC can ensure handle is valid if these fields are same on both entries, and protects players from e.g. clicking unexpected unit by hotkey, the situations where handle has valid index but its payload has been replaced.

We can come up with eud-friendly handle, to ensure if handle is valid without needing to eagerly check death of CUnit.

One might think following handle layout:

cunit_handle = EPD(CUnit + 0xA5) | (uniquenessIdentifier << 18) ('Bitwise or' of all CUnit entries = 0x3FFFD)

To check validity, this compact layout needs >> 10. Consider FastVar storing handle:

  1. Set bitmask to (0xFF << 18), substitute to value slot of condition checking validity (2T 4A if modifier is fixed to SetTo)
  2. In-place right-shift on the value slot while set bitmask to 0x3FFFF and substitute to player slot of the condition (8A + 2T 4A, no need to set SetTo again)
  3. Run the conditional branch (1T0A or 1~2T 2A)

We can also think FatFastVar, storing 2 actions in single trigger:

RawTrigger(
    actions=[
        SetMemory(?, SetTo, EPD(CUnit + 0xA5)),
        SetMemory(?, SetTo, uniquenessIdentifier << 8),
    ]
)

According to https://github.com/armoha/euddraft/discussions/60 , 0C 2A triggers can be packed into 104 bytes.

Checking validity:

  1. Substitute player slot with EPD(CUnit + 0xA5) and value slot with uniquenessIdentifier << 8 (2T 5A)
  2. Run conditional branch (1T 0A or 1~2T 2A)
armoha commented 1 year ago

We can experimentally introduce the concept on UnitGroup and EUDLoopNewUnit.

EUDLoopNewUnit : store and compare uniquenessIdentifier for each units, instead of overwriting it.

UnitGroup.cploop : No need to call it on every frame.