Applications over Freenet: a Decentralized, Anonymous Gaming API?
It's easy to register yourself as open for a game (see Listing 1). You simply construct a Freenet key (analogous to a filename or URL) that follows a well-known format and insert your desire for a match. Other game clients periodically request keys in this well-known format and make a catalog of open games. The format used by the EOF gaming engine is <<I>game>-request-<<I>seconds>-<<I>number>, where game is the name of the type of the game you're playing (to avoid a namespace collision with other games types), seconds is today's date in a funky format (to avoid a namespace collision with things inserted yesterday) and number is a unique number for that particular game (to avoid a namespace collision with other games).
Generating a key is easy, you need values for the date and the game number. To generate the game number, you first start at 0. You generate a key and try to insert it. If there is a collision, you then add 1 and try again. You keep doing this until the insert succeeds.
This can be a slow process if there are a lot of open games, and it's the reason for the date portion of the key. Since this portion changes every day, you can start over with 0 every day, thus keeping the number portion from growing arbitrarily large over time.
The seconds portion of the key is the most difficult to generate. You want a unique identifier for today's date. You could use a MM-DD-YY format. However, this is very inconvenient for programs that might want to look through several days worth of games, perhaps to generate a database of winners and losers. Enumerating through keys in this format requires the use of a calendar to know when to stop incrementing the day field, reset it and increment the month field.
Because of this, a "seconds since the epoch" format is used. A single function call exists in a majority of languages for obtaining this value. In Java, you do it with
long seconds = new Data().getTime()/1000
You have to divide by 1,000 because Java gives you milliseconds since the epoch. Unfortunately, this is not a unique identifier for today, but for a particular second of today. Luckily, there are 86,400 seconds in every day. Thus, to get a unique identifier for today, you simply compute seconds - (seconds % 86400).
You now have everything you need to generate a unique key for your match request. Now you just need something to put in it. In the EOF gaming API, we put your nickname. That way, when someone is browsing open games, they know who they will be playing against. Of course, this isn't a secure naming system. Players can change their names, copy other people's names and generally act obnoxious. Later in this article we'll rewrite the name system to be more secure, so don't get too attached to it.
Replying to an open game is simple: create a key in the format <<I>game>-reply-<<I>seconds>-<<I>number>, where all of the fields are the same as the request. It is important to note that you don't generate your own number here but, instead, use the same one as the request to which you want to reply. Put your nickname in the file and insert it under this key. If a collision occurs, then someone else has already entered the game and the game is closed. This method stated above obviously only works for two players. Extending it to N players is left as an exercise for the reader. Hopefully, your opponent's client is periodically checking for the insertion of a file with precisely the same key as the one you just inserted. Now it's time to insert moves.
The players take turns inserting moves under keys with the format <<I>game>-move-<<I>seconds>-<<I>number>, where the number starts at 0 and increments by one with each move. Whether players play in turn and whether their moves are legal is not part of this framework. These aspects depend greatly on what game you're playing and, as such, should be handled by software that knows about these things. There is, however, one fundamental and terrible flaw with this system of moves: your opponent can move for you and the game engine has no way of knowing who really made the move. It obviously would be desirable to have the moves be unspoofable. This is easy enough to do, but it requires more knowledge of Freenet features, in particular the formidable signed subspace key (SSK).