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 , , , .

44 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
    Physics() : G(0.0000000000667);
    virtual ~Physics();
    // Physical properties
    const float G;
    // Don’t want any outer functions to toss around needless copies
    Physics(Physics &physical);


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

    #include “Physics.h”

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


    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.

    > “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”.

    > 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”.

    > 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. Mikolaj Konarski says

    Hi! Your article has just been mentioned on

    Would it possible to readd the diagrams mentioned in the text that are currently missing? Thank you!

  18. Dante says

    Highly descriptive post, I liked that bit.
    Will there be a part 2?

  19. Myles says

    I read a lot of interesting content here. Probably you spend a
    lot of time writing, i know how to save you
    a lot of time, there is an online tool that creates unique, SEO friendly
    posts in seconds, just search in google – laranitas free content source

  20. diet tips and fitness goals review says

    With havin so much content and articles do you ever run into any problems of plagorism or
    copyright infringement? My blog has a lot of exclusive content I’ve either authored myself or outsourced but it looks like a lot of it is
    popping it up all over the internet without my permission. Do you know
    any ways to help protect against content from being
    ripped off? I’d really appreciate it.

  21. website traffic says

    Simply wish to say your article is as astonishing.

    The clarity for your put up is simply nice and i can think you’re a professional in this subject.
    Fine with your permission allow me to grab your feed
    to stay updated with impending post. Thanks one million and please carry on the
    enjoyable work.

  22. blackhatprotools says

    Thank you for any other wonderful post. The place else
    may anybody get that kind of information in such an ideal approach
    of writing? I’ve a presentation next week, and I am at the look for such information.

  23. Celebrity Teeth Today says

    Hurrah, that’s what I was looking for, what a material!
    present here at this website, thanks admin of this site.

  24. Green Coffee Cleanse says

    Nice blog right here! Additionally your web site lots up
    very fast! What web host are you the usage of? Can I get your affiliate link on your host?
    I wish my website loaded up as quickly as yours lol

  25. hacker un compte facebook says

    Very descriptive blog, I enjoyed that bit. Will there be a
    part 2?

  26. Green Coffee Cleanse says

    Unquestionably imagine that which you stated. Your favourite justification appeared to be on the net the simplest factor to be aware of.
    I say to you, I definitely get irked whilst other folks consider concerns that they just do not recognise about.
    You controlled to hit the nail upon the highest and also
    defined out the entire thing without having side-effects , other people can take a signal.
    Will probably be back to get more. Thanks

  27. weight loss says

    Wonderful beat ! I wish to apprentice while you amend your website,
    how can i subscribe for a blog website? The account aided me a acceptable deal.
    I had been a little bit acquainted of this your broadcast provided bright clear idea

  28. says

    You really make it seem so easy with your presentation but I find this
    matter to be actually something which I think I would never understand.
    It seems too complicated and very broad for me. I’m looking forward for your next post, I’ll try to get
    the hang of it!

  29. Tyler says

    Valacyclovir may be the generic brand of the treatments and is popular amonst the people experiencing
    this infection.

  30. best article rewriter says

    Your style is so unique in comparison to other folks I have read stuff from.
    Thank you for posting when you’ve got the opportunity,
    Guess I will just book mark this web site.

  31. Arden says

    6 GHz MSM8928 Snapdragon 400 Quad Core Processor and 1.
    That way, if one goes down, someone else can turn on a phone that still
    has its full charge. This literally leaves no escape for
    the victim of bullying; where once their bedroom was a safe haven away from
    the bullying and name calling at school, they are
    now carrying this bully around with them wherever they go.

  32. flappy bird cheats tool says

    If you are going for best contents like me, only visit this website every day because it offers quality contents,

  33. diet tips says

    This page definitely has all the information I needed about this subject and didn’t know who to ask.

  34. Derick says

    Najdete tady sexy partnery z Prahy, kteří touží po tom, splnit všechna ѵаše prání – pokud jim tօ
    dovolíte. Promente sfoje nejtajnejší erotické fantazie а sny ve
    skutecnost s nekým neokoukaným ɑ neznámým a odvažtе se.
    nebo se třeba sejdete rovnou s několika, pokud se nna tօ

  35. chatroulette alternative french dictionary says

    The webcam supplies an instant link and the
    savvy predator will know just how to reel the younger person into a “relationship” that
    will go beyond the Chatroulette on-line site. The user’s live image
    appears in one video box via webcam and his partner’s image appears in the other box.

    Il n’ya qu’une individualiste doit: vous devez trouver l’autre femme intéressante, et
    souvent les période qui nécessite la parcouru redoutable
    de briser la induction.

  36. home hydroponics says

    Most properties have a front garden or a backyard with timber and grass.
    The particular person can easily make a number of
    changes then it will be better than it was earlier than.

  37. aquaponic farming says

    Sustaining a farm isn’t straightforward given the massive space to
    cover and the manpower wanted to make it work.

  38. webcam sexchat says

    Spot on with this write-up, I absolutely feel this website
    needs a lot more attention. I’ll probably be back again to see more, thanks for the advice!

  39. Lemuel says

    Thanks for some other excellent article. Where else could anyone get that kind of information in such a perfect means of writing?
    I have a presentation subsequent week, and I’m at the search for
    such info.

  40. buy electronics online with bad credit says

    This website was… how do you say it?Relevant!!
    Finally I’ve found something which helped me.
    Thannk you!

  41. Fred says

    Hi admin do you need unlimited articles for your site ? What if you could
    copy post from other blogs, make it unique and publish on your website – i know the
    right tool for you, just search in google:
    kisamtai’s article tool

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.