Jump to content

Anyone Using Redux with Phaser?


Recommended Posts

So I started a project in es5 javascript and put everything in one huge game file. This quickly became hard to manage so I decided to use ES6 Javascript and break things out into their own classes. However, I then realized that there are times when these different classes need to display and modify the same data. In a part project I've used Redux with react which was pretty awesome, and I've used shivering very similar in angular 2 (Ngrx library). 

In another post about React it seems like people are saying the virtual DOM, JSX, and all that is pretty much useless with the way that phaser renders in canvas and doesn't really use any HTML. 

However, I just stumbled across this really cool jsfiddle that uses the redux library, straight up, as a way to manage state with redux alone: https://jsfiddle.net/archierocks183/zygz2ksm/17/

What do you guys think about this? Do you think it's a good way to go? Does anyone have any projects where you've gone down his route (or something similar)? How did it go? 

Just trying to get ideas and figure out how to manage state in my growing app. Thanks! 

Link to comment
Share on other sites

I've got a number of tests for this sort of thing, biggest issue is simply with performance.

Redux and redux-like libs aren't really designed for state that is changing frequently, the primary use-case being changes resulting from user or network actions, neither of which happen particularly frequently. Things like animations, which do trigger frequently whilst running, aren't usually kept within a centralised store.

I've tested this with and without the complexity of rendering into a canvas (using Pixi rather than Phaser but the process is the same) and managing large lists of entities, all changing their position every tick, is pretty heavy, very hard to keep up with 60 fps.

Depending on your use-case though, it is very definitely possible.

Link to comment
Share on other sites

It's not the pub/sub (event dispatching) its the recreation of the state object each change, which could be 60+ times a second, for a large state object this is always going to be expensive. I also tried using stuff like immutable.js which, in theory, actually makes this cheaper but it introduced loads of other overhead so was much much slower (having spoken to a friend who does a lot of data visualisation they couldn't use immutable for the same reason).

Of course, redux doesn't enforce that you create a new state object each mutation, you could just mutate the state object but you'd have to weigh that up with how React (or other complementary modules like reselect) does its work i.e. if anything is checking for a mutation with a `prevState !== nextState` (as React does) then things might start getting funky when it can't work out what has changed with a standard JS equality check. You could end up with a more manual tracking of whats changed but then you lose most of the benefits of modules you're using, you could use a more comprehensive equality check but then you ramp up the calculation costs, given you're likely going to be fighting for perf anyway then upping the calculation costs probably isn't going to work out very well.

Link to comment
Share on other sites

  • 2 weeks later...

An interesting topic. I've had good experiences with using immutable data structures for games in the past (ClojureScript). Would you mind sharing some details of your benchmarking @mattstyles? I didn't do anything very fancy with lots of graphics, though.

I think it *should* be possible to apply something like redux to keep track of the state. My advice is, you don't subscribe rendering to every game state change directly - as was done in the fiddle -  but separate state changes from drawing and draw periodically with animation frames. Maybe also keep the sheer number of state changes low by grouping smaller changes per dispatch together. Immutability plus js being single-threaded will help you, as you'll always have a valid snapshot when rendering (or dispatching a bigger change). You might even have mutable elements like particle effects and physics on their own, as you only need to push them a time-tick event; so they won't trigger dispatches either; although I can imagine that could cause some major headache from the FP point of view...

Link to comment
Share on other sites

@waechtertroll nothing very comprehensive re benchmarking as it was very much only a POC and I only needed an indicative idea of perf immutable vs mutable data. My tests comprised of a fairly large list of entities and having one of those entities moving so each tick updated its position and then rendered. This meant that each tick I had to search through the array for the entity I wanted, update its position, and return a new array, then render. I did this with immutable.js and then just with a plain JS array and objects, so this also involved some changes to the reducer to handle the difference between an immutable.js data structure and a plain one (its quite possibly my FPS drop was due to borking this implementation but I tried to keep it simple enough to minimise this risk).

The immutable.js version ran at less than 50% the FPS of the plain object one and this issue only grew worse as I played with the number of elements in the array. Moving all elements vs moving one didn't change much, as you'd expect.

I'd guess that things like ClojureScript and Elm enforce immutability in their data structures at the source level but then just use fairly plain objects when it gets into JS-land, whereas immutable.js would have to do a load more work to enforce immutability whilst the app is running i.e. I'm guessing ClojureScript throws an error at compile time (build time) if you're trying to mutate an object, whereas immutable.js would do this at runtime and all those checks are always going to be expensive at run time. I am only guessing here though.

I've used redux (or a redux-like lib) and react for lots of games, but none of these games are spamming updates every tick, for things like animation I've tended towards using stateful components to handle those, moving them out of the central state object, which is pretty akin to your last couple of sentences. This has worked really well, but, yeah, could be a major headache for many types of games (none of the ones I have toyed around creating have had the same issues as your typical action-style game).

Link to comment
Share on other sites

  • 11 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...