I eventually solved the problem I outlined in my previous post, though I’m still not fully satisfied with it. I wanted a really kind of random ordering to my questions but because MySQL returns them in ascending primary key order (which, in this case, is the question_id), there’s no good way to consistently serve them up in the same random order. So, fine, okay. The questions are still randomly selected, more or less, and then displayed in order according to question_id. Fine. I can live with that, even if I don’t love it.

So I got that working, uh, April … 19? So like, the day after my last entry. It wasn’t particularly hard so much as it was annoying. And it’s still somewhat annoying. But I’ll live.

What hung me up for a full week was what came next:

What to reward the player with after they pass the challenge?

For real, I was stumped.

I have no idea
Sabrina the Teenage Witch doesn’t know, why should I?

So I thought about it. A lot. And I watched a lot of YouTube videos of game designers talking about things. They talked about being generous, they talked about player psychology, they talked about extrinsic and intrinsic motivation…

I finally did a real brainstorm. Like an honest-to-god, old-school brainstorm, the likes of which I rarely have done outside of elementary school, where I just wrote down everything I could think of on various pieces of paper. And this was the result.

The contents of my brain.

Then, as if things weren’t tough enough, I also wanted a graduated reward system.

Let’s be honest, I’m asking people to answer 10 questions correctly in 60 seconds — including spelling. Even if you’re picking a category you’re super familiar with, you may not get all ten. In my testing, I usually got around 8/10 for most categories and I wrote the damn questions.

So I wanted to balance for the likelihood that people who pass the challenge get 6-8 questions right and if they get 9 or even 10, they should get something awesome.

Here’s how that turned out.

5 questions or fewer correct: BZZT! Sorry, please try again tomorrow.

6 questions correct:

  • Visit from the Wise Water Spirit to encourage them
  • Replenishment of energy
  • The ability to continue down the river

7 or 8 questions correct:

  • All of the above, plus…
  • Moving a distance down the river, courtesy of the Wise Water Spirit

9 questions correct:

  • All of the above, plus…
  • Three Fire Opals. I won’t go into what these do specifically, but they’ll be a form of currency.

10 questions correct:

  • All of the above, plus…
  • A companion for your travels!

Listen, I was heavily influenced by the BBS games of my youth, okay? When I thought about my favourite moments from Legend of the Red Dragon, I thought about getting a horse that would extend your day. So I decided to incorporate a (temporary) companion for your travels if you manage to get ten questions right. The companion is a large turtle (tortoise? I’m calling it a turtle.) and will make your journey down the river more expeditious, shall we say. That said, at maintenance, the turtle can decide to leave you and go on his merry way. There will be a maximum number of days the turtle will accompany you, too.

The most fun bit is that, back in Grade 8, me and three of the girls in my class at school decided to get turtles and we’d take care of them in the school’s bio lab. My friend, V, named hers Tiny, I named mine Wriggles, another girl, J, named hers Hugo, and then F brought one of her turtles from home whose name was Ribbit.

There’s a very long story here in which J’s friend (and my future best friend, but I definitely didn’t like her at first), nearly killed all the turtles by mistake, but, frankly, that’s a story for another time…

Anyway, I decided that if I was adding a turtle, by golly, that turtle will have a name and there’s a random chance that its name will be either Tiny, Wriggles, Hugo or Ribbit. I’m ridiculously pleased by this. Not only am I adding something cool, but it’s meaningful to me personally because of the names and because of the concept coming from the coolest event in that old BBS game.

So I spent a lot of time modifying the database to ensure that it could handle all the things I needed to add — turtle stuff, Fire Opal stuff… Then, I had to start writing functions to ensure that the database changes happen based on the score you get. So I got that bit done tonight and then I got to start writing the encounter with the Wise Water Spirit, depending on your score, and did that tonight, too.

My code works, my text works (I used switch statements both for the code and for the text) and really, all that’s left is:

  • make sure you can’t do the rapids again once you’ve done them
  • add tasks to maintenance, such as turtle stuff
  • make sure I offer the right options to players based on them passing or failing the challenge
  • make sure I edit things to incorporate the possibility of a turtle and/or Fire Opals

Once I do all that (mayyyyybe on the weekend???), then I’ll be in good shape to actually launch the challenge. It’s gonna take a couple of hours to launch, for sure, because I have a lot of things to do to the database. Everything from adding category ID numbers (and adding 100 questions about Survivor!) to all the challenge-related tables. So much to do there, so there will certainly be some maintenance first, but we’re definitely getting close to the launch of the first challenge.

I suppose I should really start thinking about the second challenge… Oh boy.

Anyway, I should get some sleep. Hope you and yours are staying safe during this time!

The Rapids are Going Slowly

By which I mean my work on Challenge 1: The Rapids, is going very slowly. The rapids are, by nature, quite quick…

So the goal here is to present players with a challenge that they must pass in order to continue on their way down the river. My challenge of choice is for them to pick one of five categories, which are randomly selected. Then, once they pick a category they want, they get ten randomly selected questions from that category.

In theory, all of this works beautifully.

It’s when you want to prevent cheating that things go to hell.

If I could count on no one hitting the back button or no one reloading, then things would be fine. But because I’m not in an app, I can’t control people’s actions, so I have to account for the possibility of rampant cheating.

So I’m locking the category choices. Once shown to the user, they get saved to the database. And once you choose one of them, that’s also saved. And then the ten questions that get randomly selected? Also saved. (And then, because I’m not an utter monster, they will all get wiped at maintenance if you fail the challenge, so that if you had a bad day, you can come back fresh the next day. And this also prevents cheating because you can’t then go look up the answer.)

I’m taking the ten question IDs and storing them, then retrieving them.

The problem is that I’m then retrieving the question details (question, answer, alt answer, etc) from those IDs and they are all coming back in ascending numerical order. This means that when you first look at the questions, they’re in the order in which they were generated and passed back to that page. So, basically:

CHALLENGE PAGE: “Yo, Function, get me ten questions from Star Trek: The Next Generation!”
FUNCTION: “You got it! Okay, get all the questions from Star Trek: The Next Generation. Then, shuffle them. Then, slice off the last ten of them. Then shuffle them again, for funsies. Yo! Challenge page! Coming back at you!”
CHALLENGE PAGE: “Thanks, Function!”

So all of that works. But if these values are locked, this is what happens:

CHALLENGE PAGE: “Yo, Function! Get me the the saved question IDs for this user!”
FUNCTION: “Sure thing! Here you go, there’s ten of them!”
CHALLENGE PAGE: “Awesome, thanks! Now, can you get me the questions for these ten question IDs?”
FUNCTION: “Yep! One sec! Okay, get me all the data for any question matching these ten question IDs! Great. Yo, Challenge Page! Here we go!”
CHALLENGE PAGE: “Thanks! … wait. This… this isn’t the same order, is it?”
FUNCTION: “You never said it had to be the same order.”
CHALLENGE PAGE: “That’s implied, jerk.”
FUNCTION: “IS IT CODED THAT WAY? NO? Then just be glad you’re getting that info, buddy.”
CHALLENGE PAGE: “COME ON, seriously?!”

Pulling the question data based on the submitted question IDs pulls the questions in ascending numerical order by question ID. Even if the question IDs weren’t passed along in that order.

So this leaves me with mismatched questions and answers on any potential reload or revisit of the page. Again, if they don’t try to reload or change categories or questions, everything is fine, but if they do that and then attempt to come back to the challenge page? They can’t possibly win because everything is out of order.

I have three potential solutions and I hate them all.

  1. Store the question ID AND the question itself when locking the questions. Why do I hate this? Because it’s lazy and yet still a lot of work.
  2. When locking the question data, order things in ascending numerical order (and also define that precisely when retrieving the data). I hate this because I don’t want my questions in ascending numerical order. I suppose I could do that and then shuffle things. I guess.
  3. Make sure I’m retrieving the question ID with the question data and redo the question ID variables to add to the form data. This is similar to 2 but involves marginally less rewriting of what I already have there, though still would require me to reshuffle things.

On the bright side, I started out playing with my code tonight not knowing what the problem was and now I’ve not only identified it, but I know why it’s happening (vaguely — basically, if you ever pull data from a database and you don’t order it, you’re kind of asking for randomness) and I also have three viable (if unlikable) solutions.

So there’s that.

Once I’ve done that, I then need to calculate/check the answers. So the plan is that if you get 0 through 5 answers correct, you fail and you get to try again the next day, with new category choices and new questions, as previously noted.

If you get six right, you pass. But then I also want to add rewards for getting 7, 8, 9 or 10 questions right.

My game design “skills”, such as they are, basically do not care about the level of my PHP skills. Like, not in the slightest. As such, my PHP skills are having trouble keeping up with my imagination. Every time I want to add something “cool”, part of me (the part that has to figure out the logic to it for coding purposes) yells at my imagination to say SURE YEAH WE NEED A TON MORE COMPLEXITY IN THIS GAME RIGHT NOW, WELL-DONE, JULIE! It’s not fun to war against your creative side and your logical side, but I guess this is my life, now.

What else is my life? Well, there’s kind of a global pandemic sweeping across the earth. I have not left my apartment building in nearly three weeks, but I also work from home, so it’s mostly business as usual here, interestingly. My greatest worries are running out of milk and not being able to run to the corner store and also not being able to book a grocery delivery before my milk runs out.

Work is busy — like Black Friday/Cyber Monday levels of busy — so I haven’t had a ton of time to code, despite the pandemic. All kinds of people are like “PICK UP A NEW SKILL” and I’m like “can I just have a nap, please?”. I’m excessively thankful that I’m not needing to worry about my next paycheque or being able to afford milk and other groceries, so I definitely can’t complain about being busy. I mean, I can, but it makes me sound like an ungrateful wretch when I am, in fact, eternally grateful to not have to worry about things on that front.

All of this to say, I have no idea when the beta of my game will be out, but I hope hope hope 0.4.0a (which will have Challenge 1: The Rapids in it) will be out by the second week of May. Target is roundabout May 10. Maybe. Hopefully. We’ll see. And that same weekend, I’ll revise my own targets for deadlines and stuff.

And now, bed, and more coding tomorrow. I hope you and yours are well during this troubling time, and please don’t feel like you have to learn a language or pick up an instrument. Some days, all we can do is exist and, frankly, that’s okay.