General Discussion (#1) - PlayerPosition packets (again) (#7) - Message List

PlayerPosition packets (again)

I found another bug having to do with player position packets (bounty was the particular culprit here). When a player dies, or switches to another frequency or ship, generally the bot will not get a new position packet for the player, leaving in the Player object the last recorded bit of data, probably from when the player was flying around happily while last alive.

Especially considering we are now disabling the system of routinely (periodically) updating position data, it seems like it might be a good idea to at least force a position update on receiving these particular events to ensure at least a modicum of reliability in the Player class. It won't be all that big a burden, and will ensure these critical updates.

I've fixed up one part of Player so that bounty will at least be recorded properly (not yet committed), but we still need to actually get the updated data. I can do this if everyone's generally in favor.

The other piece is, does anyone have a good UDP packet list? PlayerDeath is rather enigmatic… http://wiki.minegoboom.com/index.php/UDP_Game_Protocol is the best I can find. Here is the death packet:

0x06 Game 0x402CFC Player died

- 0 1 Type - 1 1 Death green - 2 2 Killer ident - 4 2 Killed ident - 6 2 Bounty - 8 2 ? Flags

"Bounty" I'm assuming means the amount to add to the bounty. Presently I think we just add it to the player's score… which makes sense because for some reason the method is called "getScore()" inside the PlayerDeath class. I'm not sure how score would actually be calculated here, and maybe it wouldn't be at all, just relying on a ScoreUpdate packet to be sent later on. It's all very enigmatic. I'm pretty sure just adding the bounty gained to score isn't doing the job, though. :P

  • Message #7

    Nice find, I never thought of the position updating that way, I never really noticed it in a significant fashion, but then again, what you're doing with purepubbot is more demanding. I'm not sure what my whistle level on these matters are but I'd say it's for the better of the core.

    PS: What modules aside from purepubbot can we see this effect? You've peaked my curiosity. :p

  • Message #8

    dugwyler, see the javadoc comments in PlayerDeath.java (http://www.twcore.org/doc/twcore/core/events/PlayerDeath.html), they are quite complete.

    I don't really get what TWCore is doing wrong though. If you need to watch the players after they die you need to have to bot cycle through the players (just like Mervbot did when it needed more player information).

    Instead you want to have TWCore force a position update after the player died? Doesn't this defeat purpose of not cycling the players because it's so much overhead for bots not using it?

    P.S. I asked on the MGB forums if someone knows a better UDP Game protocol document, maybe there is still a better one somewhere.

    • Message #9

      Well, that's the thing — they aren't complete because they aren't exactly accurate. I wouldn't be asking otherwise. D1st0rt wrote most of the documentation for the events, and I wrote most of the documentation for the rest of the core (took ages), and both of us are human and prone to error — they are anythbing but "quite complete." For example, it says "The bounty, along with the other kill score modifiers in settings are added to the players kill points", yet this never happens using PlayerDeath itself. It might happen on the server, or it might happen on a normal client, but TWCore actually just takes the "bounty" and adds it to the player's score (pretty sure this is not correct). One main reason I'm posting here is because one can't tell whether this means the bounty the player earned by the kill, or the full bounty of the person who was killed. It's probably the former, but then it's hard to ensure that.

      As for position updating being a huge amount of overhead, that may be just a myth after all. The spectate request packet, 0x08 C2S, is 3 bytes long (plus small header). When we turn the position update feature from sending this absolutely tiny packet every 5 seconds, to not sending it at all, I don't think we're taking a huge load off of TWCore at all. In the process we lose some reliability. The bot will, like any client, also receive position updates for anyone in radar range no matter what we do — the only difference is how quickly we change its position in order to get a larger range of packets.

      In order to ensure things like bounty and other position packet based information are correct, I don't think it's too bad a proposal to send those 3 or so bytes each time a person changes frequency or ship, or perhaps even when they die. And evaluating the overall load addition of simply sending a new spectate packet every 5 seconds by default — even every second is really not much at all — vs. the default unreliability of TWCore, requiring a fairly complex understanding of how it works just to get it to function properly … well, I would side more safely on the side of sending the couple bytes now and again in order to ensure slightly more reliable info.

      • Message #10

        I find it hard to understand we must do this (spectate a player when he dies/changes ships/etc) to get extra information of the player for more reliability with bots who need this while the normal client doesn't do this (afaik) ?

        The problems you mention with TWCore are:

        • Position of players
        • Bounty of players
        • Score of players

        Continuum doesn't have any problems with the score so TWCore shouldn't aswell. As for the Bounty and the Score, yes, the bot needs to cycle the players to get accurate information which is already available to any bots.

        I've also seen TWCore's implementation of the DeathPacket which I also found incorrect. However, I think it's better to fix it properly instead of making a hack to work around it. I'm sure Mervbot has the correct implementation.

        So I still don't really see the need of getting extra position info from a player when he dies, changes ship or changes frequency. Instead we should just make TWCore implement the protocol correctly.

        P.S. D1st0rt provides a nice UDP Game Protocol at http://d1st0rt.sscentral.com/packets.html .

        • Message #11

          Thanks for the packet list — that was the one I remembered, and could never find again. It's actually cleared up the issue of the PlayerDeath packet, which according to it is handled correctly: we merely add the points to kill points, and bounty is (strangely) untouched after killing another player. Strange that it's called bounty, and also strange in that you would think bounty would get added at this point.

          The difference between a bot and a player in respect to position packets is pretty large. Our bots (for the most part) do not play Subspace — they spectate, and in a way need to keep an eye on all players. A player, on the other hand, plays Subspace. They move around the screen, operate from a specific position, and so only need detailed information about the players on or near their radar … the ones with which they may interact.

          In a sense bots interact with everyone, need to be somewhat aware of everyone at once, so they must switch who they are spectating to receive the correct information about the player. To emphasize why changing position when a player dies or changes ship/freq, take the example of bounty. The bot is spectating player A, and another, player B, goes zooming across and sends many position packets, which the bot uses to update its info on B. B later goes out of radar range of A, and starts making kills, moving around, etc. We receive any death packets that result from kills made by B, but we do not receive B's new position packets, so we don't update B's bounty, score or position. If anyone tries to get the location of B they get the last position of when the player left A's radar. Now B dies, and is on a completely different part of the map. But death does not cause bounty or position to be reset — because what would we reset it to? We don't know what default bounty is, or where they might warp to. The bot still thinks that B has the bounty they had when they went off of A's radar.

          If we just quickly spectated them and forced a position packet, we'd have this information, and that's all I'm suggesting — that we might send the 3 bytes in order that we might have a more reliable bot core by default, rather than requiring special setup. Or, perhaps having some sort of method that would require implementation by bots extending SubspaceBot to set this particular feature. Consider everything that becomes unreliable without at least a modicum of spectate changing: direction, position, velocity, bounty, energy, all weapons info, status of stealth, cloak, xradar, antiwarp, whether the player is in safe, as well as number of reps, warps, bursts, etc.

          This isn't altogether awful. The only problem is that I think most coders assume that this information is provided safely by how we have the Player class set up. I saw someone trying to use a Player's hasShields() method to create antispawn protection, for example, and I do use bounty in PurePub. It's not all that cut and dry here; I do have reservations against it myself, but I would prefer some sort of semi-reliability rather than it appearing randomly reliable to new coders who haven't delved that far into TWCore.

          • Message #12

            I agree with most of your post, however I don't see why the player cycling we already have isn't sufficient?
            If novice coders don't know about it too well why don't modify the javadoc to point it out and fix the bots depending on it? (Adding one call to BotAction.startReliablePositionUpdating() is enough)

            If you really think it should be necessary, at least make it optional for each bot or something so bots that really don't need it don't "suffer" from it (even though it isn't that much like you said).

            • Message #13

              After the forums.tw.org postings I think we have a decent solution at this point. Switching which player the bot is spectating on death/freqchange/shipchange is probably not necessary. However, to give a modicum of reliability, it seems like we should:

              - Set Player bounty to 0 after death/freqchange/shipchange. This will successfully bypass the Player handling of short position packets:

              if( m_bounty < message.getBounty() )

              m_bounty = message.getBounty();

              (This is done because bounty in short position packets is only one byte, giving a limit of 255 — if bounty goes over 255 and the bot updated it based on a short packet, it will be incorrect. I had a different kind of fix for this, but bounty to 0 should work fine.)

              - Re-enable regular position changing inside Arena, in light of the recent discovery of the minuscule bandwidth it costs, as opposed to the level of reliability it provides by default to new coders. I would recommend a value of 1 second. This would still allow experienced coders who wish to save a very small amount of net traffic (3 bytes every second) to turn this feature off, while not causing frustration for inexperienced coders who would not be able to figure out why most of the information in Player is always incorrect. I had to find this one out myself the hard way, after a few hours of experimentation.

              - Update JavaDocs accordingly, especially in Player, informing coders that the data may still not be up to date and that using the appropriate BotAction method will ensure it is more reliable.