Functional-style programming in game development.

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Functional-style programming in game development.

      Does anyone have any experience making games using functional programming techniques? I'm not necessarily looking for games totally written in a functional language (though I would love to hear about it) - just interested in hearing of any kind of implementation of functional concepts.

      altdevblogaday.com/2012/04/26/functional-programming-in-c/

      ^ Probably my favorite articles about the benefits of using functional programming concepts. The following paragraph always gets me:

      "A significant mitigating factor is that performance today means parallel programming, which usually requires more copying and combining than in a single threaded environment even in the optimal performance case, so the penalty is smaller, while the complexity reduction and correctness benefits are correspondingly larger. When you start thinking about running, say, all the characters in a game world in parallel, it starts sinking in that the object oriented approach of updating objects has some deep difficulties in parallel environments. Maybe if all of the object just referenced a read only version of the world state, and we copied over the updated version at the end of the frame... Hey, wait a minute..."
    • Not really, though some of the concepts he's putting out there are just good architecture. Pure Functions are a great example of this. I had never heard the term before, but the concept is relatively common.

      On The Sims, we have unit tests that are written for most large systems. It's required that you run all the unit tests before checking anything in. The tests themselves rarely ever fail. In fact, they're somewhat useless for finding bugs once the system is done and working. Their real power comes from forcing you to architect your system in such a way that it can be exercised by providing some inputs and watching the outputs. In this way, our core systems are "pure".

      For example, I wrote the sim stats system, which is what keeps track of nearly every number associated with a Sim. Hunger, Energy, Bladder, skills, age, etc. This system is tested with a few hundred lines of unit tests. Making me write these unit tests forced me to decouple the system from our tuning structure and from Sims entirely. Stats could be attached to anything, and they are. When a Sim eats food, the food has a stat on it that determines how much of it is left. It also has a stat on it that determines when it spoils, which works exactly the same way as the motives (Bladder, social, etc) on the Sim.

      These concepts can be very powerful, but we're not all going to switch to Haskell anytime soon.

      -Rez
    • Thanks for the input; real-world examples like your stats system are great to hear about! It really shows how decoupling makes a big difference and it helps encourage me to continue to do the same. And yeah, I don't see anyone using a functional language for game development outside of maybe some kind of base system stuff that would benefit from the thread safety that tends to come with functional languages (maybe for AI or something?).

      I try to keep the projects I have at work (some Flash, mostly PHP) and at home as orthogonal as possible. Thanks to some legacy projects I was started on years ago, I came to find the incredibly frustrating consequences of working in coupled systems - the smallest change would have a ripple effect across the entire application! But I think it was a good learning experience.

      Have you been able to use your stats system outside of The Sims on other projects you've worked on? It sounds like it could have a lot of uses!

      Also, thanks to you and MrMike for the book! It's been a great read and will soon be a great resource.
    • Originally posted by jmhgny
      Have you been able to use your stats system outside of The Sims on other projects you've worked on? It sounds like it could have a lot of uses!

      It depends on what you mean. I've used this pattern on other projects, but this specific implementation of the Sim Statistics system was written for our current game. No other game is using the same engine right now. We've been talking about reusing it for another project, in which case my stats system would absolutely be reused.


      Also, thanks to you and MrMike for the book! It's been a great read and will soon be a great resource.

      You're quite welcome, I'm glad you're enjoying it!

      -Rez
    • Originally posted by rezination
      It depends on what you mean. I've used this pattern on other projects, but this specific implementation of the Sim Statistics system was written for our current game. No other game is using the same engine right now. We've been talking about reusing it for another project, in which case my stats system would absolutely be reused.

      I think I meant that specific implementation (or like a base version of it not necessarily tied in to your current game), though who knows because I tend to write this stuff late at night. But that's pretty cool that you might get the chance to reuse it for another project! For me, that's something I hope for in projects I work on - to get a chance to develop a system that has the potential to be used elsewhere. But I've found that trying to force it to work with everything just takes way too much time; so I just let it naturally develop and when it gets to a certain point I go "this can be made more generic" and then mess with it. Doesn't happen too often with me but it's fun when it does.

      You're quite welcome, I'm glad you're enjoying it!

      Literally finished it tonight!
    • Yeah, reuse comes with experience. I have a 2D game engine I wrote that I use for all my side projects. The last side project I did was a little simulation game. The engine itself is about 46,000 lines of code, which is all reusable and used on every project. The simulation game itself was only about 7000 or so.

      My code is structured into layers of functionality where each layer has a different level of reuse. At the very core is the Utility layer, where all my core extension code lives. This code is generic enough to work with any project and I typically include it with any C++ project I do. It has things like my memory pooling system, the OS abstraction interface, error/logging stuff, lots of math, various custom data structures, and so on.

      The next layer up is my Toolbox layer. The toolbox layer is separated into projects (vcxproj files) that each implement some basic system. The rule is that none of these projects are allowed to know about each other. In fact, projects in the Toolbox layer are ONLY allowed to depend on code in the Utility layer. My process & event systems are here, my resource system is here, my DirectX abstraction code is here, etc.

      The third layer is my Engine layer. Its purpose is to bring everything together. It's allowed to depend on anything and everything in Toolbox and Utility layers. It's also allowed to depend on various projects inside itself, though they're usually kept at arms length with abstract interface classes. This is where all the engine-specific code lives. My Application, Logic, and Scene classes are all here. My GUI system, my object/component system, and a number of other things that tie everything together are here. There are also a lot of implementation things here. For example, the resource system is in the Toolbox layer. It doesn't actually provide any resources, it just provides the Resource base class. All the actual resources are defined in the Engine layer. The resource system isn't allowed to know what a texture is, or what a sound is. Only the Engine layer can know about specific engine resources.

      Above that I have a Mix-In layer (previously called my Genre layer for those who have heard this speech before). This is where I put code that I plan on reusing, but that isn't going to be used on every project. This is where I'd add things like a quest system, or a minimap, or processes specific to platformer games, or time-of-day code for simulation games. These are all plug-and-play systems that can be mixed in. They follow a similar rule as the Toolbox layer in that the individual projects in that layer aren't allowed to know about other projects in the layer. They can look at other layers at Engine level and below.

      On top of everything, I have the Game layer. This is where game-specific code and assets go. Anything and everything can go here and depend on anything else. Some of this code ends up being extracted to another layer, but most of it is just too game-specific. It tends to largely be made up of script. On that simulation game I made, about 5000 of the 7000 lines of code were written in Lua. The 2000 lines of C++ is split between about 500 for system support (game-specific Application and Logic classes, etc.) with the other 1500 being C++ processes written for performance reasons and called/controlled from Lua. This was usually code that needed to process every frame (I have a rule that the script isn't allowed to "tick").

      I hope that's helpful. If you're just starting out, I would't worry too much about abstraction and architecture. The most important thing is to get stuff done. You can extract the good parts later.

      -Rez
    • I hope that's helpful. If you're just starting out, I would't worry too much about abstraction and architecture. The most important thing is to get stuff done. You can extract the good parts later.


      That is incredibly helpful, thank you!

      Just getting something done has been my most difficult obstacle. I read and read and read but when it comes down to actually making something, I hesitate and my brain just goes to mush.
    • Originally posted by jmhgny
      Just getting something done has been my most difficult obstacle. I read and read and read but when it comes down to actually making something, I hesitate and my brain just goes to mush.


      That's a common problem, which is why I make the analogy of training vs experience in the Teapot Wars chapter. The most important thing you can do to get better is actually make stuff. :)

      -Rez