I’ve been digging around my machine trying to find any fun old projects I could throw on my GitHub page. What I’m mostly finding is how I get grandiose ideas for programming projects and then abandon them in a week. Some of the programming I did in college is absolutely laughable, but it’s also amazing how many things I’ve started that I’ve completely forgotten about.
I wrote a while ago about Nuke ‘Em, which is a dumb idea for a turn-based strategy game that I’ve chased every time I’ve moved to a new language or platform. I think the closest I’ve gotten to something running is a Ruby on Rails attempt I played with in 2008. But last night, I was digging through some C source code I wrote in 1999, trying to get a web based version of this going, and it was… interesting reading.
Looking at the code, it’s amazing how many ways I was reinventing the wheel, or painting myself into a corner. A few observations:
- The project was a bunch of C source that would compile into a half-dozen CGI files that would then go onto a web server. When a user went to /user/login or whatever, that would run the login CGI binary. Why didn’t I just write a bunch of Perl scripts or some PHP for this? Well, I guess I already knew C, no use in learning something new and relevant.
- Actually, some of the pages were generated by shell scripts which had forms where the action was to hit one of the binaries.
- I doubt anyone would try to do something like use cURL to download the actual login binary, open it in a binary editor, and mess with it, right?
- There was no templating system for generating web pages in 1999 (that I knew of; there probably was) so I had a routine to glue a head.html and tail.html template at the start and end of each generated page.
- Part of the decision to do things this way was based on the limitations of my hosting provider, and part of it was price. I’m sure MS FrontPage would have made this all easier, but I think I was unemployed when I was doing this.
- There is what I think is my first attempt ever at writing a Makefile from scratch. It shows.
- The whole thing used a series of ndbm databases to store everything, including users, passwords, the map, and pending user turns. This databases were created in the /tmp directory and were world-writeable files. Nobody would think of looking around the /tmp directory of a public web server, so this was totally secure.
- ndbm (or its predecessor NDBM) was basically like the first NoSQL database ever, sort of. (I would think a garage full of punchcards in random order would be the actual first NoSQL database, but whatever.) Anyway, it wasn’t relational, and didn’t have tables, so each “table” was just another file in the /tmp directory.
- When you set up the world by creating initial users and making a terrain map and such, you would just run another binary which spat out the configured db files. Only an administrator could do this, because the files were different executables not installed in the hosted web directory. It didn’t check in any way if an admin was running the scripts, but it’s not like someone other than the admin would compile and run the source themselves and overwrite the world-writable files in the /tmp directory, would they?
- There is a whole science to map-building, how to algorithmically scallop out water and land edges and mountains in some pseudo-random way to make a cool map of a world on the fly. This randomly generated a single-digit number for every square on the map and put that terrain in place.
- For everything, and especially in the login, parameters like username and password are passed in the URL, because nobody would screw around and pass a bunch of garbage in URL parameters. And there probably weren’t search engines crawling and permanently storing parameterized URLs to do things like delete all users.
- Oh, that password parameter is sent plaintext. It’s got to match the password in the publicly-readable database in the /tmp directory, which is also plaintext.
- Players each have money they spend to build armies and buy missiles and stuff. Guess where that number is stored.
- There is a separate library file (a .c and .h) that is chock full of dumb stuff that isn’t in the standard library, but I’m sure there are 863 different public libraries that do it, and if this was NodeJS or Ruby or Python, it would either be a built-in or it would be an npm/gem/library away. Like why did I write a routine to convert encoded URL parameters into arrays? Why did I write my own routine to convert ASCII strings into integers? Why didn’t I write something to encapsulate database calls, instead of pasting the same dozen lines across multiple files?
- I don’t know why I did this, but the maximum length of a URL is malloc’ed to a size determined by reading an environment label, and I have no idea where that was set. (!?)
- Not sure what C unit testing framework existed in 1999, but mine consisted of a file called test.c that ran a bunch of code and printf’ed the results to the console.
- I never got to the point of putting in the turn-based logic, but my loose notes showed that I wanted to have a cron job that would fire every ten minutes (or whatever) and run a program that evaluated all of the turn moves and calculated out the combat losses and money spent and all that stuff.
- No source control, of course. Lots of ~ and # emacs files, and lots of files copied with a .backup extension.
Sigh. Okay, a few bits of advice to myself twenty-some years ago:
- The first is to learn PHP (ugh) or wait a few years and do it all in Ruby on Rails. I know Rails isn’t cool anymore, but it would have been so much easier to build models for all of the basic data types, then scaffold the whole thing, implement controllers for the bits of logic, and take the scaffold views and make them pretty. Of course I still can’t deploy Rails apps on my hosting provider, so that’s another issue.
- Find public libraries to do the nasty stuff. It wasn’t as much of an option then, but it is now. The rub here is it never feels like I’m building things anymore; I’m just connecting together things that other people have built, and then trying to keep up with when libraries change or break. Having a solid ORM library, a templating engine, and something to deal with session persistence would have saved me a ton of time. (See also using Rails for this.)
- Break things up into smaller tasks, like as MVPs for each piece. I sort of did this, looking at my notes, but I probably would have went deeper if I had really planned this a bit. I usually do it all seat-of-the-pants, and then get overwhelmed when I have nine different problems going on at once.
- Think about security first. I know my thought was to have it all use no passwords or plaintext, and I’d lock it down after I got it running. I should have thought about that earlier, so I didn’t paint myself into a corner.
- Source control, dummy. RCS was a thing then, and I was already using it for my writing. Check in often. It’s free.
(PS, I’ll probably start writing this same dumb game as an Electron app the next time I get bored.)