Mobile responsiveness work

So the thing about making things mobile responsive is that it’s a user interface and user experience issue. It’s not a game issue. It’s not something I can fix by tweaking the PHP function, it’s not something I can fix by rewriting some logic.

What is it? It’s finicky, that’s what it is.

Obviously, I should have done a mobile-first design. I always tell myself I’ll just throw the website together right quick and then if I feel like it, I’ll go back and make the site mobile responsive. And basically I never do that. Although I did follow that idea when I put together the latest version of juliemartin.org, but that was yonks ago and it’s also not a slick-looking site. Look, website design has never been my forte. I can do it, I can do all the things, but it’s a bit tedious and it’s a bit boring for me.

It’s funny how I’ve changed over the years. Literally 20 years ago, there was nothing I loved more than playing with website design and using CSS and little snippets of JavaScript to change the look of my websites. And now it’s like… that’s not challenging enough. It’s just finicky enough to annoy me to mean I don’t really have mastery over it and that it’s not easy, but it’s not like it’s difficult to get things to look the way I want them to. (Note: it is still challenging to get things to look pretty, but that’s a whole other failing of mine.)

I’ve set next Saturday as the tentative date when I’ll launch patch 0.3.0a, which would include mobile responsiveness. I started tinkering with it around 3:30am this morning, like 12 hours ago, gave it an hour and was relatively satisfied with what I’d accomplished. But I’m not looking forward to the rest of the work. The <div>s related to the questions being correct or incorrect, or getting a fish or not, or finding food or not, all of those are annoyingly tricky as it is, so I do not relish the thought of trying to make them responsive. I guess we’ll see how finicky it is, eh?

Following up on my previous entry, I also started trying to code a 1% chance of a fun and random thing that happens, but I’m stuck, which is infuriating. Errors crop up everywhere! But why? I may have to shelve that ’till 0.3.1a, along with another 100 questions or so.

Finally, I wrote up an article at DEV about my experiences while writing the game and how you should just do the thing. I didn’t have everything planned out when I started and I still don’t know a ton of things and yet… here I am. Doing the thing. Writing the game. Learning things.

And on that note, I should probably go back to my CSS…

Patch 0.2.0a is out!

My dudes, I did it. I merged and deployed Patch 0.2.0a of River of Kurn exactly when I intended to! I am very psyched.

Patch notes are here at the forum: https://forum.riverofkurn.com/discussion/13/river-of-kurn-patch-notes-patch-0-2-0a#latest

Essentially, I rocked it. I:

  • built my question importer tool which works beautifully
  • fixed expiring sessions by modifying my php.ini to add session.gc_maxlifetime = 3600 and then adding some stuff to my pages that set the original lifetime of the session to 3600 seconds (1 hour) and then some math on each other page to determine if it’s been more than an hour since the session was last active. If so, it redirects you to a logged out page where it explains what happened. Very proud of this one!
  • refactored my change password function so that I could then implement a forgot password function. Which, you know, I had forgotten to implement in the first place! Whoopsiedoodle.

I did a couple of other things, which also included adding 100 Star Wars questions (no spoilers for The Rise of Skywalker, I promise!) and 100 questions on Human Biology.

I also posted to the RiverOfKurn Twitter account:

@RiverOfKurn

And I sent out the first issue of ROK News, the River of Kurn newsletter! You can see it on the web here.

Whew. I need a nap. (It, uh, may be 5:22am and I may not have slept yet…)

Anyway, another thing I’m doing, because I have no experience whatsoever in game design, is taking Will Wright’s Game Design and Theory course at Masterclass. Check out the preview here:

https://www.masterclass.com/classes/will-wright-teaches-game-design-and-theory

Will Wright, in case you’re unaware, is responsible for the Sim-type games. SimCity, SimAnt, SimCity 2000, The Sims, Spore. The list goes on. I have, legitimately, spent hours, perhaps weeks or months of my life playing this man’s games. Certainly, he knows stuff that I don’t.

I decided to go with the “all-access” pricing, because $120 CAD for a single class versus $240 CAD for a year of access to every single class was just a no-brainer. They have Shonda Rhimes, Aaron Sorkin, Garry Kasparov, Malcolm Gladwell, David Sedaris, Neil Gaiman, Margaret Atwood and so many more that I’d love to learn from, particularly when it comes to writing. But it was Will Wright teaching a class that got me to pony up the cash.

This isn’t sponsored in any way, I promise. I am just blown away with how detailed and what high quality the class is. It’s amazing. There are workbooks! Exercises! Homework! (I admit, I have not delved deeply into the homework side of it yet.) But just the lectures alone are amazing. My brain is teeming with ideas on how to refine my game just from the perspective of play. Like, what would make things more engaging for the players? What would allow them to feel more in control of their time on the river? Super exciting to be feeling so creative right now, let me tell you.

One of the things I’m thinking of adding is a daily game with your guide on the river, Dorene. If you can answer her question correctly (or win her game or something like that), you have a chance to win a reward of your choice, with one of the rewards being a surprise.

That surprise can be good or, because Dorene is a water nymph and is mischievious, it could be bad. I’ve already come up with the different options with 10% chance for two of the best things and 25% chance for the third-best thing, with a combined 55% chance for the two bad things. I actually cackled while writing it all down.

Then, thinking about random happenstances made me remember some of the Legend of the Red Dragon random events. I would love it when I came across a horse, for example, or got refreshed (max HP) or any number of little things like that, so I’m going to add in at least one of those, too — probably a 1% chance to occur when you’re foraging for food and have under a certain amount of energy.

Of course, the big question is “when”. hahaha, yeah, I have a lot of work to do already, so we’ll see where I can put in some of this more compelling gameplay stuff. Some bits would be easy to implement, some would be harder. I also deliberately wanted to be vague about how the game works, to let people figure it out for themselves, the way I had to when I was a kid playing Trade Wars 2002 and Legend of the Red Dragon and Sky Mountain. I can always add information or warnings or clarifications or notices to the game, but I can’t remove the information once they’ve taken it in, which would ruin some of the fun of discovering things.

As Will Wright puts it, it’s about finding the state of flow. If it’s too hard or unnecessarily punishing or complicated, then people will never gain interest in it. If it’s too easy or too simple or too boring, people will tire of it easily because they’ll master it quickly. (Think of tic-tac-toe — adults have no interest in playing because we’ve mastered it, but a 5yo would love it. Note to self: play tic-tac-toe with eldest nephew next you see him.)

The ideal state is the state of flow, where it’s hard enough but doesn’t punish you unnecessarily. Humour helps and so does the feedback you receive when you fail. After all, so much of playing a game is failure and learning how to do things better.

When I played World of Warcraft quite seriously, my favourite thing to do was to raid. I loved being in a group of 40 or 25 people and taking down a difficult encounter. (But honestly, I never again want to hear Sindragosa threaten me as my pathetic magic betrays me.) But I didn’t mind wiping over and over again, as long as we gained more information on the encounter. Like “oh my god why did we all just blow up???”, figure it out, fix the problem, then don’t get blown up and progress in the fight. Except then something else would occur, inevitably, hahaha.

One of my toughest learning encounters in World of Warcraft was the 25-man Heroic Blackthorn, in the Dragon Soul raid. The entire encounter takes place on an airship and the first phase is brutal. The second phase is worse. But the worst part for us was everyone dying in the first 30 seconds of the encounter. Something would be missed and we’d take damage. Or someone wouldn’t hug their buddy and the buddy would die. Or someone fell off the airship. It was maddening because we couldn’t progress far enough to figure out what the hell all the different problems were. (There were three separate issues that we had to iron out, as it happens.) We eventually got through it and the footage of us all dying constantly was pretty hilarious, in retrospect. At the time, though, that felt punishing. It felt hard for no reason. It made all of us want to give up in a way I hadn’t felt for a long time. (Did I mention the airship was on fire for the majority of the fight and the fire was buggy as all get out? Lord.)

Anyway that’s kind of where I think my game is at right now. The questions are a little hard and players don’t have quite enough agency. So on one hand, my game is a little too punishing (for no reason) and on the other, it’s kind of simple and boring.

It’s a very interesting problem to have and it’s a fascinating balance to want to strike.

All right, it’s late. I need to sleep. Back to work on Monday after 16 days off in a row. Hopefully I’ll still be able to work regularly on the game and get mobile responsiveness done for January 25…

Progression and Regression

Well, I’m kind of surprised it hasn’t been longer than nearly four months since I sat down to write here! Go me. That feels like progress of some sort. Maybe.

And speaking of progress, there has been very little progress on River of Kurn of late. This is for a number of reasons. First, November is National Novel Writing Month, in which I participate annually. Once again, I managed to finish 50,000 words of a novel in the 30 days of November! And that meant zero coding, because I also helped plan my own high-school reunion (never you mind just how many years we celebrated), plus work was wild. December arrived and work was even wilder, plus those pesky “holiday” things ate up time in terms of thinking, planning, shopping and preparing.

I did make some attempts to code in October, but failed miserably because I got stuck on a totally optional thing. You see, I wanted to build myself a tool to add more questions to the game easily. Of course, adding them isn’t that hard in the first place, but it was infuriating to add the questions to the questions table, then add in rows for those questions in the statistics tables for the blue game as well as the green game. And if there was an issue importing, I’d have to dump the numbers out of the question table and reassign numbers to the questions before attempting again, or I’d go from, say, question 1331 to 1381.

So I was stuck. I’d never coded something to import from a file before. I can do database dumps and backups, but I had never tried to bring data into the database programmatically before. So I got stuck and then I got busy.

I’ve been off work for a full six days now (and have another 10 to go!) and the holidays are now over for me, so when I woke up at 4am today for no apparent reason, I decided to reorganize my plans for my game and I decided to tackle this import issue.

Four hours of testing, testing, testing and testing some more later, I now have an import tool built into the admin section on my game’s website. I mean, it’s not live yet, I’ll do that when I finish adding another 100 questions (about Star Wars this time) and add a couple of other things to the game. I’m going to rework an introduction question, add text to explain the validation link will be sent to the email address you provide, etc. Anyway. I am super jazzed about this, because it makes adding questions so much easier. I literally browse for the CSV file on my computer, upload it and it does everything for me. Victory! (Another victory: managed to renew the SSL cert for the game site and am feeling very proud about this because it was NOT simple.)

In not so great news, my EVGA GTX 1080 Ti video card died on me just over two weeks ago. It lived about 16 months. I saw my holiday plans of gaming and coding vanish before my eyes. While I could always use the integrated graphics to at least use a monitor and actually use my computer, that’s no way to game. I also have a pretty crappy video card that’s been sitting in my old computer, so that’s what’s in my new computer now. I can’t do much in the way of gaming, but I can power a second monitor, so I can at least get some coding done! (As evidenced by my building my import tool.) The other piece of good news is that I was under my manufacturer’s warranty, so I got approved for an RMA (return merchandise authorization) to send EVGA my card and they’ll send me another one. The bad news there is that even though I paid for 1-day shipping, they only attempted delivery on Tuesday, December 24 (and not Monday, December 23), which means that EVGA was closed. Obviously, they were closed on the 25th as well.

Thankfully, the delivery was accepted on the 26th. But now we’re probably looking at them shipping a replacement next week. And, well, their site says “shipping for online/RMA orders will stop completely on Tuesday, 12/31/2019 at 2pm Pacific Time” and will resume the following Tuesday. So if they don’t ship it out today (Friday) or Monday, I probably won’t get my video card until, uh, mid-late January. Even if they ship it today or Monday, I probably won’t get it before the end of my vacation time. This is the universe’s way to tell me to catch up on TV and coding, I guess.

So that brings me to my plans for 2020 for River of Kurn:

  • 0.2.0 release scheduled for January 4, consisting of: 200+ more questions, the tool I created, other bits and bobs and hopefully a way to keep sessions active or allow them to fail gracefully.
  • 0.3.0 release scheduled for January 25, consisting of making things work properly on mobile.
  • Beta release scheduled for February 29, consisting of 37 separate issues… hahaha oh boy.
  • Full release scheduled for July 1, consisting of an additional 15 issues.

And, of course, since adding questions are so much easier now, I’m hoping to add more questions much more regularly.

So that’s what’s up with me. Hoping to post more frequently here, too!

100daysofcode done, Alpha launched!

Well, it took me, uh, 352 days from September 4, 2018, to August 22, 2019, to complete the 100daysofcode challenge, but I did it. 100 days where I worked on my game. Granted, nowhere near the 100 days in a row, but it was really useful to keep logging things and keep track of what I was doing and where I was going. Plus, reading about my failures and/or challenges now is just funny.

This log entry might be one of my favourites. I am so frustrated, you can practically hear the fatigue in my text.

Anyway, in my last blog post, I figured 62ish hours of work to get things done for Labour Day. Well, my alpha launched at 2am the morning after Labour Day (so close enough), and it was close to 130 hours of work, from June 30-September 2. Note to self: double all estimated hours going forward.

Throughout the last year and more, I have learned a great deal about PHP, MySQL, Amazon Web Services, Docker, Composer, sessions, CSVs, importing CSVs, SSL certificates… A lot of stuff. And now that the game is launched, the adventure is kind of only starting. I’m going to have data! Actual, real, user data!

I also desperately need a LOT more questions, so that’ll be my focus for the next couple of weeks. Why do I need a LOT more questions? Well, the game is currently, shall we say, heavily weighted towards the nerds and geeks of the world. There are 300 Star Trek questions. 100 Red Dwarf questions. Over 100 Doctor Who questions. 100 Back to the Future questions. It’s, uh, not great for a well-rounded trivia experience, so when I looked at the real-time “Correctly-answered questions percentage” at some point today, it was 38%! Like, what?!? Sure, even I don’t get 100%, but I get in the mid-70s, typically. Granted, I wrote the vast majority of the questions, so I do have an unfair advantage, but even taking that into consideration, I thought for sure we’d be looking at closer to 50%.

Well, my dad signed up and played and, because we have a small sample size and because it seems he got a bunch about the periodic table, he brought the overall correct question percentage up to 42% and change. But, the wonderful thing is that I can call up all these stats and find out which questions are hard. Or too hard. Or too easy. Like, okay, I have a question about a hockey player named Blake Geoffrion, who’s descended from not one, but two famous Montreal Canadiens players. Sure. That’s hard. I don’t expect a lot of people to get that.

Should a non-Canadian know the capital of our Nunavut territory? Well, probably not.

But you’d think most people would know Brandon Routh played Superman in Superman Returns, no? Well, still very geeky, I guess.

Anyway, I’m watching the data and will be writing many more questions that are less nerdy in scope. The goal is to get like 5-6000 questions total for the main launch. Then the Star Trek questions would only be five percent of the total questions instead of a whopping 25% or so right now.

That said, props to whoever knew Deanna Troi’s mother’s name, whoever knew who played the Seventh Doctor and whoever knew what game Queeg challenged Holly to play!

All right. Bedtime now. Go play my game!

https://www.riverofkurn.com/

2019 is halfway over??

It’s officially the last day of June of 2019 and I haven’t posted here since December 1, 2018.

Whoopsiedoodle.

It’s not to say I haven’t coded over the last seven months, but let’s just say that I have not been coding regularly. I kind of did, for a bit in February and March, but then barely at all in April or May, and not at all in January.

Long story short, the company I work at does an annual company-wide trip, since we’re a distributed team, and I learned… in early January, I think, that we were going to Scotland. Well, genealogy is a bit of a hobby of mine and I am 3/8 Scottish, with one of my dad’s paternal grandparents being Scottish and both of my dad’s maternal grandparents being Scottish. Now, when I’d first been to Scotland with my dad, we went to Cluny, Aberdeenshire, which is where his paternal grandmother is from. So I went all out on the family research in January on my dad’s maternal grandparents, who were both born and raised in Edinburgh before coming to Canada. I don’t want to discuss how much money I spent at ScotlandsPeople! By the time I went to Scotland, I went from knowing just the names of my great-grandparents to having identified all sixteen (or close to it) of my 4x-great-grandparents on that side of the family, mostly including dates of birth, dates of death, and many marriage dates.

Not only that, I had compiled a list of almost 50 addresses where various family members had lived in and around Edinburgh.

Plus, I had nine gravesites spread out across four separate cemeteries to visit, none of which were marked, except the one in freaking Kelso, down in the Borders area. How could I visit Scotland and not visit the one graveyard that had ancestors named on it? Answer, I couldn’t.

Family grave in Kelso
Grave of my 4x-great-grandparents.
The River Tweed
From the outskirts of Kelso, the River Tweed.
The River Tweed
The River Tweed on the outskirts of Kelso.

And here’s one of my favourite pictures from Edinburgh:

At my great-grandfather's.
This is where my great-great-grandfather raised his family in Edinburgh, including my great-grandfather.

So April was filled with travel and then recovering from travel, then May was upon us and I had a wedding to go to in Virginia, which included spending like 30 hours there but it took me 20 hours there and back on a train from New Jersey, plus the flight to and from Newark. I left my place just before five in the morning on the Friday and only arrived at the hotel in Virginia past 1am on the Saturday. Let me tell you that I quite enjoy the train, but 9+ hours in a row on a train is… not ideal.

And that’s how we get to June.

In terms of coding, the crappy thing is that I’m stuck in my game. There is a legitimate game-breaking bug, but when I try to fix that, I break user sessions. It’s been super discouraging so that’s probably why I haven’t touched anything in June. We’ll see about playing with things this weekend, though.

I keep saying this, but I want an alpha out soon. Like, I wanted it out this weekend. But that was back in May.

Now aiming for around Labour Day. I think that’s doable. That’s two months. If I spend even just an hour a day, that’s 62 hours of work that I could accomplish on the game. Now, to be fair, I won’t spend an hour a day every day, but I think it’s absolutely possible to do at least 50 hours of work between now and Labour Day, even if that means some marathon weekends or chunks of four hours in a single night.

Anyway, that’s where I am. You can keep up to date on my stuff through my update log on GitHub and I also tend to post stuff on Instagram when I’m coding, particularly in the stories.

I feel better for having posted. Maybe now I can refocus and get working on stuff over the next few days. And, you know, post more regularly!

NaNoWriMo done!

Well, I took a really, really long break from #100daysofcode. Like, 31 days. And it was all because of National Novel Writing Month. For the 8th time ever (and seventh time in a row), I achieved the goal of writing 50,000 words in the 30 days of November. NaNoWriMo is something I have attempted sixteen times. I started in 2002 and I skipped 2011, but I’ve at least attempted it 16 times.

Finally, this year, I’ve pulled even. 16 attempts, 8 victories, 8 losses. And, in the process, I crossed the 500,000 lifetime word mark. Solely during November, over these last 16 years, I have written 500,000 words of various novels. It’s astounding to me. That doesn’t count my other writings, it doesn’t count how I’ve continued on with some of these novels. It’s literally just 480 days of writing. That’s just over 1000 words each and every one of those days. Some days, of course, I’ve written as many as 17,000 words (for real) or as few as 0, but the average is about 1000.

So another November comes to an end and another December begins.

And now, I can go back to coding.

I had figured I could absolutely write for NaNoWriMo and code for 100 days of code at the same time.

Wrong! Just wrong. Maybe I had time, but my brain did not like the shifting back and forth from writing to coding, so I did no coding at all during November. Oh God. What is code?

I’m planning to get back to it tonight or tomorrow. In the meantime, I haven’t been posting here about coding because I’ve been posting about coding in my 100 days of code log on GitHub. I do want to spend more time writing about my challenges and problems here, though, in more long-form writing.

Highlights include my doing a Docker course by Bret Fisher, doing #Hacktoberfest, and generally getting through portions of my game. I’m still in the intro in the game, but 90% of the code I’m writing now will be used in the actual game, so… this is good.

That’s about it for now, but that’s what I’ve been up to. 🙂

So! Much! Progress!

I started doing the #100daysofcode challenge on Tuesday morning. It was a modest start, just did about an hour of stuff before work, since I was inexplicably up at 4:30am or something dumb. And yet, I was able to actually tackle true email uniqueness.

So I had two concerns here:

  1. Prevent people from creating multiple accounts with the same email address. Like, user @ gmail.com is the same as u.s.e.r @ gmail.com or user+game @gmail.com. So I didn’t want that to be possible.
  2. Not mess up people’s given email addresses so I can actually send them communication about the game. What if someone’s not on gmail and, I don’t know, the period between their first and last names actually matters? What if someone set up a mail filter for the game using the plus sign? I definitely wanted to send mail to the address they had provided, but I didn’t want to have that address be the unique address.

What I did is save the given email address, but also normalized it (strtolower). Then, I made it unique by virtue of, well, here’s the code and I’ll explain it below.

Code to normalize and sanitize emails
Code to normalize and sanitize emails

Breaking the email up into its component parts of username @ and domain by exploding on the @ sign made things easy for me to modify just the username and then reconstruct the email address as a new variable called $uniqueEmail. So I then explode on any + sign. Then, by focusing on the first part of the resulting array ($sanitizingUsername), which is to say anything before any + sign that might exist in it, I’m now dealing with just the username. Then, I replace anything that isn’t a-z, A-Z or 0-9 with nothing (“”). Then, I rebuild the email address with the sanitized username I just created, concatenated with the @ sign and the previously-split apart domain.

This allows for an email address like julie.m.a.r.t.i.n+game @domain to be viewed by my program as juliemartin @domain for the uniqueEmail() check function, but, I’m still emailing that specific julie.m.a.r.t.i.n+game @domain address for any game communications.

Bonus: julie.martin @domain works fine, as does juliemartin @domain. Exploding on a + that may or may not exist has no ill-effects if it doesn’t.

So that’s how Day 1 of #100daysofcode went.

I’m logging my daily progress in a log file on GitHub, so you can check it out here:

https://github.com/juliebugmtl/100-days-of-code/blob/master/log.md

If you read it, you’ll see that, on day 1, I had neglected to change my email variable to the all-important email1 when I made the change for JavaScript validation purposes. I snag a bunch of information from the user’s submitted form on POST, but I forgot to change email to email1 when I changed the form ID/name for that field.

Guess what else I forgot to change?

The password field. I’m validating the password too, so I made two fields, one called password1 and one called password2 but at no point in time did I change my snagging information from the POST to snag from password1, so it was still pulling from the (non-existent) password.

Do you know how much fun it is to try to log in with a password that doesn’t actually exist when you don’t know it doesn’t exist?

Answer: not a lot, let me tell you! You can read about that in Day 4’s entry.

What’s hilarious is that the issue with the password storage and hashing comes on the heels of resounding success on Day 3 where I basically coded a whole function blindly and, to my utter shock, it worked perfectly on the first try.

Day 3 was dedicated to getting SendGrid to send out emails for validation and for blacklisting and I’d set up the validation workflow on Day 2 and finally got the link mailed out on Day 3, whereupon I then coded the blacklisting function without testing it at all until the end and it worked.

But Julie, you may ask, why the hell would you use a blacklist function? Surely people who are signing up for your game are, you know, actually interested in playing your game, no?

NO.

I have a Gmail address. I’ve had it since April 29, 2004. Unfortunately, being an early adopter means that I got my first choice of email address. As such, everyone else who wants that email address has to modify it, like if it were julie @gmail (it’s not), then everyone after me had to do julie1 @gmail or juliea @gmail or julie01 etc, etc, etc.

Do you know how often people forget that they have appended something to their email username?

It’s often.

Like, multiple-times-a-day-often, sometimes. Certainly multiple times a week. In the past, I have received emails from banks, airlines, universities, family and friends of other Julies, real estate agents and, the worst of them all, REPUBLICAN CAMPAIGN NEWSLETTERS.

All because these… these… these bozos, can’t properly understand what the hell their email address is.

So many of them are important messages so I try to write back with a canned response going “hey, wrong person” basically.

Just slightly above the Republican campaign newsletter crap I get, in terms of annoyance, is the stuff other people have signed me up for. Not actually me, obviously, but like an acquaintance, friend, family member of someone else out there has signed up my email address for Blue Apron in the past. Multiple times. This woman Susan signed me up to Blue Apron in March of 2016. Three. Separate. Times.

Thankfully, they listened to me and blacklisted my address, but the point here is that I don’t ever want anyone to have to deal with that pain in the ass when it comes to my game.

Hence, a blacklist system. My blacklist function does the following:

  • looks up the user
  • snags the unique email
  • adds the unique email to a voluntary blacklist
  • deletes the user
  • deletes the token associated with that user

You can only get to the blacklist page by virtue of clicking the link in the email sent. The URL adds the token and the user ID in its parameters, so it’s like domain.com/blacklist.php?t=TOKENHERE&user=USERIDHERE. If the token doesn’t match the user ID, it won’t work. And I do refresh the tokens once someone validates, so they can’t accidentally delete themselves.

Gotta say, I’m pretty pleased with that functionality. Plus, if someone wants to register and uses a blacklisted email, they get asked to email me to remove the email from the blacklist. If the email doesn’t match, then I won’t remove it, simply.

So there’s been a lot of progress. Registration is effectively done. Login works. Time to clean up and refine All The Things and then work on:

  • identifying an admin user
  • adding menu options for logged-in users (admin and not)
  • working out what the hell logged-in users should be able to do! hahaha

Some planning to do, for sure, but this stuff is getting interesting. Keep up to date with me on Instagram, where I’m posting stories when I sit down to code and post a pic when I’m done working for that day.

#100daysofcode

I’ve been thinking about it for at least a couple of months and I’ve decided to embark upon #100daysofcode. Why? Because it’s there!

No, truthfully, I’ve wanted to do this since I first saw the tags on various Instagram posts that I’ve seen. The thing that’s been stopping me is that I literally cannot commit to 100 days straight of code. Probably the soonest I could do that is December 1.

So while I’m starting the #100daysofcode challenge today, September 4, there are two major changes I’m making to the rules for myself. The rules state you need to code one hour a day for 100 days and you can only skip one day every two weeks, adding that skipped day to the end of the 100 original days to ensure that you are actually doing 100 days.

The first rule change here is that I am not going to code from September 25 until the 29th (may or may not be inclusive). Why? I have a work trip. I definitely do not think I can get away with sitting in my room coding for an hour a day when the rest of my colleagues are hanging out and chatting and getting to know one another. As such, instead of this challenge ending for me on December 13, it’ll end much closer to December 18. Or possibly later.

The second is that every November, I participate in National Novel Writing Month. That means that I should be striving to hit 1667 words of creative writing during every day of November. It rarely actually turns out like that — I’ll sometimes go several days without writing and then will suddenly write 7,500 words and will catch up. However, the goal is 50,000 words in 30 days and so because of this, I’m giving myself permission to skip coding 1-2 times a week during November.

So that’s an additional 4-8 days, which beings me to December 22 to December 26. Obviously, you have Christmas in there, too, which needs to be accounted for, so here’s my thinking: in the 119 days between today and December 31 (inclusive), my aim is to reach 100 days of coding for at least one hour a day. That’s totally doable. I may even come in ahead of that projection, depending on how well the writing goes in November.

19 days is a bit of a buffer, definitely, but I think this is an achievable, albeit challenging goal. I did think about putting this off until December 1, when I could conceivably actually do the challenge as intended. But what’s the point of putting off something I want to do that will encourage me to do something I should be doing? While I’m a life-long procrastinator, it seemed silly to me to hold off on this challenge for another three months.

I’ll be primarily posting to Instagram, but those posts cross-post automatically to Twitter. Follow me on either: the username for both is juliebugmtl.

And now, to get a cup of tea and start my first hour of coding in this challenge, since it’s 7:14am and I’ve inexplicably been awake since 4:30.

I built a computer!

On Monday, August 27th, for the first time in my life, I assembled a computer from scratch. It even booted on the first attempt! I documented it on Instagram, in my stories, and here are some of the pics, including some of the comments I made on the pics.

Photo of my new case
And so it begins.
Something like 8 power cables from the power supply.
So. Many. Power. Cables.
Power supply installed.
Power supply: check!
Motherboard map.
Honestly, this was the most useful piece of paper.
The spot on the motherboard for the CPU.
The seat for the CPU. This was the most nerve-wracking portion of the whole thing.
Image of the CPU.
More than $400 right here.
CPU in its seat.
Seated!
CPU locked into place with the frame.
Locked in.
Fan installed in the front of the case.
Installed the fan for my CPU cooler.
Container of Arctic Silver thermal paste with the CPU and motherboard in the background.
Okay, this was also terrifying — applying thermal paste to the CPU in preparation to put the cooler on top.
Corsair CPU cooler in place on the motherboard.
Cooler installed!
Power cables plugged into the power supply.
Remember all those power cables? hahaha
Video card seated in motherboard.
Video card in!
Shot of the left side of the case, showing the interior of the computer.
Done!

There were a couple of small issues, though:

a) The case fans weren’t running. I had completely forgotten to hook them up to power. There was this wire coming down in the case with the old four-pin system and I’m like “what does this even connect to??” since it wasn’t terribly obvious, so I’d ignored it. But I knew to hook up the peripheral power cable to the peripheral power source in the power supply and then connect that cable to the four-pin wire. So that wasn’t a big deal. And, it being 1:30am when I finally booted the thing, it was something I could deal with Tuesday.

b) My SSD wasn’t recognized. I’d actually thought this might be an issue. My friend, Andrew, who was on the phone (well, FaceTime Audio) with me for like, 90 minutes on Monday evening) had indicated that he wasn’t sure that was the right slot for the SSD M2 and I looked at my motherboard map (YES THERE WAS A FREAKING MAP) and saw that the other slot was underneath some branded plastic casing. So I kept it in the original slot and figured that if it wasn’t recognized, I’d fix it the next day. Sure enough, wrong slot.

SSD in the wrong M2 slot on the board.
But this ended up being the wrong slot.

So on Tuesday, I connected the power for the fans and then uninstalled the video card, pulled off the casing hiding the M2 slot, moved the SSD there, then reinstalled my video card and crossed my fingers and it booted into the Windows setup (courtesy of my USB key with the Windows installation on it) and it recognized my SSD!

I installed Windows (that was a whole Thing, too, but eventually got resolved) and then started the painful process of copying stuff over. Fun fact: I’m still not done copying and installing things, but the vast majority of important stuff is done. I haven’t yet installed my writing program (Scrivener), don’t think I’ve installed Dropbox, etc, but most of my actual files are copied — creative writing stuff, my programming stuff, photos, other documents… That said, my old computer is still sitting on my dining room table, hooked up to the router via ethernet cable and the drives are shared, so I can just copy as needed.

Overall, it went a LOT better than I thought it would. I also engaged in some light cable management on Saturday, and this is the end result.

Photo of my workspace.
Clean! Sort of!

In terms of the game, I haven’t done a ton of stuff, owing to, you know, computer building and copying stuff over. That said, my dev environment with Docker used to take in excess of 8.5 minutes to boot up on the old computer.

It takes 27 seconds on the new one. Just let that sink in for a sec. Or 27.

But even without that blazing speed, I’m pleased to say that I solved the problem with the password strength script last weekend! The issue was that I was calling the script too early, so I shoved it to the bottom of the form and it worked just fine at that point. Since building the computer, I’ve made some modifications to it and to my own registration validation script, so now I have JavaScript checks for:

  • username length (must be at least 5 characters, no more than 16)
  • username allowable characters (a-zA-Z and 0-9, but can’t start with a number)
  • password1 matching password2 (you know, your typical re-enter to verify password thing)
  • password strength must be at least “good”, as per the password strength check
  • email1 matching email2 (verify your email)

Plus, I have PHP checks for:

  • username uniqueness
  • email uniqueness (this still needs work)
  • spammer/disposable domain emails
  • disallowed usernames (admin and such)
  • profane usernames
  • voluntary blacklist (to prevent people from accidentally getting signed up because how are people so stupid as to not know their own email address? Trust me, this happens to me constantly.)

I also added some styling. Just some basic CSS to make sure the form looks nice as well as making sure error messages are easily shown.

Screenshot of registration screen where the user is asked to input a stronger password.
See? Error messages!
Screenshot of the registration form, Sublime Text 3 and my Docker container log.
Here’s a better pic.

So that’s what’s up with me. I’ve got a four-day weekend this weekend, due to Labour Day on Monday and I also took the Friday off, so it’s been a pretty glorious weekend for me. My living room is a disaster, so my goal tonight is to clean that up and put away all the documentation for all my components, my spare cables, spare screws, etc. Then, while my old computer will still be on my dining room table, at least it won’t be surrounded by an insane amount of empty boxes, ripped plastic bags, electronic cables and screwdrivers and such.

More updates as I make progress in the game, certainly. My next task is to clean up the unique email check and move on to sending out validation emails. And then login stuff! Man, this stuff is really starting to come together and I am psyched, dudes. Psyched.

A new computer and game updates

Earlier this year, I made the decision that I needed a new computer. I mean, this decision has been in the making for a while. I bought my last computer from Dell in 2011 and have upgraded it a few times — added RAM, swapped video cards and such. But it takes forever to load programs. Even loading Chrome can make the computer temperamental. Multitasking? Mostly out the window.

The CPU is an Intel i7 930 quad core and, at cpu.userbenchmark.com, it ranks at 330th of 1122 CPUs ranked. I mean, not terrible, right? Still, I can’t do most of what I want to do as well as I’d like to do it. So I decided, with the help of a friend of mine, that I’d not only buy a new computer, but I’d assemble it myself.

I bought all the parts on Tuesday night and they’re starting to arrive today (Thursday).

The new CPU I’m getting is ranked 8th/1122. Just a bit of an upgrade, eh?

I went all-out on this. We’re talking 16GB RAM (expandable to 64), 500GB SSD and 1TB HDD, GeForce GTX 1080Ti graphics card, SLI-compatible motherboard — and I suspect the 1080Ti will drop (eventually) so it won’t be quite so expensive to buy a second one later on, since the 2080 and 2080Ti have been announced. No peripherals, since I’m just going to use the ones I already have. And I also want a new monitor to replace one of my two (and I’d give one of them to my brother). So the new rig will be able to handle video card upgrades, RAM upgrades and such.

My only worry is nuking my CPU by accident, hahaha oh god. Anyway, I should be assembling everything late next week and I’m super excited to be able to open programs like Photoshop while Spotify is open, or open Discord while playing a game with my brother and not have my ENTIRE COMPUTER FREAK OUT. Even opening my writing program, Scrivener, can make everything chug and then I’ll realize that oops, I left Docker open from the last time I was coding and maybe THAT’S the problem.

So, coding.

When last I wrote, I was dealing with registration validation of things like unique usernames and such. I’ve moved from the PHP validation (mostly — still something left there) to JavaScript/form validation. I’ve used regular expressions (oh, regex, I did not miss you) to ensure that usernames are only 5-16 characters and don’t begin with a number. I’ve made sure that if your email1 and email2 fields don’t match that it alerts you to that. I’m currently working on an implementation of password strength based on the zxcvbn library by Dropbox. I’m having trouble with it and, of course, if something is wrong with the JavaScript, the user gets registered anyway because the validation won’t occur and, since I’m only doing uniqueness checks in PHP, it won’t stop “test” from getting registered unless I’ve already registered “test”. (Yes, I’ll have to ensure that JavaScript is running on the user’s browser in order to play the game, good times.)

It’s slow going with JavaScript. It’s definitely the language I’m least familiar with after my web programming diploma. Like my current error is, I’m sure, a variable scope problem, but I’m not really sure how to fix it. Guess I’ll figure it out going forward.

So once the JavaScript validation is done, I want to go back to the PHP checks and look at making sure I have a unique email, which will mean stripping all the dots and plus signs (and everything after a plus sign) from addresses, to ensure that Gmail users, for example, can’t sign up for multiple accounts. In truth, it’s not the end of the world if there are multiple user accounts, but I’m hoping for some measure of cooperation in the game and that would make things too easy for people.

So I figure I need to hold on to two email addresses — the original one and then a unique check one, and run the unique checks on … both? I guess? I still need to figure out the logic there, which I’ve been putting off, if I’m honest, because I haven’t quite thought it all the way through yet.

Also to do:

  • add validation email with validation link
  • ensure validation email has opt-out/blacklist link

And then, I think I could move on to login. Which is also terrifying to me, but I’ve ostensibly done it before, in PHP II, so we’ll see where that goes.

From there, I’ll certainly want an account page so people can:

  • change their email address on file (but not their username)
  • reset their password
  • invite a friend…? (This may only be a v2 thing, but we’ll see)

THEN, I might be ready to actually create a flow for people to actually play the game. Part of the issue here is that I’m still working on story. So far, I can pull trivia questions from a database and keep score. This is awesome. It was hard work to get to that point! But there’s this whole story I vaguely have in mind, which is going to mean keeping track of different variables and that will affect how the gameplay works. I also want to build in a maintenance function (one that runs automatically but also one I can run manually if need be) and I want to add in all kinds of admin functions like being able to add, delete and modify users through an admin frontend rather than mess with the database directly. Same with adding, deleting and modifying questions. I also want to code something to back up my databases on command and reset the game.

Still, once I get the login going and allow for a flow for people to get to the game, maybe I’ll send out a few invitations to some friends to try it out, just to see if they can break the (very basic) functionality I have. If they can break it, I’ll have a lot of work to do before I can think about bringing in the actual gameplay I have in mind.

Whew. So that’s my update.

And while I’ve been writing this, I got notification from Intelcom that my delivery consisting of my new:

  • CPU
  • SSD
  • HD
  • power supply
  • motherboard

is arriving in the next ~3 hours. If everything that should be delivered today does arrive, I’ll have had deliveries from UPS, Purolator, Canada Post and Intelcom. In a single day. And I feel for Purolator, because they’re deliverying three packages to me, apparently, including my CPU cooler and my RAM. UPS is bringing me my video card, while Canada Post is bringing me the last part of my nephew’s birthday gift, which is a Spider-Man t-shirt.

Anyway, I should get my day started, despite the fact I just want to go back to sleep. I’ll have pictures of stuff next time, no doubt!