Skip to content


Why I switched from component-based game engine architecture to functional reactive programming

Components have become pretty popular these days and I’d like to share some issues we had with them in our game projects. I was experimenting with component-based game engine architectures for 2 years and eventually stumbled upon functional reactive programming (FRP) to solve some of the issues of game-object components. I hope to provide some arguments from an objectoriented programming (OOP) viewpoint to why I think FRP helps to write more reusable code.

The argument for component-based game-engines usually starts like this: Game-objects should be represented like objects in reality but as the project progresses however, class hierarchies become more and more complex and thus should be split into small, reusable components. Game developers like abstract and re-usable game-engines after all. The following diagram illustrates such a monolithic class hierarchy (adopted from the book Game Engine Architecture):

Game-object components address these issues by reducing game-objects to identifiable containers of components, where each component encapsulates some reusable functionality and automatically communicates with other components. A component could be something like: a position, player movement, 3D model, health-points and so on. For the communication of components in our engine we used messages, events or let them directly search for components implementing a specified interface, which is illustrated in the following diagram:

In component-based architecture we were mostly concerned about the component intercommunication, like the player movement for example: Should the Mover-component manipulate the position directly or send movement-messages? Or should the Position-component listen to movement-events? What if we want the player movement to behave just a little differently, like being a little random? Do we implement a new RandomMover-component, or do we need a new component,… again,… just to encapsulate the random function into a component? And how does this fit into the automatic Position-Mover-communication?

In the book Component-based Software Engineering (CBSE) they actually define a component as:

A software component is a software element that conforms to a component model and can be independently deployed and composed without modification according to a composition standard. [...] A component model defines specific interaction and composition standards. [...]

In plain English: “In order to allow a new component to be added to an existing environment of components in a game-object and automatically communicate with each other, the communication protocol between the components has to be predefined“. I think the component-based game engine literature mixes-up “combining existing functionality to define game-specific logic” (= reusing functionality) and “automatic communication within unknown game-objects” (= dynamic functionality). Automatic communication is restricted to the known components and new functionality always has to be game-specific (either hard-coded, or in scripts, or any other data-driven method). Even with components you define the player game-object specifically at some point: Player = PositionComponent + VisualComponent + InputComponent.

In FRP everything is based upon time, thus time should be abstracted away into “time dependent functions” (behaviors). A Mover-”component” should just produce a translation vector over time from user-input — nothing more! And if we want it to be a bit random, we just compose the output with the random function in the game-object definition. A pure mathematical function is the most isolated, self-existing and reusable component you can get, as it depends (and only depends!) on the direct input. There is no need the encapsulate a function into a component… which is then managed by a component container (game-object) and defines a lot of messages and events to get the data to the right point.

I’m arguing that game-objects are always game-specific but with time-dependent functions you just have to combine the existing functionality in the right way for every specific game-object. For example, let the movement of a game-object by calculated by: the initial position + some translation over time from user-input + a random factor + … and so on. You may then compose the movement behavior into more complex behaviors (or complete game-objects if you like) in every way you can imagine: A movable, static image game-object? MovingImage = translation function + draw image function. A movable, animation game-object? Certainly! MovingAnimation = same translation function + draw animation function. Or just a static animation perhaps? StaticAnimation = position + draw animation function.

I’m not going into more detail about FRP for now, you can find more information on my blog or on the internet. Component-based software engineering can still be applied in this environment on higher level, like the communication between subsystems or game-objects, but not on the level of game-object functionality level! If you still think you want to implement game-object components, ask yourself the following questions:

  • How can different functionality be defined in terms of relative complex, non-elementary components?
  • What are the most elementary components?
  • In which way are elementary components different from pure functions?
  • How can existing components automatically communicate with new messages from new components?
  • What is the point of ignoring a message that a component doesn’t know of?
  • What happened to the input-process-output model after all?

Tagged with , , , .


38 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Jedd Haberstro says

    Would you mind giving a more concrete example or explanation of how you’re using FRP to replace a component-based design? :)

  2. Alex Schearer says

    This is a helpful post outlining the distinction between traditional game hierarchies and a component model as well as the motivation for moving from one to the other. I’m in the midst of implementing a game using a component model and have been wondering what a functional language could offer to resolve some of the complexity which creeps in when connecting components, especially when they aren’t owned by the same entity. I’d love to see a follow up post where you go into more detail about how functional programming worked and didn’t work. Of course without revealing your entire thesis!

  3. Johannes_von_Luck says

    This sort of layout is also possible from just having a heavy reliance on interfaces (say with an optional, but separate, default implementation class).

    The problem with the design above, where renderable object inherits from movable object that inherits from game object, is simply that functionality becomes top heavy. Consider an object added into this layout that is not movable but still requires the renderable part? You move the renderable up (or just reorganize). Now do this a few more times, say you need a different kind of pellet that is not renderable nor movable, etc., and you simply wind up with a top heavy class that is supposed to be “reused” and functionality not needed is “nulled out”.

    When you instead reference classes as members of inherited interfaces, then you simply talk through the interfaces. Doing so resembles quite closely the idea behind component based architecture.

    Why? Because game objects are more fit for a has-a relationship, not an is-a relationship.

  4. Gerold Meisinger says

    I wouldn’t say replace. I think the game literature understands components (in OOP!) as functionality that can be interconnected by forms of communication, but also mix-in the game-specific stuff (like a health component, which forces you into a specific scheme). In general CBSE components are just defined as something that communicates according to a *predefined protocol*, so new, unknown components can be used in an existing environment. But when you define game-specific(!) objects of their own, most of the time you just want to connect existing functionality, like “Player = Position+Translation+Animation, thus: let the position be changed by a translation suggestions and draw the animation at the resulting position”. That is what “signal functions” give you in Yampa with the usual benefits of FP (like combining new complex components from very, very basic ones). General CBSE can still be applied here, like when you want objects to communicate with each other. But maybe the communication isn’t needed at all. Collisions f.e. can be resolved by looking at the object states from a more global viewpoint and sending the game-objects collision events which need to be resolved by game-specific(!) rules. You may define a “Object which destroys itself on collision”, which is okay for most games, but more complex games have more specific rules.

  5. Den says

    Lots of jabber, no concrete samples: useless.

  6. Gerold Meisinger says

    Yap, I will eventually come to that. For now I just wanted to show the limits of components.

  7. Den says

    Fair enough. I am looking forward to it!

  8. Jesse Werner says

    Concrete examples please!!

  9. Nick Wiggill says

    To those who don’t get it:

    FRP is only a part of the whole. The most important aspect, pure functional composition, can be done with just straight FP and you can also achieve it with prototypal OO as in eg. JavaScript. If you’re not sold on that first, you’re not gonna be sold on FRP.

    FRP is really a whole layer on top of the concept of first-class functions as being the ideal form of composing functionality.

  10. imre says

    On one hand I understand what you say about the (possible) limitations of component systems, and I also see how important functional composition is. On the other hand I think I also know the basic principles behind FRP. But I fail to see the connection between these two.

    Most importantly:
    “How can existing components automatically communicate with new messages from new components?”
    This depends on how those components are designed, just like it would depend on how your functions are defined. In both cases, you need to keep functional composition in mind. Your example of Mover producing a translation based on time is not only possible in a component system, but actually to me it seems to be the straightforward version.

    If all you wanted to say is that in a good component system components have a single output (so they are really functions, making functional composition possible), then I agree.

  11. anon says

    Appears to me the OP doesn’t truly understand entity-component-systems, or perhaps I didn’t understand the explanation without concrete examples. Components should just hold data, for the example of random movement, that’s a simple random flag in the necessary component, and a change in the handling system to process the random. I’d like to see more examples… it’s very clear how OOP works and where it breaks down… if you see a fault in Component-Systems in favor of FRP, then illustrate how that works.

  12. Tom says

    Having each functional aspect of the game react to a time-based system is a bit clever (almost event-driven with respect to time). However, there are major down-sides to adopting this type of paradigm. In the aggregate, you run the risk of having your classes lose a lot of their self-maintainability and overall cleanliness; two fundamentally important concepts in OOP. Your classes will also lose some higher-levels of abstraction which is the whole point of OOP. This may be a viable solution to a procedural or object-based language (like JavaScript); However, in a low-level object-oriented language, FRP is not a conclusive enough solution for engine architecture.

    On another note, I do believe you are not approaching the concept of component-based architecture quite effectively. In fact, I believe that of many professional engineers within the gaming industry. Often times, I see many programmers demonstrate component-based objects as interfaces that registers to some base object handler which interprets some message and then executes some code. This is not how component-based objects work (or should work). Each component of the game should be encapsulated at a high-level and self-maintainable – meaning: each class takes care of its self and nothing more. Objects are like entities; entities have relationships. The relationship of these components are like siblings; they are children to the game object. Let me demonstrate:

    // Physics.h – An extremely contrived physics component of the main game object
    #ifndef _PHYSICS_H_
    #define _PHYSICS_H_

    class Physics
    {
    public:
    Physics() : G(0.0000000000667);
    virtual ~Physics();
    // Physical properties
    const float G;
    protected:
    // Don’t want any outer functions to toss around needless copies
    Physics(Physics &physical);
    };

    #endif

    // Game.h – An extremely contrived example of the main game object
    #ifndef _GAME_H_
    #define _GAME_H_

    #include “Physics.h”

    class Game
    {
    public:
    Game();
    virtual ~Game();
    protected:
    // Same deal here
    Game(Game &game);
    // TODO: List all instances of relevant component objects
    Physics physics;
    };

    #endif

    You see, each component is encapsulated and an instance (the only instance, hence the protected copy constructor) is giving to the main game object. That is what we call a HAS_A relationship; The game HAS_A physics component. Furthermore, the game does not manage the state of each component; rather it is responsible for the implementation of each component and nothing more. The game object must maintain its own state as well.

    I understand many programmers will find it hard to adopt – let alone understand – a new paradigm. A lot of the responses within the industry seem to be out of confusion. I do not wish to disrespect your ideals, nor the ideals of my fellows piers. However, In my experience, I believe a component-based architecture is most efficient in terms of OOP.

  13. Gerold Meisinger says

    @Nick Wiggil
    > pure functional composition, can be done with just straight FP

    Ah, you’re very right on that.

    @imre
    > “How can existing components automatically communicate with new messages from new components?” This depends on how those components are designed, just like it would depend on how your functions are defined.

    The emphasis is on NEW messages here. The argument in some implementations is, that you add a new component that broadcast messages to other components and magically everything works together. Which simply can’t work if they don’t use the same “protocol”.

    @anon
    > Components should just hold data, for the example of random movement, that’s a simple random flag in the necessary component

    What about “holding functionality”? And adding a random flag would make the component more powerful than an ordinary “straight-line” movement component would need. We could however add “apply-randomness” component to the movement component but that’s a lot of overhead for something I’d call “parametrization”.

    > it’s very clear how OOP works and where it breaks down
    Really? I haven’t read or heard of any OOP critism until I deliberately started looking for it :) And I’d glad to hear where you think “it breaks down”.

    @Tom
    > However, in a low-level object-oriented language, FRP is not a conclusive enough solution for engine architecture

    Well… most of them are written in Haskell, a non-object-oriented language ;)

    > This is not how component-based objects work (or should work).

    Yeah, a definition would be fine. I think a lot of confusion derives from using different terminology. What you call a component in your example, we used to call a subsystem(-component), wereas in my article I use game-object components.

    @Future me
    More concrete examples!

  14. Ywen says

    Just a question: why Yampa?

    Why an AFRP framework instead of an applicative and monad-based one (like reactive, or now sodium, reactive-banana or elerea)?

  15. Gerold Meisinger says

    Please note the date! I’d definitely would take a look at reactive-banana. My original choice was mainly:
    * more papers and examples available (FRP is hard enough if you’re not used to FP)
    * mature and though-through code (I still think that Arrows make a lot more sense in this context than monads)

  16. william says

    I have a few components I find very useful for defining game objects, like a “Bank” component (essentially a protected value kept between certain intervals, with methods to withdraw or deposit values) or a “Timer” element (which counts down until empty and then returns true instead of false).

    I suppose these aren’t components “per-se” as they don’t communicate automatically through (a)synchronous messaging, but they do demonstrate the usefulness of object-oriented programming over pure-functional!

    That said it’s always interesting to see new paradigms proposed: I’ll look into FRP with great interest :)

  17. Johnd273 says

    Link exchange is nothing else but it is just placing the other persons weblog link on your page at proper place and other person will also do similar in support of you. fedgkccbakba

  18. search engine optimization in seattle says

    Hi, I do think this is a great site. I stumbledupon it
    ;) I’m going to return yet again since i have
    book marked it. Money and freedom is the greatest way to change,
    may you be rich and continue to guide others.

  19. Build Lean Muscle Diet says

    Fantastic goods from you, man. I have understand your stuff
    previous to and you’re just too wonderful. I really
    like what you’ve acquired here, really like what you’re stating
    and the way in which you say it. You make it entertaining and you
    still take care of to keep it smart. I cant wait to read much more from you.
    This is really a terrific site.

  20. Florida SEO Company says

    Hello, i believe that i noticed you visited my blog thus i
    got here to return the desire?.I am attempting to find things to enhance my site!I assume its good enough to use a few of your ideas!!

  21. Ripped Muscle X Reviews says

    Right now it looks like Drupal is the preferred
    blogging platform available right now. (from what I’ve read) Is that what
    you are using on your blog?

  22. lean muscle meal says

    Hmm it looks like your blog ate my first comment (it was super
    long) so I guess I’ll just sum it up what I had written and say, I’m thoroughly
    enjoying your blog. I too am an aspiring blog blogger but I’m still new to the
    whole thing. Do you have any tips for rookie blog
    writers? I’d certainly appreciate it.

  23. dobierz idealny biustonosz says

    I always used to study post in news papers but now as
    I am a user of internet therefore from now I am using
    net for posts, thanks to web.

  24. Low Testosterone supplements says

    Useful info. Fortunate me I found your site accidentally, and
    I am stunned why this accident didn’t happened in advance!
    I bookmarked it.

  25. wrinkle rewind anti-aging cream says

    My spouse and I stumbled over here from a different
    website and thought I may as well check things out. I like what I see so i am just following you.

    Look forward to exploring your web page repeatedly.

  26. www.paykanhunter.com says

    Hello there! This post couldn’t be written any better!
    Reading through this post reminds me of my previous roommate!
    He continually kept preaching about this. I most certainly will send this post to him.

    Fairly certain he will have a great read. Thank you for sharing!

  27. Forrestthinks.Blogspot.Co.Nz says

    Very nice write-up. I definitely love this website.
    Stick with it!

  28. arnaques petites annonce says

    An outstanding share! I have just forwarded this
    onto a friend who was conducting a little homework on this.
    And he actually ordered me dinner because I discovered it for him…
    lol. So let me reword this…. Thanks for the meal!!
    But yeah, thanks for spending the time to talk about this matter here on your blog.

  29. african mango diet pill reviews says

    Hi it’s me, I am also visiting this site regularly,
    this site is truly good and the people are in fact sharing nice thoughts.

  30. Garcinia XT review says

    It’s not my first time to visit this web site, i am visiting this site dailly and take good facts from
    here every day.

  31. http://www.winstepconsulting.com/project/173 says

    Hello there, just became alert to your blog through Google, and found that it is really informative.
    I am going to watch out for brussels. I’ll appreciate if you continue this
    in future. Lots of people will be benefited from your writing.
    Cheers!

  32. anti aging product reviews says

    Hi there to every body, it’s my first go to see of this website; this weblog includes
    remarkable and truly fine data for visitors.

  33. search engine optimization sarasota says

    If some one needs expert view regarding running a blog then i propose him/her to pay a visit
    this blog, Keep up the good work.

  34. use article writing says

    Wow, tɦis paragraph is fastidious, my younter sister is analyzing these things, therefore
    I am going to tell her.

  35. http://www.starstudentmagazine.com/news/best-design-services/ says

    Awesome blog! Is your theme custom made or did you download it from
    somewhere? A theme liuke yours with a few simple tweeks would
    really make my blog jump out. Please let me know where you got your design. Thank you

Continuing the Discussion

  1. Component system | BoxHacker linked to this post on 2011-07-02

    [...] Programming discusses these benefits in illustrated detail while Lambdor discusses some problems he [...]

  2. First Thoughts on XNA 4.0 Game Architecture – Small Thoughts linked to this post on 2011-09-09

    [...] is to have them abstract and the best way to do that is to normally make it so that your engine is Component base driven. Although that architecture lends itself to amazing data driven design, I wanted to just [...]



Some HTML is OK

or, reply to this post via trackback.