Coding games is strange

Maybe you are chosen one, and do not have any problems with making them. Well, all I can say is that am not one of them. Of course, I love coding and I love making games but o boy, isn’t it hard to get it finished. It’s been one and a half a year since I started programming, yet I haven’t done anything. You know that feeling when, you written thousands of lines of code and then realized: Oh no, what have I created, this is such a mess and I haven’t even implemented UI system… This situation happened numerous times.

What even is the best practise? Should I use global state or forbid it? What language is the best?. How am I supposed to structure my code? Let’s try to answer these questions, and believe me, I spend a lot of time wondering, but most importantly trying. I tried to use engine, then tried to build my own. Lot of time was wasted, lot of knowledge gained.

One concrete thing I tried, and it was really foolish, to use Rust-lang to make a game. Mistakes were done in deed. Though am not saying Rust is bad or something, it promises safety, safety and safety and speed, but there is the catch. If compiler considers your safe code unsafe, you have to rewrite it. Rust is truly horrible language for videogames, but knowledge of it is insanely useful. Rust compiler teaches you how to think. It mostly enforces better solutions. It discourages from using pointers to data and if you think about it, less pointers the better. Then you can sometimes apply practise from rust to different language to improve your code. Still using rust for everything is just no good. What do we really want from a game making language?

Majority of game logic has to be reused on multiple places. OOP languages offers inheritance por reusing behaviour. Isn’t that convenient? No, it is not, or at least I don’t think it is. Whi should I spend my time strategically branching my object tree in a way that nothing is redundant and nothing is there twice. That’s just a big waste of time for me to be honest. I am of course saying this after multiple tries. What we really need is language that is not object oriented, that does not create unnecessary temptation to make thinks like they exist. We have to look at data as data not as cars and animals. They really aren’t that, even if we name them like that. The way to go is composition and embedding.

Now those are little fancy words but principle is very simple. You have an object that holds transformation of any visible object in game? Don’t make everything inherit it, make it a property of it or better said, component. You can do this in any language but not every language makes it so nice as Golang. Let’s let the code speak for itself:

package mainimport "fmt"type Foo struct {
A int
}
func (f Foo) Double() int {
return f.A * 2
}
type Bar struct {
B int
}
func (b Bar) Half() int {
return b.B / 2
}
type FooBar struct {
Foo
Bar
}
func (f FooBar) Sum() int {
return f.A + f.B
}
func main() {
fb := FooBar{Foo{4}, Bar{6}}
fmt.Println("fb:", fb)
fmt.Println("fb.A:", fb.A, "fb.Foo.A:", fb.Foo.A)
fmt.Println("fb.Half():", fb.Half())
fmt.Println("fb.Bar.Half():", fb.Bar.Half())
fmt.Println("fb.Sum():", fb.Sum())
}

As you can see Go lets you omit names of components if you do not provide name of struct field. You can run this example in Go playground to see the results.

Now that we found a language, let’s talk about global state. It’s usually considered best practise to not use is at all. I of course tried to not use global state at all because rust basically does not support it at all, but I quickly came to a conclusion that this is god damn hell. If every function takes ten parameters only because you just cannot make these arrays of game objects global, ewe though you always need just one of them. You can sure make one gigantic Object named GameState that would contain everything and just pass that around, witch absolutely disallows concurrency…

This is kind of getting long. Let split it to multiple articles. See you later.