bw logo

Chapter 4. Variations

The example here is a starting point for building your own friends list. We have pointed out areas that need further work before it would be suitable for use in a production system. Certainly you will also have specific requirements for your game. This section discusses some obvious variations and their implications.

4.1. Asking for permission to be someone’s friend

This could be a requirement if friends have special access (e.g., the getInfo command in this document's example).

Ideally, the friend can subsequently rescind his friendship after granting it. This means admirers list should become editable by the user. Hence, it should probably store more than just the DBID for performance reasons.

It may also be a good idea then to limit the size of the admirers list, since there would be usability problems when this list is large.

Each "Can I be your friend?" request should also be stored somewhere. Places they could be stored:

  • On the client of the player being asked (the askee).

    • This is the bare minimum, since the askee must have visual indication of being asked.

    • When the askee logs off, requests are forgotten.

    • The asker cannot keep track of outstanding requests.

    • A possible situation exists where acceptance is rejected because the asker’s friends list has become full since the request was made.

  • On the client of the askee and on the base of the player who is asking (the asker).

    • The asker can keep track of outstanding requests, therefore will not exceed friends list limit.

    • The asker can withdraw the request.

    • The askee can notify the asker when he logs off (by using info in the request from the asker) and the asker can remove outstanding requests.

    • It is possible, but it does not make much sense for the asker to persist requests because askee will forget requests when he logs off.

  • On the client and base of the askee, and on the base of the asker.

    • Same as above except...

    • Both askee and asker can persist requests, and requests can be accepted independent of each other’s online status.

    • Possible data integrity problems because we have persistent data in two entities that needs to be kept in sync.

4.2. Enforcing mutual friendship

Where mutual friendship is enforced, it will be possible to eliminate the separate friends list and admirers list.

So when player A adds player B into his friends list, he is automatically added to B’s friends list.

It is highly recommended that players be forced to ask permission before forming friendships (see above). This is to prevent total strangers from using up the limited number of friends each player is allowed to have.

Note that enforcing mutual friendship would not allow a game world to have "leader" characters with many more admirers than friends.

4.3. Matching request and response

In this document's example, the base would often call self.client.showMessage( <type>, <source>, <message> ) as response to a request from the client.

Often this is not sufficient for real GUIs. For example, a button may be disabled while the operation is in progress and re-enabled when the operation completes. So the client must know that the showMessage corresponds to an outstanding request, and not some unsolicited message (e.g., message from a friend).

One solution would be to make a separate callback method for each operation (e.g., onAddedFriend, onDeletedFriend, etc). But this could make the .def file quite cluttered.

Another solution would be to pass sequence numbers and have them passed back in the result (e.g., showMessage( <sequence_number>, <type>, <source>, <message> )). This would have the advantage of supporting multiple outstanding requests of the same type (e.g., multiple addFriends), but is obviously more expensive (extra integer in message and dictionary in the client to map sequence number to request) and therefore should be limited to infrequent calls.