This post could also be called:One step forward, two steps backwards.
I thought I should rewind a little bit, and have an overview of the game before we continue.
The C# version of the game has 9 files and each, each has a class where (generally a component is defined), I decided to change this for the F# version of the game, tho I am not sure type per file is an idiom of F# or not. (Comments on this, really welcome)
The idea of doing this port is to show the progression of the code from C# to F# to (hopefully) better F# so if you have some comments on how to improve, they are super welcome, particularly commenting with code samples (or PRs). The whole game (in C# and F# and the editor ) is all available from this github repo.
About Duality
The engine, Duality, is a C# engine that follows some of the C# idioms. It is not in our inmediate plans to make a wrapper to make the engine more f# friendly, I find don’t find it too hard to work with the two languages, however it might be because I am familiar with it enough to not feel much of the pain.
These are bits of code we will se over and over
Is it a bit humid here?
Declaring a component. Needs to be serializable, and inherit from component
[<Serializable>]
type LifeMeter() =
inherit Component()
Most of these components will need to implement ICmpUpdatable
or ICmpInitializable
interface ICmpUpdatable with
member this.OnUpdate() =
//Do some componenty stuff here
Some components need to be able to detect collisions, on those situations you need to implement ICmpCollisionListener
interface ICmpCollisionListener with
member this.OnCollisionBegin (_, args)=
// Do collision stuff here (or somewhere else)
member this.OnCollisionEnd(_,_)=
()
member this.OnCollisionSolve(_,_)=
()
I don’t think I mind the interface implementations.
Then there is the find the (not null) component. In the example below we are looking for a TextRenderer
within the object. In the None matching, it is more likely you want to log and editor warning, rather than do nothing
let tr = OptionComponent<TextRenderer> this.GameObj
match tr with
| None -> ()
| Some tr ->tr.Text.SourceText <- sprintf "Score: %i" score
What does all of this mean? well I though it might be useful to sunmarize what I have seen so far. I’ll update this post with more if I think of any other repeating pattern.
Untill the next time :D