Designing a < operator for a GUID

Started by
7 comments, last by Deflinek 9 years, 2 months ago
Hi.

I wanted to hold my player class in a STD::map using the player ID.
PlayerId is a class rapper around a GUID
And to add this class as the key to STD::map I need a <operator.

Would I be better of doing it as a string compare with GUID strings.

Then I looked up the == operator for GUID and thats using memcmp . I take it that one should use memcmp(guid1, guid2) is less then zero for the < operator

Does it compare left is less or right is less.
Advertisement

The "memcmp(guid1, guid2) is less than zero" relation defines a strict weak ordering and is thus suitable for use in an std::map if and only if your GUIDs have fixed, constant size. Which is almost certainly the case.


Does it compare left is less or right is less.

It doesn't really matter, any strict weak ordering will do. If you define it as "memcmp(&guid1, &guid2, sizeof(GUID)) < 0" then it compares guid1 < guid2 where < is your comparator to the map function. So if it evaluates to true, guid1 is defined to be "less" than guid2.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

The "memcmp(guid1, guid2) is less than zero" relation defines a strict weak ordering and is thus suitable for use in an std::map if and only if your GUIDs have fixed, constant size. Which is almost certainly the case.


Note that these results depend on how you store the GUID. If you're storing GUIDs a word at a time then a simple memcmp will sort the GUID differently on a big-endian architecture than on a little-endian architecture. This can matter in a lot of cases you might not think about.


On another note, it's not clear what is meant by a player ID, but I would argue that at GUID may not be the best ID to use. Searching and sorting a 128-bit value is slower than searching and sorting 32-bit or 64-bit values. Don't use a bigger value than you need.

Sean Middleditch – Game Systems Engineer – Join my team!



Note that these results depend on how you store the GUID. If you're storing GUIDs a word at a time then a simple memcmp will sort the GUID differently on a big-endian architecture than on a little-endian architecture. This can matter in a lot of cases you might not think about.

Yes, indeed. The GUID itself is defined as a string of bits, and the implementer should take care to store it consistently across target systems as needed. Cheers for the note since it may not have been obvious to everyone.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Oh.

this is going to be part of networking for my game and object to player ownerships

What will happend if I send that GUID as a string to a player over the net. they will still compare to each othe I hope.

what about 32 bit machine sending to 64 bit ????

Im going to send all data as strings and rebuild there values on the other end

the PlayerID looks like this

class playerID

{

GUID ID;

//member

};

using windows guid functions to convert to string as well.

I'm using the ID as the network player ID or should I use Some thing else ??? but ai players need a GUID as well ???

You don't need GUIDs for this. GUIDs are useful if two machines that aren't currently connected together need to independently generate identifiers, which later might become connected later (and the IDs could collide).

In most networked games, this isn't the case. The computers are immediately connected, so the server can generate IDs and send them to the client.

When sending binary data across the network, you do have to be careful. You have to pay attention to the size of each field, and any padding. In addition, a binary integer has many representations, the most common of which are little endian and big endian. One typically selects an endianness for the protocol, and converts incoming multi-byte integers to that storage. Historically, big endian has been preferred, even though on modern desktops you are likely using little endian. Some network protocols use different techniques, e.g. variable length encoding depending on the value, or send a delta-value instead, possibly with run-length encoding (RLE) to handle blocks of zero values.

Sending text data doesn't have these worries, but you have other issues about parsing such as handling delimiters that occur in the data you want to send, e.g. if you use the space character as a delimiter but the user wants to send a username or a chat message that includes spaces. Textual data is typically less space efficient on the network and takes longer to read and write than binary data. Not necessarily an immediate concern, it again depends on the game and how often you need to send and the volume of data you are sending.

Thanks all.

In most networked games, this isn't the case. The computers are immediately connected, so the server can generate IDs and send them to the client.

how would you do that. just a count then some time you will need to restart the sever and kick all players to reset id ???

I'm just in the design stage at the moment and looking at how the objects and players need to link together for networking.

or are the IDs created for each game say a game has 4 players the id only local to that game then I could have ids of 0 to 3 is that what you mean

I was thinking my player is going to be able to play then when done playing come back to the lobby and join or create new game with the same id until they log off.

something like starcraft 2 battle net setup.

Oh too many way to do it confused.

Yep I think I'll set the server to set the ID per game. Only planning on 8 - 16 players.

I guess I could use a char to hold the value then.

save on network trafic.

If your players will have permanent accounts used to join a game (even if only few of them can play at the same time) you will need to identify them between sessions so permanent ID may be better than "per game" one. In such case you need to store user info on server (I assume some DB) so a unique key is a must.

For this reason you may use auto-increment int column so DB ensures uniqueness or you may generate it yourself - just be sure to do it threat safe to avoid duplicates.

This topic is closed to new replies.

Advertisement