Fleet Devblog #1: Prototyping is Hard

As hinted in my last post I’ve recently started work on a game. I intend to make this the first of a series of devblogs chronicling my work on it. Today, I’m going to give a brief rundown of what the game is (or how I imagine it) and the current state of the prototype I’ve been building.

Fleet

The working title for the game is Fleet; it’s a bit of a mixture between chess and Hearthstone with spaceships and RPG elements. Here’s how it works:

Overall, I want the game to be simple-enough for anyone to jump in after a tutorial and I also want it to be very open to casual play. However, I also think the strategic elements make it a prime candidate for serious/competitive play. I always planned on launching for desktop first, but had hoped I’d be able to open it up to mobile as well (I’ll be developing in Javascript so that’s particularly easy) but I’m starting to think that the amount of information necessary to play will be hard to fit on a mobile screen. That’s a ways off though.

Prototyping

So here’s the problem: I am terrible at prototyping. I’m the type of person that enjoys the design and architecture part of software development probably more than the actual implementation. I’d rather spend 10 days designing the perfect API rather than designing 10 iterations every day. This is almost always a bad thing; iteration is crucial. One article that I found particularly interesting against the idea of premature-abstraction was Casey Muratori’s post on “Compression Oriented Programming. The idea of not abstracting until you need an abstraction, rather than abstracting in anticipation of needing it, makes a lot of sense to me, even if it isn’t exactly what I’ve been taught.

So here’s my progression from being very bad at prototyping to being slightly less bad at prototyping. When I started working on this game, the first thing I started working on was the server networking architecture. And I spent at least an hour just designing it. This was terribly unproductive for a few reasons:

A lot of these realizations came after having watched Extra Credit’s excellent video on “MVP” I ended up scrapping a lot of what I had done and started working on a purely client-side implementation. The games would be between a human and an AI player so I wouldn’t have to worry about anything server-side. The next hiccup I encountered was the UI. The nature of the game pretty much requires a fairly hefty UI to represent all the information you need and allow you to take action appropriately. I originally had started out trying to do it all on the canvas, trying to roll my own basic layout library before I caught myself and searched for a better solution. I was working with web-tech anyway, so why not just use HTML for the UI for now? Within about 20 minutes I had a fully functional UI thanks to my existing HTML+CSS experience. That allowed me to finally get to work on the important stuff: gameplay.

Current Status

The gameplay is going well, and I have a few ideas for posts in the next couple of weeks about interesting things I’ve done so far. Currently, the game supports the following:

An example of current gameplay is shown in the GIF below. The blue hexagons are ally ships, and the red is an enemy ship. The green bars on the left side of hexes represent health and the yellow represent energy.

Fleet Prototype Gameplay

Against my best wishes because the codebase is a mess, I’ve forced myself to put all the code on GitHub in its current state. Try not to look at the client code because it’s a mess. The game folder is a bit better and more interesting.

Issues & Next Steps

I have these ordered based on how important I think they are, so if you think I’m wrong please let me know!

At this point, I’d say it would qualify as a “game”. From there, I’d need to add art, begin adding multiplayer, add much more content & items, etc. One step at a time.

I hope you enjoyed my first devblog; hopefully there will be many more to come. Until then, let me know what you thought on Twitter (@ganashaw).See you next time!

Resolutions

I’ve never really been one for New Year’s resolutions. Part of it is probably that I’ve always been fairly comfortable and complacent with my life that making any drastic changes has seemed entirely too inconvenient. As you’ve probably surmised from the title, I’ve had a change of heart. My hope is that by writing them down, even if no one else reads them, I might feel a tiny bit more obligated to stick to them. Hopefully, in 365 days I’ll have a new post to say that I actually completed them all.

1. Write More

I’ve had this blog for quite a while now (3+ years) and I have 6 posts, including this one. That’s pretty pathetic. I think writing or at least keeping some sort or journal is a fairly productive thing to do. Especially with respect to technical aspects, I think writing about projects helps to review your work and think about ways you could have done things better or differently. Assuming someone reads what you write, it also provides a means of receiving feedback which is invaluable. I think the most important consequence of writing about projects is that it forces you to justify your decisions. The more detail you include, the more you have to rationalize each decision you made. I hypothesize that this will make me a more deliberate, careful developer since if I make bad decisions I’ll then have to tell the entire internet about how I made terrible design choices.

2. Develop and Launch a Game

Every two months or so for the past several years, I get an overwhelming desire to develop a video game. This typically results in me coming up with a half-baked idea, spending an inordinate amount of time to come up with a clever name, spend about a week tops coding up a prototype without finishing and then abandoning the project altogether. My goal for 2017 is that I actually follow through on one of these projects and “finish” it. Besides just developing a game, I want to maintain a devblog, promote the game on social media, and do all the things a typical indie developer would do. I don’t plan to go into gamedev full-time any time soon, but I think there are a lot of skills that I can learn from hobby gamedev that will help me in other aspects of my career. The gamedev bug has bitten me again so I’ve currently got something in the works; with any luck, the first entry of my devblog for that project will be out this week.

3. Read More

I’ve always vehemently abhorred reading. I don’t know why. I found it tedious and boring. I still do, but now I recognize that it’s actually kind of a good thing to do. Especially in the software development field, there is a ton of literature written about how to become better at the craft. I’d like to read a few of these books. At the top of my list are:

I’d also love any fiction suggestions to throw into the mix. I’ve read and loved the entire “Hitchhiker’s Guide” series by Douglas Adams.

4. Increase My Faith

2017 will be the first year in which I’m not a student, seeing as I’m graduating in May (woohoo!). A consequence of this is that I’ll no longer be held accountable by others (e.g. religious educators, FOCUS missionaries) with respect to my faith. It will be completely up to me to nurture and increase it. My goal for 2017 is to accomplish this. The exact method isn’t clear, but I know I want to grow closer to Christ and He wants to grow closer to me.

So that’s it. My four resolutions for 2017. Feel free to hold me accountable on Twitter (@ganashaw). Hopefully, I’ll be back in a couple days with a devblog for my latest project.

Making Something ugly

I’m definitely an idea guy. I have ideas all the time. I think that most of them suck, but the thing with ideas is that there’s no way to know if they suck unless you execute them. Generally, when you have an idea you want to make a prototype as quickly as possible so you can decide where your idea falls on the scale of suckiness (or greatness, if you’re lucky). But like I said, I’m an idea guy, not an execution guy. Executing is hard. Whenever I sat down to try to prototype an idea one of the major roadblocks for me were graphics. It seemed like any low level (aka powerful) language required lots of external libraries and gross stuff. It was a pain, for me and probably for many others. So ugly is my attempt at fixing that. I dreamed up ugly as a universal graphics library, a graphics library that could be used on any machine, with any language, really quickly. And I think I succeeded.

Goals

Starting out, I had a few goals in mind when making ugly:

Good revision history

I wanted to force myself to make small, frequent commits. This has a two-part purpose. One, by keeping the commits small, it’s easier for me to make progress because it takes less time to make that little change here or add some safety checks there. Secondly, it makes it easier to track down bugs. If I don’t notice a bug right away, it’s easier to go back in the history to find out where the bug first occured, and since the commits are small, it’s usually very obvious what change introduced the bug.

(There’s also a third advantage: it makes writing project-recaps like this much easier)

Finish it

I had a really bad habit of not finishing projects. I wanted to finish ugly. And I did. And I’m proud of myself for it. (Ironically, this blog post took me several months to finish…)

Planning

So I wanted to make ugly language and platform agnostic. That means it had to be written in a language that everyone had. And what does every computer have? A web browser. So I decided to make ugly with Javascript, doing all the rendering in the browser. Unfortunately, there’s really no good way to get data from a user’s machine to a Javascript front-end without introducing a server, so I built a server implementation in node.js to forward data from the client to the viewer. The interface was fairly simple: The client program or whatever needed to be rendered writes data to the node.js server via stdin. The server would validate incoming commands and then forward them to the browser-based renderer using websockets.

At this point, there were a few things I wasn’t certain of. I was mainly worried about the latency that would be introduced by introducing the node.js middle-man. It was important that the rendering happen as close to realtime as possible. However, as I couldn’t think of a better way to achieve what I wanted, I decide to go ahead and try it out.

Execution

Note: This is pretty much me narrating my commit history. Yay version control!

Making connections

I started out just having the node.js server read lines from stdin. I then introduced a basic logging module to handle logging to a file and/or stdout and stderr. Next I cooked up the code for serving the rendering-client where the actual drawing would happen and forwarded the lines read from stdin to the client via websockets. At this point, all the connections were made and I just had to add the logic.

Protocol

The next thing I had to do was define the format in which ugly would expect incoming commands to be. I decided on a fairly minimal syntax:

command_name arg1 arg2 arg3 ...

I also introduced the concept of ‘chunks’ which grouped related commands:

$CHUNK_NAME
command_name arg1 arg2 ...
command2_name arg1 ...
...
$END_CHUNK

There would be two types of chunks: CONFIG chunks which would define settings to be used throughout the render and FRAME chunks which would define the drawing commands to be used for a single frame.

Validation

I decided that the server would be responsible for validating the commands so that the client could assume it only received valid commands. The less non-drawing work the client would have to do, the better. As I started writing validation code for the commands, I realized that this was going to get real gross real fast. I essentially had a block of code that looked like

if (command_name = "command1")
    validateCommand1 (commandStr)
else if (command_name = "command2")
    validateCommand2 (commandStr)
...

And I planned to have well over 30 commands. I decided to split out the commands into their own module. Each command be an object with a validate function. This way the server, could simply query the command module, get the command, and call its validate function:

var command = commands[command_name];

if (command.validate ())
    sendToClient(command_str);
else
    error("Bad command!");

For one, this made it a tad bit easier to add commands (I didn’t have to add an extra “if” branch for each command), but it also turned out to make executing the command easier on the client-side.

(Note: in the end, instead of having a validate function for the whole command, I had a validate function for each argument, but this is a minor implementation detail; the gist remains the same)

Rendering

Once the command was validated server-side, I sent the full plaintext string to the client via websocket. Here, I once again leveraged my command module. In Javascript, suppose you write a function like so:

object.myFunc = function (arg1, arg2) { // do stuff };

Conveniently, you can also access and execute this function like

object["myFunc"].apply (object, [arg1, arg2]);

The key here being that the function is identified by a string. That meant in my command module, I just needed to save the string representation associated with each frame command. Additionally, I needed to get the arguments. This was again easy because the arguments my plaintext command took were exactly the same taken by the Javascript function. So I could apply all of my frame commands in exactly the same way; all that changed was the data.

Putting It All Together

To give you a better idea of how the commands are actually processed, I’ll trace the execution of one all the way through. Here’s an example of how the clearRect command is represented in the command module:

clear_rect: {
    name: 'clearRect',
    type: commandTypes.METHOD
    params: [
        param ('x', paramTypes.FLOAT),
        param ('y', paramTypes.FLOAT),
        param ('width', paramTypes.BOUNDED_FLOAT (0,
                Number.MAX_VALUE)),
        param ('height', paramTypes.BOUNDED_FLOAT (0,
                Number.MAX_VALUE)),
    ]
}

And here’s how that command would be provided:

$FRAME
...
clear_rect 0 0 100 250
$END_FRAME

The server would first read in the full string (line 3 in the code block above). It would then take the first “word” ('clear_rect') and search for it in my commands module (which would return the objct in the firstcode block above). From here, the arguments of the plain text command would be validated. To do that, it first sends all four parameters (0, 0, 100, 250) to the FLOAT paramType, since it is the paramType of the first parameter in the parameter list. That parameter object would validate it and return whichever arguments it didn’t use. In this case, the float parameter uses only the first parameter so it leaves 0, 100, and 250 (parameter types don’t always consume just one argument; a color param-type for example consumes four: r, g, b, a). The remaining parameters then passed to the next parameter objects until they are all validated. If no errors are encountered, that command is sent to the client.

When the client receives the command, it again looks up the clear_rect object. It then asks each of the command object for the Javascript value type. For example, for a paramTypes.FLOAT, passing the string '3' would return the value 3. This argument list is then used to call the function:

canvas["clear_rect"].apply (canvas, [0, 0, 100, 250]);

And we’re done! Feel free to read through the code to see it in action.

Final Thoughts

So that was the basic design and structure of ugly. I’m very pleased with the way I was able to cleanly separate the data (the commands and their arguments) from the execution. The amount of code reuse in this project is really quite impressive in my opinion.

I think the most exciting thing about ugly was when I got the first (and as of yet only) pull request. Just a few hours after posting the project on Reddit and HackerNews, someone submitted an example that used ugly to visualize Conway’s Game of Life. It was super neat to see someone using code that I wrote. That alone made the whole project worth it.

If ugly is something that sounds useful to you, go check it out on GitHub. As always, pull requests are welcome!

My Life at Carnegie Mellon

Last year while I was looking at perspective colleges, and even once I had decided on CMU, I was very interested in the student perspective; what it’s like to actually be a student at Carnegie Mellon. Surprisingly, there was very little available aside from the standard student life page on each university’s website. Seeing as I’ve completed roughly a semester and a half now, I thought I’d go ahead and contribute for anyone who might be interested in that sort of thing.

About Me

Since a significant portion of the post will be subjective, my background is probably relevant as it definitely shapes my expectations and opinions of things. First things first, I’m a freshman studying computer science. Before college, I spent three years at The Louisiana School for Math, Science, and the Arts a public school for high-achieving highschoolers in Louisiana. LSMSA is actually situated on a college campus, and most of the classes are taught by college professors at a college level; about 90% of my teachers had a terminal degree in their field of study. As a result, I had already experienced a lot of what is often lumped into the “college experience.” Namely, I had spent three years living relatively independently in a dorm, I was being taught at a college level, and I was being exposed to a truly diverse group of people; much more than an average highschool. I point this out mainly because these are all aspects which may have a significant impact on one’s college epxerience, but they weren’t for me, so I probably won’t talk about them as much. Additionally, I’m one of the most introverted people you’ll ever meet (if you ever meet me..) so I can’t comment much on the social scene at CMU either.

First Impressions

As a freshman, your first real look at CMU will be during orientation week. I mean sure, those summer tours are great, but they don’t really give you a feel for the campus and student body. Before anything else, you have to move in. I must say, the orientation staff make this absolutely painless. I got out of my car, they told me to go do some logistical things like get my ID and some CMU swag, and by the time I got back my stuff was already at the door of my room…on the third floor. Already, I’m digging this place. The week continued pretty much as expected, awkward ice breakers, cool performances and shows, crowded meals, and lots of walking. As an introvert, a lot of the week was uncomfortable for me; I suspect that that’s the case for a lot of CMU students, especially computer science majors. I didn’t really end up with a close-knit group of friends like many people seemed to; however, that’s not for lack of opportunities, and probably more for lack of me trying/knowing how.

After orientation, I got my first experience of real college life. A few classes, surprisingly not terrible food, and a pretty substantial amount of homework. My first class was Matter and Interactions I, which is described as the “Honors Physics” course at CMU. I felt compelled to take this course for a variety of reasons. First of all, without it I would have been carrying “only” 40 units of classes. (For a freshman, the maximum is 55 and the minimum is like 35, I think) Despite having been accepted into one of the most prestigious schools in the world, while I was scheduling my classes I for some reason still felt the need to “prove” myself. To justify my presence. I thought that the best way to do this was to take as many hard classes as I possibly could. As if somehow I was being a slacker if I wasn’t taking the maximum number of units every semester. Within about two weeks, I gravely regretted my decision. One of the most dangerous traps that I fell into during that first semester (and still do to this day) is making the assumption that because my computer science classes are super hard (and they are), all of my other classes are super easy. (and they aren’t) Matter and Interactions kicked my ass and the ass of just about everyone else in that class. It was hard, and it took up a lot of my time. And the worst part? I don’t think it really even matters. I mean, I’m not a physics major, I have no intention of getting a degree in physics. I could have taken the intro physics class and my graduation requirement would have been just as fulfilled, recruiters probably wouldn’t have known the difference, and I would have had more time to spend doing things that did matter, like my CS classes, side projects, and research. More on that later…

The Grind

Eventually, I got into the groove of things and developed a pretty routine schedule. I had class every day til about mid-afternoon, went to Gates and watched Netflix until 5, grabbed dinner, worked on any homework due the next day, played video games, and went to sleep. On the weekends, I spent my Saturday afternoons playing video games or working on side projects and my Saturday nights (about 8pm-1am) working on problem sets because I honestly didn’t have anything better to do. Typically I could finish about half of my week’s work on Saturday nights. On Sundays I went to my research meeting and worked on that for a few hours, then worked on homework until a meeting for the FSAE team at 6:30, before having dinner, going to mass, and going to bed. This was how just about every week played out. Honestly, it wasn’t that bad, aside from the inevitable frustration over my math assignment, I was pretty satisfied. Still, it seems as though this pattern of routineness is inevitable; or at least I haven’t found a solution. This semester is pretty much the same except I have a lot more work. Great Theoretical Ideas for Computer Scientists (15-251) is, according to many, one of the most challenging CS courses students are required to take at Carnegie Mellon; I easily dedicate 6-10 hours per week just working on the homework not to mention attending lectures and “homework writing sessions.” (don’t ask…)

Now, don’t get me wrong, I’m not complaining. When I decided to come to CMU, I expected to be pushed harder than I’ve ever been pushed before, and to get my ego taken down a few pegs. Both of those events occurred within about a week. The grind isn’t bad…in many ways it prepares you for the real world, for a job, but it is a grind nonetheless and it can wear you down. On the brightside, to counteract the grind, CMU students, especially CS students, are presented with loads of perks that make the grind worth it.

The Perks

Carnegie Mellon University has one of the top computer science programs in the country. Naturally, there are benefits. The first that I noticed was just how eager companies and recruiters are to talk to you. I remember sitting in Gates (the computer science building) one afternoon and a company’s recruiter came around the study area handing out cookies and flyers for a tech talk that evening. Maybe it’s just me, but that blew my mind. Companies really really want to hire you. Even as a freshman, it’s pretty normal for students to get summer internships at Google, Amazon, Microsoft, etc. as well as smaller startups working on really cool things.

Another huge perk is the caliber of the faculty working here. World famous professors in any field are normal, professors working on things that could truly change the world. And the best part? They’ll let you work with them. I knew coming into Carnegie Mellon that I wanted to get a taste for doing research, so I started looking at professors doing cool things. I eventually found Dr. Red Whittaker. He’s done some pretty freaking cool things like building an award winning autonomous vehicle, and leading the pack for the Google Lunar XPrize. I walked into his office one day and asked him if there would be room for me to work in his lab and within a month (he’s a busy guy) I was writing software for a 30cm x 30cm x 30cm experimental lunar rover. Opportunities and perks abound at CMU, and I’ve done my best to take advantage of them as much as possible.

The Journey Continues

I’ve only been here for about 6 months now, so I’m still figuring stuff out, but I’ve definitely learned a lot already. I’ve learned that I don’t need to be the best at everything. I don’t even need to be the best at anything. In fact, there’s probably many people better at me in just about everything. The best I can do is my best, so that’s what I’m going for. One step at a time, the journey continues, and so far it’s been totally worth it.

My First All-Nighter

It seems to be more and more common for students to brag (or complain, regret) about how little sleep they got the previous night. It definitely happened at my highschool and it’s even more prevalent here at CMU. Fortunately, I had been lucky enough to never have to pull an all-nighter…until last weekend when I participated in my first ever hackathon here at CMU. TartanHacks 2015 was a blast and probably one of the most enjoyable all-nighters I’ll ever experience.

Pre-Hack

It started like any other Friday: classes until 2:20, research meeting at 2:30, bible study at 4:00, dinner at 5:00. Then things got exciting. I waited in line for about 5 minutes, obtained a wristband, and proceeded into the auditorium. I met up with my group and we listened to the sponsors brag about their sweet prizes (read: badass drones, cash money) and convince us that we should use their APIs. Then, we rushed to get dinner (after securing our hack spot of course). The wait for dinner was absurdly long and unfortunately we lost about an hour of valuable hack time, but in the end it turned out not to matter.

Commence H4cking

Our idea was pretty simple: craigslist, but for rentals. A platform that would allow students to rent out their un(der)used items to fellow students. As simple as it was, it still turned out to be a lot of work. One thing our group struggled with was the division of labor. All the inner workings seemed pretty connected that it didn’t really seem possible to work in parallel. As a result, most of the coding ended up on me while my peers helped me scope out potential APIs and other logistics. I didn’t mind, but I felt kind of bad that I got to have all the fun. This is definitely something I’d like to improve upon in the future.

I think I wrote the first line of code at around 8:30pm Friday night and I had finished a somewhat working application around 9:30am Saturday morning. Luckily I didn’t run into any significant technical challenges throughout the night; I really had a ton of fun. Something about bringing a project from nothing to.. something in such a short period of time was really rewarding. It really affirmed my education/career/life path. Programming is truly something I love.

The Expo

After hacking had officially ended on Saturday night, there was an expo for everyone to show off the things that they made. To say I was blown away would be an understatement. There were devices made of card board to help the visually impaired see in 3D. There was an augmented-reality version of Asteroids. There were so many things I never would have thought of and yet I wasn’t surprised at all. Hackathons seem to really bring out the most intelligent, creative, awesome people. The kind of people that you just know will be successful.

ShareIt!

My team’s app, shown above, didn’t win, but I wasn’t really disappointed. We got some awesome feedback and I had a ton of fun. I was absolutely exhausted and I think I slept for about 14 hours the next day, but it was so worth it. It is definitely an all-nighter I’ll never forget.

My First Foray In Open Source Software

Prelude

Almost all programmers that I’ve talked to are huge proponents of open source software. Recruiters avidly encourage job applicants to contribute to open source software because they love to see it on resumes. Until a few days ago, I had never contributed to any open source project other than my own. Finding myself terribly bored one weekend, I decided to change that. So this is a brief summary of my first contribution to open source software.

Step 1: Find a Project

This has almost always been the hardest part for me. Ideally, you want a project that doesn’t have a huge codebase already. Less code makes it easier for you to contribute right away. However, you also want your contribution to matter. The incentive to contribute to an obscure command line utility that only works on Ubuntu 10.02 is minimal at best. I used Github to explore interesting projects. There are also websites that pick out Github repos with the most “issues” but the problem with that is that most of these projects have literally 1000s of issues. That can be pretty intimidating for a newcomer. Luckily, I stumbled upon a neat little Javascript library called TheaterJS. The appeal of this project was three-fold:

Step 2: Write Some Code

After I had found this project and settled on how I would contribute, I forked the repo and got to work on my solution. This should be the fun part, and it was. I did my best to maintain the same style as all the other code that had been written, even if I didn’t agree with it (spaces are inferior to tabs, people). Aside from style issues, I made sure to avoid making any unnecessary globals to avoid polluting existing code. Overall, I made sure I wrote quality code, just like I would if I were working on my own project.

Step 2a: Test Your Code

I can’t think of anything more embarrassing than submitting a broken pull request, so I made sure to thoroughly test my code after it had been fully integrated. I found a few bugs, fixed them, tested some more, washed, rinsed, and repeat until I was confident I had flawlessly implemented the feature.

Step 3: Submit a Pull Request

Finally, I submitted my pull request and waited for the owner’s response. At first, he briefly looked at my code, said it looked good and that he was testing it locally. Score! A few hours later he came back and told me he was experiencing a bug with part of my implementation. Much to my dismay, there was indeed a bug in my code. Luckily, I was able to fix it in a matter of seconds. I committed, pushed, and waited for his response. After that, the owner and I had a brief discussion about what different parts of my code did, and then he merged it with the existing repo! Now, anyone who uses his library will be using some code that I wrote, and I think that’s pretty cool.

Hopefully, this is the first of many contributions to open source software. It’s definitely a satisfying experience that I would recommend to any programmer.

Making Lights and What I Learned

Lights!

About Lights

I just recently finished developing an adaptation of the classic “Lights Out” game. For those of you who aren’t familiar, the object of the game is to turn on all the lights on the grid. Whenever you toggle a light, all 4 adjacent lights would also be toggled. In my version of the game, Lights, the same rules and objective apply. However, some lights are “directed” meaning when you toggle them, only the adjacent light(s) in certain direction(s) are toggled, which increases the difficulty of the game. The game itself has some fairly interesting nuances to it. Firstly, the order in which you toggle lights doesn’t matter. Assuming you start with a board configuration A, if you toggle light 1 and then light 2, this is equivalent to toggling light 2 and then light 1. Also, somewhat obviously, tapping on the same light twice (or any even number of times) is the same as not tapping it at all. Likewise, tapping a light an odd number of times is the same as tapping it only once. What this mean is every solvable board can be solved by tapping a subset of lights only once. Pretty nifty.

Design and Structure

I have a really bad habit of over-engineering my code. I actually started this project last May, but I didn’t get very far. I started looking at the code again about a week ago and was pretty overwhelmed. It consisted of about five different classes that did somewhat obscure things in very obscure ways. I started by pruning away almost all of the existing code, and began working in a single file. Surprisingly, this made my code more readable than when it was split up between classes. It was easy to follow the code which greatly aided debugging. I think that having everything in one place will also make it easier to maintain (to a point). I’ve always had a thing about making my code “look good” and to me, long files always failed to achieve this. However, I’m starting to see the beauty of consolidating code and replacing lots of little classes with lots of little functions.

As far as the design of the game, I’m actually pretty happy with it. One aspect that I didn’t like was the fact that I couldn’t find a way to add multi-directional arrows without cluttering the design. If you play it, you’ll notice that arrows are always either up/down or left/right. Never both. There’s nothing difficult about this from a programming standpoint, but I absolutely could not find a way to elegantly add it to the design. I’m not too upset about this, but I never really like when form gets in the way of function. Perhaps a better designer than I could come up with a solution.

Development

The development process went fairly quickly, which is a first. I did get to play with a few things that I hadn’t before, though. For example, this was the first time I had ever used CSS3 transitions, and boy are they cool! It made the Javascript so much simpler to have all of the animations handled by CSS. I know I’m barely scratching the surface but I can see now why people have been so excited about them.

I also got to work with cookies to keep track of users’ best scores. The way Javascript handles cookies is very interesting for me. Cookies are stored in document.cookie as a “string.” I put string in quotes because there’s some sort of voodoo going on behind the scenes. Namely, when you define a cookie, it’s generally of the form name=value; expires <UTC DATE>. You then assign this value to document.cookie. But what if you want multiple cookies? Well, you do the same thing. But you only specify one at a time. So, as an example, the following snippet would store three cookies:

document.cookie = "name=John Doe; expires Sat, Dec 20 2014 12:00:00 UTC";
document.cookie = "age=24; expires Sat, Dec 20 2014 12:00:00 UTC";
document.cookie = "gender=Male; expires Sat, Dec 20 2014 12:00:00 UTC";

What gets to me is that it looks like we’re assigning to document.cookie each time, but it never gets overwritten. Furthermore, if we were to then read document.cookie, we would see

"name=John Doe; age=24; gender=Male;"

What happened to the expiration dates?! Your guess is as good as mine. What made cookies really annoying is that there doesn’t appear to be a way to test cookies using the file:/// protocol, which makes local development very difficult. (As an aside, Google Chrome supposedly has a flag to enable file cookies, but I couldn’t get it to work).

Takeaways

I think the biggest thing I gained from Lights was finally finishing a project and releasing it to the public. I don’t think I’ve ever done it before and it’s a really good feeling to finish something and be satisfied with it. I would deeply appreciate any feedback you may have, you can contact me on Github or via email. At the moment, my best score is 31. Can you beat me?

Copyright William Ganucheau 2014-2015