It's bad to display a name based on a player order in the same place
as where you're letting people change that order and not have the
name change. So re-juggle the rematch process to allow the name to
be changed -- but don't change once the user has edited the name.
A rare stall resulted when the invitee on channel 2 responded
first. It would get assigned channel 1 and so the invitation on that
channel would get deleted. If it hadn't already reached the mqtt
server it would never be delivered. My fix is to use an invitation's
channel instead IFF its address matches the return address of the
incoming message. I'm not sure what happens if there's somehow a mix
of invited (via rematch) and invited-some-other-way players. None of
this matters for two-device games anyway.
When rematching, some users have a convention that e.g. lowest scoring
player in the "parent" game goes first. So allow that, providing the
choice on each rematch until a default has been chosen. Support
changing that default in a new prefs setting.
The place I chose to enforce the order was on the host as invitees are
registering and being assigned slots. But by then there's no longer
any connection to the game that was rematched, e.g. to use its
scores. So during the rematched game creation process I create and
store with the new game the necessary ordering information. For the
3-and-4 device case, it was also necessary to tweak the information
about other guests that the host sends guests (added during earlier
work on rematching.)
Two cases dealt with here. First, if my opponent deletes the game when
I have an un-ack'd message, I'll keep sending it forever. Fix is to
flip a bit in comms in response to a game_gone event so no more
sending will happen. (Better than emptying the queue, as it leaves
open the possibility of resurrecting the game with code changes
later.) Second, if there's a retained message from a dead game I'll
keep receiving it until it's replaced, and if the game's dead it never
will be. Fix is to add a new api endpoint noSuchGame() to the relay2
server and to call it on receiving a message for which I have no game
to deliver it to. The endpoint "unretains" the message so I won't get
it again unless it's resent.
My combining messages logic failed for ACKs, sending the queue but not
the ACK unless the ACK was in the queue. Appending it at send time is
fraught, so I am instead adding ACKs to the queue, but not persisting
them, so they only last long enough to be sent after they're
added. Seems to fix a common problem of games failing to get ACKs for
their final messages after they finish.