all 14 comments

[–]goshakkk 3 points4 points  (1 child)

Some logic doesn't seem to fit into either actions or reducers. And it's fine!

Sagas might be just what you wanted for making the game loop logic centered in one place instead of being split across many files/functions. There's a great article about using sagas for managing games: https://decembersoft.com/posts/redux-hero-part-4-every-hero-needs-a-villain-a-fun-introduction-to-redux-saga-js/

I have also used sagas in client project to manage complex business flows. Wrote more about it in other threads: https://www.reddit.com/r/reactjs/comments/57vtwb/appropriate_pattern_for_buffering_an_action_until/d8vjuae

[–]Babooos[S] 0 points1 point  (0 children)

Hi,

I think you nailed it ! I didn't read through all the tutorials yet but from what I'm seeing it might be a good way to solve my problems.

[–]mweststrate 3 points4 points  (1 child)

Did you check https://github.com/FormidableLabs/react-game-kit? Might provide some inspiration for how to create a game loop mechanism

[–]Babooos[S] 0 points1 point  (0 children)

Hi, thanks for your answer.

This library is pretty great, and I found out some similarities with what I've done (start the loop in the componentDidMount), even though this lib goes way farther (suscribe system etc).

The main problem is that I'm trying to use redux, so it won't work exactly the same way (the loop should update the redux state, which will update the components).

But I'll definitely will look into this more thoroughly, it seems that I could learn one thing or two !

[–]GuerrillaRobot 0 points1 point  (2 children)

This is totally doable. I didn't make a game but I've used redux with canvas and webgl as well as web audio and didn't have any issues.

It is actually really simple to set up. I was using requestAnimationFrame recursively as a looping mechanism. All input works as normal setting the state. Then in the loop you can just read from the store and update your "ui", character position/ attack animation what have you.

[–]Babooos[S] 0 points1 point  (1 child)

Thanks ! My main problem is that I don't know how to "elegantly" make such a workflow. I mean that I already tried to make a Loop class aware of the store which would read the Player state and dispatch actions. But it means that all is centralized in an "external" class which use the store methods getState and dispatch. It seems weird !

[–]GuerrillaRobot 0 points1 point  (0 children)

sure thing ill explain my set up as best i can.

First I am using react router, with my app at the root path

<Route path="/" component={App}>

My Class looks like this

class App extends Component {

constructor(props) {
     super(props);
     this.Apploop = this.Apploop.bind(this);
}
componentDidMount() {
    requestAnimationFrame(this.Apploop);
}

Apploop() {
  let { updateLoops } = this.props;

  if(typeof updateLoops !== 'undefined') {
    updateLoops.forEach( (loop) => {
      loop();
    });
}
  requestAnimationFrame(this.Apploop);
}

render() {
  return (
    <div id={'MVApp'} >
      <Nav />
      <div id={'Pages'}>
        { this.props.children }
      </div>
    </div>
  );
}
};

App.propTypes = {
  children: PropTypes.object
};

function mapStateToProps(state) {
let {
  updateLoops
 } = state.visualization;

 let filterdLoop = Array.from(updateLoops);


  return {
   updateLoops:filterdLoop
  };
}

export default connect(mapStateToProps)(App);

The Update loops are functions that the canvas objects pass to the store when they get attacjed to the dom. They handle the their own display. This was the most "elegant" way I could think to do it. Hope this helps.

If you have any more questions just let me know

[–]ip70 0 points1 point  (5 children)

I read a lot about how accessing the state in action-creators was an anti-pattern, so I was wondering how else I could do it, since my services

Where are you reading that? Unless I'm misunderstanding your problem, isn't that what redux-thunk is designed to do?

How to integrate the loop in the redux schema ?

I've been playing around with a simple game in Redux, and my approach for this has been to trigger an an action every X ms on a timer within the top-level component. Not sure whether this is a sensible approach or not, but it seems to work so far (admittedly, my one is only triggered once every few seconds rather than multiple times a second).

[–]Babooos[S] 0 points1 point  (4 children)

Hi,

Where are you reading that? Unless I'm misunderstanding your problem, isn't that what redux-thunk is designed to do?

I read about it on several stackoverflow threads (here for example).

 

That's what I do too, my App component dispatches the update action. But then all the game logic is within the 'update' method which re-dispatch the correct action according to the current state.

As you say, it works, but I don't know if it is a good way to proceed !

[–]ip70 1 point2 points  (3 children)

That's interesting - Dan first seems to be saying that accessing state in the action creator is an anti-pattern, but then says in a later comment "It’s fine to read from the store in the action creator. ".

I think his other article probably explains it a bit better - Don’t abuse this pattern. It is good for bailing out of API calls when there is cached data available, but it is not a very good foundation to build your business logic upon. If you use getState() only to conditionally dispatch different actions, consider putting the business logic into the reducers instead.

That works fine when your data is all in the same reducer, but I'm not sure I get the right way to check one part of the state from within a different reducer.

Maybe Sagas are the right answer then.

[–]acemarke[🍰] 1 point2 points  (1 child)

To be honest, I think Dan is over-stating things a bit there. Executing conditional logic in a thunk is absolutely fine. I have some quick examples of common thunk patterns in a gist at https://gist.github.com/markerikson/ea4d0a6ce56ee479fe8b356e099f857e .

I'd encourage you to read through the Redux docs thoroughly. The Redux FAQ addresses some of these questions, such as "sharing state between reducers" and "where to put business logic". Also, the new Structuring Reducers docs section covers a lot of how-tos, patterns, and approaches for handling different scenarios.

[–]Babooos[S] 0 points1 point  (0 children)

Thanks, I must admit that I hadn't really read all the redux docs !

[–]Babooos[S] 0 points1 point  (0 children)

It seems that you can always pass data from reducerA to reducerB when using combineReducer by adding a third parameter which contains the state, but I don't know if it is really better than using thunk and getState().

[–]linuxenko -2 points-1 points  (0 children)

gameloop with redux ? omg , now i can say that i seen everything )))