Hacker News new | past | comments | ask | show | jobs | submit login

Can anyone explain why it is:

  var newState =
      drawManuel(
      drawBackground(
      processInput(state)));
and not:

  var newState = processInput(state);
  drawManuel(newState);
  drawBackground(newState);
When I read the first my intuition is that application of drawManual and drawBackground is important for the value of newState. The second one makes it clear that newState does not depend on drawManual (or drawBackground).

It would also make the first bug more easier to spot:

  var newState = handleCollisions(state)
  newState = processInput(newState)
  drawBackground(newState)
  drawManuel(newState)
The problem with the order of handleCollisions and processInput is now more visible because now it is obvious that just those two change the state - so we concentrate on them. And there are less parentheses.

(Initially I used another variable here to make it more functional - but then I decided this is useless - we are still in an imperative language)

I have a feeling that the author have some strange idea about what functional means. I stopped reading after this part.




Indeed.

If the state is immutable, then drawing (which shouldn't modify the state) can be, conceptually, done in parallel. While in practice this is unlikely to actually happen, your code snippet reflects this conceptual property better and is therefore, in my opinion, much easier to read: I know where the state is modified and where it is merely read. I also know that drawManuel cannot mess with drawBackgrounds data and vice-versa.


It's not only conceptual difference.

It is a good practice to decouple state manipulation from drawing (even to do drawing in different thread, and with different frequency, than state manipulation).

This allows for computers with wastly different processing power to run the same simulation in sync, while the more powerful computer can draw 10 times as many intermediate frames.

Alternatives are variable step length (makes it hard to write deterministic simulation), or fixed step length and capping framerate to it (sacrifices animation quality on better computers for easy implementation).

EDIT: also - the ordering between drawManuel and drawBackground probably do matter, and there's probably some state related to drawing (like animation frame numbers etc) so there should be separate screenState that reflects that.

  state = processInput(state);
  screenState = drawBackground(state, screenState);
  screenState = drawManuel(state, screenState);


I meant conceptually because of what you say in your edit. As far as your state variable is concerned, they are parallel. But as you point out, there is implicit screen state (either in the code or in the GPU or wherever) and when updating that, order certainly does matter.

If each draw* function drew to a temp buffer to be composited later, then they could be parallel. But none of this is really relevant to the game-state discussion, though, since we were both talking about (and agreeing, I think) that decoupling is good regardless. Even if just to aid reasoning.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: