Fork me on GitHub
#clojure-gamedev
<
2021-08-05
>
Noah Bogart05:08:45

I’m playing with a rewrite of my stateful game to make it a purely functional one and I’m struggling with feeling like I always have to start from the outermost layer to do any changes. For example, in the stateful engine, I have a queue of “steps” that acts as a “last in first out” stack. Each step is a volatile map and has a :complete? flag, so I can pass the the step into a given function and call (vswap! step assoc :complete? true) when it’s time to pop the step from the queue in the next iteration

Noah Bogart05:08:27

However, in the pure version, I pass both the game state and the step into the function and then have to juggle the updating the step inside of the game state and return state and then outside of that function, I have to dive into the state to find the step and check if it is :complete?. Means I’m constantly performing additional work to look up and update variables that would be a simple mutation in, say, javascript

Noah Bogart05:08:13

This relates to the place of friction where in javascript I can do something like this.game = game and then in my class I just have access to the game object and don’t have to be going from game into X into Y to perform my function.

Noah Bogart05:08:23

Maybe I’m just not structuring my data correctly lol

Noah Bogart05:08:32

How do y’all handle these issues?

Noah Bogart13:08:19

separate but related: in javascript, i can say something like:

const step = this.game.getCurrentStep();
if (!step.continue()) {
    this.game.dropCurrentStep();
}
and because step has a reference to this.game, i can have step mutate this.game while also returning a boolean saying whether it succeeded or not (for instance, if the step requires player input, return false).

Noah Bogart13:08:42

what’s best practice for doing the same in clojure? do I return a tuple (`[state success?]`) or set a flag on the game state or is there some other practice I haven’t thought of

Noah Bogart13:08:30

the other idea i had was to write a function called current-step-complete? which checks to see if the step itself is marked as complete

Noah Bogart14:08:32

oh hell yeah, that’s great. thank you, i’ll read it over!

pithyless14:08:56

I'm avoiding giving more concrete advice, because I've struggled myself with different ways of modeling control flow (outside of gamedev) and while all the examples given have their pros/cons, I don't think any one has flat out won. :)

👍 3
Noah Bogart14:08:04

hah you’re welcome to share how you do it, i promise to not blame you if i use your method and then tear my hair out later

pithyless14:08:51

I've basically tried all of them XD, aside from the missionary approach which I'm still trying to fully grok, so yeah... the more you know, the less you really know.

Noah Bogart14:08:09

haha for real. i’m also struggling with the “if i want to rewrite this, i have to do it right” (which leads to not getting anything done) whereas the stateful engine already exists and works well enough that i can continue to hack on it. Joel (joelonsoftware) has talked at length about this, so i’ve resisted so far, but the statefulness of this thing is so deep there’s p much no way for me to gracefully transition to a more pure version