It’s time for a programming example everybody loves: the famous ‘Animal/Speak’ example used to demonstrate inheritance from object oriented programming. For many it is their first introduction to defining and structuring behaviour, though it is not the only way or even what many would reach for in practice.
Thanks to OOP we often hear there is an example that goes like this:
class Animal {
virtual String speak()
}
class Dog: Animal {
String Speak() {
return "woof"
}
}
class Cat: Animal {
A field_a;
String Speak() {
return "meow"
}
}
What I actually do is this:
enum AnimalType {
Dog,
Cat,
}
impl AnimalType {
fn speak(self) -> String {
match self {
AnimalType::Dog => "woof",
AnimalType::Cat => "meow",
}
}
}
struct Animal {
ty: AnimalType,
field_a: A,
}
Which is a great for just geting the job done but I’d be lying if I said there weren’t some match statements with 100 cases. Of course they can be broken up with the use of traits but I didn’t want to.
There is no rule that says you should refer to things one at a time. In fact, there can be a lot of nice benefits to working at the collection level always, although they are hard to explain. This is probably how I’d probably prefer to do it (shown with static array):
const MAX_ANIMALS: usize = 64000;
pub struct Animals {
types: [Option<AnimalType>; MAX_ANIMALS],
field_a: [Option<A>; MAX_ANIMALS],
}
Making the game moddable is the Holy Grail.
// ???
// Lua shit
Truly I think this depends completely. Can it be completely data driven - serialize and deserialize. Does it need to run scripts? Then we would become API maintainers.
This relates to my game Gnomes as it approaches 50,000 sales. 2. is in production. I think 3. would assist me to design a proper save format AS WELL AS improve performance for peoples crazy lategame builds (although that has more to do with it being stored in a HashMap though the solution would BECOME this). I think 4. would be the ultimate dream of a game but takes planning.