- a card lands one tick after its command fires, since the client
hashes after LogicTime::increaseTick, not before
- answer RequestSectorState immediately except in the two ticks after
a firing tick, where a full update would teleport the client past
the command it just queued - the old blanket refusal left every
card the player tapped silently deleted while it held
- carry both pending commands and queued deploys in the same delivery
ledger so the quiet window covers what the player actually paid for
- add the regression tests for the birth tick and the deferred answer
two separate breakages behind "no achievement, no level up", both
checked against the client in IDA.
level up: LogicClientAvatar::xpGainHelper adds a gain to exp_points -
which is progress WITHIN the level, not a running total - then rolls it
into levels: while exp_points >= ExpToNextLevel(level) it subtracts that
threshold and increments the level, calling levelUp for the deck slots
and diamond reward. our add_exp only grew exp_points, so the bar filled
past full and the level never moved. it now rolls over the same way,
against the exp_levels table.
achievement: the client only offers a claim when progress >= ActionCount
(LogicClientAvatar::isAchievementCompleted reads commodity 2), and the
claim command re-reads that same commodity - and build_avatar populated
none of it, so every claim came back "not completed". build_avatar now
serves real progress: findcard from the count of distinct cards owned,
reacharena from the arena reached. donate / jointeam / watchtv need
social features we do not have and stay at zero.
tests cover both and fail without the fixes: 25 exp reaches level 2 with
5 carried, and a completed findcard tier claims once, grants exp, and is
rejected the second time.