F# in Social Gaming
Yui Cui
F# tends to be good for math (financial programming, etc.)
BUT it is good for general purpose as well. Starting to get used more this way.
They have implemented a slots game in F#.
Mathematicians create a math model for every game to determine how players win.
Discriminated Unions are like Enums, except that they are real types – you cannot instantiate an invalid value like you can with Enums.
Use type aliases to make your code clearer:
Type Count = int
Type LineNum = int
The point is to make invalid states unrepresentable
You’re never too smart to make mistakes
Units of Measure help
[<Measure>]
type Pence
so, 42<Pence>
10<Meter> / 2<Second> = 5 <Meter/Second>
Helps you to not use the terms incorrectly and avoid calculation errors
Records are containers for data – they are immutable
You can add a custom indexer to a record to make it easier to access a particular element of the contained array, for example
In F# you have to be explicit about what functions you want to be recursive (rec keyword)
match allows you to use the power of the discriminated union to execute different code in each case in a much safer and clearer fashion than an old-school switch statement. match does to the untrained eye look like a switch
To hold game state, they are using the actor model
Everything is an actor
An actor has a mailbox
It can receive messages via the mailbox
Gatekeeper manages the list of workers
Gatekeeper is the bottleneck, so it directs traffic and then gets out of the way – workers respond back around the gatekeeper
Actors communicate by sending messages
If they need a response they have to send a reply channel
Actors can do their communication asychronously
Does not block I/O
Actors for state management increased their performance on game servers by 5X
Caveats – game servers need to have affinity to players (player gets the same server throught their session). Need to load balance, need to avoid hotspots (tweak the logic to spawn new sessions intelligently)
Timing out players after 3 minutes helped with the hotspot problem.
Need to gracefully scale down – move player off to other servers and refuse new players so that you can turn off the server that is no longer needed
Agent summary
* no locks
* async message passing
Agents are low level and will lose any unsaved state changes if they die due to failure or exception. There is not much you can do to improve this as they come out of the box. Use akka.net, MS Orleans, or Cricket frameworks to help mitigate this. Or move out of .net and use a language that runs on the Erlang VM (erlang, elixir, etc.)
Replacing a large class hierarchy
Large scale multiplayer games with experience, levels, quests, etc. has a lot of state data
Their solution – use the message-broker pattern
Caught a gnome – an fact occurred (and event)
Each fact can trigger actions in many different areas of the game
There are lots of facts
Instead of discrete classes (100’s) build a series of discriminated unions that build on each other to express the facts
The problem is that this affects C# interop – it makes code that uses the DUs very ugly
You can use marker interfaces in C# to make it easier
Introduces the possibility of invalid states, though, so now you need to handle the exceptions that occur when there is an invalid state.
Still reduces the class hierarchy