Well, I still haven’t quite recovered from the weekend trip to another time zone and the seasonal time change (organized, clearly, by people who think cutting a piece off one end of their blanket and sewing it on to the other will make it longer) at once, so I haven’t been quite up to par coding-wise today. But I did get one important thing done: the first bit of framework for what will become the TableMaster table engine. I can call it from the main program now (even though it doesn’t do much) and put the data where it needs to go. Now it’s just about writing code. Or, more correctly, re-writing the code I wrote over 20 years ago, better.
I’ve lived so close to TableMaster for so long — its earliest incarnation dates to the 1980s, and a Sinclair QL — that it’s easy for me to forget that not everyone actually knows what it is I’m going on about.
The way I usually explain it: any random generation table in a game is actually a program meant to execute on a system of humans and dice; TableMaster makes it possible to set it up to run on a computer instead. And moreover, you can go far beyond anything that a game would provide, because the computer can do in seconds what it would take you an hour of dice-rolling and note-taking to produce.
Since this whole description is obviously going to be rather useful, I’ve moved it over to a page (you can find it here) so that people won’t have to search through all the posts to find it.
The GUI isn’t feature-complete yet — it still needs the table editor and the dice roll setting dialog — but it can run tables now. At least, it could if the table engine existed. So that’s the next step: writing (or re-writing) what used to be GENERATE, and of course is now going to be a part of one integrated program.
I’ll probably take a bit of a break this weekend (I have to catch up on some of the “real life” stuff) and then it’s on to the real guts of TableMaster.
Watch this space!
I’ve been partially, but not completely, black-boxing the development of the TableMaster GUI.
Here’s what it looks like right now:
Some things never change. There was one thing I’m doing that I couldn’t figure out a really elegant way to do; the only solution seemed to be brute force and awkwardness. So I broke down and looked at my old code to see how I’d done it back then. Yeah. Same way.
Wow … I’d forgotten that I had so many popup menus in there. Right-click menus were kind of a new thing at the time and I kind of went nuts with them.
My design philosophy for the TableMaster GUI, which hasn’t changed, is that it should be up to the user, not to me, exactly how they want to do something. So for any given function, there would be multiple ways to do it: from the main menu, a popup menu, clicking a button, with a hotkey … pretty much any way you thought you might be able to do something, you could. This made for a very useful UI for the user, but a bit of a hairball for the programmer.
The fun (ha!) part at this point is that about a week before I decided to go ahead with the TableMaster project, I got a new computer desk. It’s really an awesome drop-front desk that I found in a cluttered antique shop and fixed up a bit, with little pigeonholes and things and even an almost-secret drawer, but putting it in place necessitated moving several shelving units, building a new bookcase, and disrupting, well, pretty much everything. So my old CD backup of the TM/Win source (which modern Delphi would probably choke on, but at least I could look at what I’d done) is down there … somewhere.
Given a few of the things I’ve found, though — for instance, I’d completely forgotten that I had a built-in table editor with some fairly interesting features, though now I remember it and remember that I wanted to take that farther than I ever did (envisioning something like the Delphi IDE for table writing, which might have been, um, overkill? just a little?) –maybe I should stop coding and start digging.
So here’s another question for the hypothetical readers I imagine I have: Did you ever actually use the TM/Win table editor? Or did you just use Notepad? Is there a reason for me to put that in the first release? In a later release? Never?
The GUI is almost finished. I’m hooking up the configuration saving right now, and I still have to do the dice buttons. It’s coming along nicely. Of course, I did this already, 20 years ago!
I decided to use an .ini file instead of the Registry for config. TableMaster being what it is, it should be as portable as possible. Registry-based configuration is naturally tied to a specific computer. Therefore, it will be using an .ini file instead, so you can put the whole thing (including all your favorite tables) on a thumb drive and take it with you. Plus that will make it a lot easier if I want to port it to another platform in the future, which is a definite possibility.
Of course, this is the easy part, but it had to come first before I can start building the table engine itself. It looks like I’ll be moving on to that next week. Things are coming back to me a lot faster than I expected (I haven’t really programmed in anything that isn’t Perl or PHP since the original Wintertree days) and I’m remembering “oh, yeah, that’s how I did that” (sometimes interspersed with “… but why?).
A little TableMaster history: Back in the day, the table engine was actually a separate program; in fact, that program — GENERATE — originally existed without any sort of front end at all. When I built the original for myself, it just ran off the MS-DOS command line: GENERATE 10 GEMS. Things were so much simpler back then, eh? After all, when I started development on this, there was only Windows 3.1 and that was just a shell over MS-DOS. The first Windows front end was written in Visual BASIC, and it didn’t work very well; Visual BASIC didn’t work very well. I chucked that and TM remained a DOS program (I have to give a shout-out here to my old friend Bill Swallow for his excellent MMI library, which I used for most of the screen handling in TM/DOS) until Borland Delphi came out in 1995.
I suppose I should be coding instead of reminiscing. Given the number of people who are reading this (current count: 0) compared to the number who will buy TableMaster when it’s ready (hopefully some number > 0) it would seem to be the more profitable course of action, certainly. But here I am, listening to Celtic music and taking a break from TableMaster coding, and all of a sudden it’s 22+ years ago. Except I don’t have to worry about running a BBS for support nowadays!
Random historical trivia: my first development machine for TableMaster was a 6 MHz 80286 with Hercules monochrome graphics, 1 meg of memory, a 5.25″ floppy drive (which I still have somewhere!), and a 20 meg hard drive.
Here’s what the GUI looks like right now:
I’m trying to stick fairly close to the old layout. I’ve moved a few things around, and I’m thinking of doing something a bit different with those upper buttons (probably involving a toolbar) because there are better ways to do it now, but mostly, it’s going to look like the TableMaster you remember.
Well, the TableMaster for Windows. Sadly, TM/DOS is no more, not least because real DOS is no more. Personally, I always preferred that; I did my table development with that interface.
A story from the old days: back when I first sold TableMaster, at the very first convention I had it at* I had built this pretty graphicsoid-text UI for it. I don’t even have a screenshot of it anymore, but I remember that it was quite pretty. And, well, kind of annoying to use, but pretty. That wasn’t what I used for myself, though; I had a really ugly one, just a screen full of table names and a few options, that worked well for me. So there I am, and I’m working on some table during a slow time, and a user asks me “how come you’re selling the crappy UI and keeping the good one?” I learned something back then: pretty looks good for the reviewers, but functional looks best to the users. And that’s who it’s all for, after all. So that “ugly” UI was the front end for TM/DOS, and every user interface I’ve built since then is designed to be functional before pretty. It’s all about using it, not admiring it.
But I still like the old TM/DOS interface better.
*I signed up so late for that convention, the dealers’ room was full and they put my table out in the hall next to a LARP group that had a 30-second video on endless loop; to this day I hate the background music from it.
Back in the day, I wasn’t all that good at setting proper version numbers. The original TableMaster was up to 3.something, when it really should have been 1.3.something. That leaves me with a problem today, though, in that there would be some confusion. “TableMaster 2? But I already have TableMaster 3, I bought it in 1998!”
So, to keep things sorted out, I’m going with Roman numerals in the name. It’s TableMaster II, and version numbering will start over and be where it should be.
Beside, I’m black-boxing a lot of it — that is, starting with the known input and expected output, and writing what goes in the middle without reference to the previous code — because, frankly, there are places in my old code I’m afraid to go. There are a lot of better ways to do things than what I did in the process of learning Turbo Pascal in 1992, which is how the first proto-TableMaster got started. (and obviously I’m not using Turbo Pascal anymore, either!) So since it’s going to be mostly new code anyway, it’s definitely a new program; just one that does what the original did, only better. And without the grues lurking in the dim recesses of the code.
So: TableMaster II.
15 years ago, when I shut down Wintertree and totally gafiated, I didn’t think anyone would ever be interested in TableMaster again. I was surprised a few months ago to find out that people have been looking for it, or some replacement for it, ever since. Wow. I never knew. I thought nobody would care when operating systems left it behind (my 64-bit Win7 looks at 16-bit TM/Win and pops up an error message that amounts to “Really? You’re kidding, right?”) and even gaming itself moved on; CCGs seemed to be the future. Wow, was I ever wrong!
But old-school gaming is back and going strong. More people have computers at hand during their games than ever. And there are still people who want TableMaster.
So, I’m hard at work on a new version of TableMaster. I have most of the GUI put together already, and I’m hooking up its features. That’s the easy part, of course, but I need it to be able to work on the development of the table engine itself. I’m doing a complete code rewrite from scratch. Aside from the fact that some of my old code is buggy, and some of it is just plain embarrassing, there are better ways to do things now, and I’m a better programmer. Besides, the original was basically an MS-DOS program kind of faking it. That was so 1993! And don’t worry, I won’t be doing that thing with the clipboard anymore.
I’ve set up this blog so I have an easy way to talk about development, get any feedback that y’all might want to provide, chat with people, etc. Pretty much the kind of thing I used to do at conventions or on CompuServe back in the day. There will probably be a whole flood of posts for the first couple of days as I release a backlog of commentary, then it will settle down and I’ll post when I hit some significant milestone, or have something to say.
I do, however, have a question for anyone who’s reading this: Should I put in lookup tables? They never did work quite right, and I never used them — I’m not sure if anyone did. They were a mess to code and not much better to use, so frankly, if they’re not going to break any tables, I’m going to leave them out. So … did you ever write a table that used .lookup?
Please answer the above question in the comments for any other post (the next one would be good), because I’m using this post as a spamtrap — all comments in reply to this post will be deleted. I say again, ALL REPLIES TO THIS POST WILL BE DELETED because it is serving as a spamtrap, to make it easier to keep that crud out of the real discussion.
(note: I have no idea why the date for this is coming up as February 3, since I didn’t even register this domain name until March!)