I got some more Platformer stuff done. First, here’s what the level editor is looking like:
Right now you can only edit collision tiles, but I’m working on adding the visual tile and entity placement stuff.
And also, here’s the Sprite Crammer tool I’m working on to put multiple frames (relatively) efficiently into texture pages, using some sprites from Ravuya’s Glow. The benefits of this are twofold. First, it cuts out extraneous transparent borders on images, saving some information in an XML file so you can draw them back at the correct offset; that saves you some video RAM. Second thing, it reduces the amount of texture switches necessary, which is nice if you have lots of sprites onscreen. Some other nice features it has are a commandline mode (for using it in build systems), and Linux support if you want to run it under Mono. The UI looks a little weird due to variances in font sizes not really playing well with .NET’s absolute layout rules, but it still works, as does the commandline version.
Okay, so has anyone else noticed a curious blurring between SDI and MDI apps happening? The main culprits here are Microsoft Office and Adobe Acrobat Reader. Let me demonstrate. Normally, a program either has one window per document (thus, one taskbar button per document), or one window and subwindows for each document (only one taskbar button.) MDI apps have generally been decreasing in popularity recently, generally only sticking around for things like IDEs, Photoshop, or web browsing, if you count tabs as documents. However, if you open MS Excel or any Office program, and do a File->New (well, the equivalent now that there’s no actual menus), you’ll find that you have two taskbar icons, but one actual window.
Now, I guess they did this so the somewhat more confusing MDI system is easier to use from the taskbar. But it totally mixes metaphors. You actually have only one window, but you’ve got N taskbar icons. I think they probably should have just converted entirely to SDI, seeing as it’s gotten the better evaluation from UI experts (as far as I understand.) But the practically annoying thing about it is this:
Because of whatever black-magic voodoo is going on to make taskbar icons for nonexistant extra windows, you can no longer close an entire group of them on the taskbar, or do any of the other actions on the menu for the group. I regularly close lots of windows from the taskbar when I finish working on something, going down the line and purging stuff I don’t need anymore, but I can’t do that with this behavior.
The weirdest thing is, if you go into the Excel window (with the documents “maximized” like normal, not in a non-maximized state like the screenshot) and hit the “X” for the whole outer window, only the top document closes. So basically none of the normal “close all of these windows” actions works at all.
Adobe Acrobat Reader is exactly the same, except the “X” closes everything, which is also somewhat annoying if you had multiple PDFs open and intended to just close one. (I tend to forget an app is MDI if I use it 100% of the time with the document sub-windows maximized, like I imagine most people would.)
The weird part is they seem to have gone out of the way to make the programs behave like this half-single, half-multiple document chimera, as usually each main window gets its own taskbar icon.
Okay, so the semester started again and now I don’t have as much free time anymore. Which is not great, because when I had free time over winter break I didn’t get much of anything done. Current project statuses follow:
PLATFORMER.
I didn’t work much on this over the break. My laptop is running Linux now because the poor thing is dying and somehow it seems to work alright with Ubuntu (as in, it only freezes intermittently, as opposed to Windows which can’t get through the installer without bluescreening.) So, being that I was away for the majority of my break, and thus using my laptop, which runs Linux, I didn’t get much done on a game that uses XNA. I have done a little more design work but it’s mostly on the silly kinds of details I worry about that noone else is interested in. I’m hoping that eventually I’ll get to a point where I can release a demo (or at least a video) every month or two of the progress, it’ll depend on how classes go.
PORTAL TURRET.
Not a whole lot since the last update. I have some more details worked out for motor control but it’s still all basically resting on fabricating the body at this point. I am going to talk to someone at NCSU about using the school of design’s CNC router to do this. I am also still unsure about how the thing should be controlled - complete autonomy is sort of boring, and adding a proper remote control unit would be a giant pain because I’m not that great at electronics. Besides that, the rest of it is just details, hopefully.
SHILSCRIPT++
I got some work done on this over the break. I’m working on static checking for expressions right now. Basically I need to clean up the classes used for types and implement some kind of overload resolution function. I haven’t implemented overloads yet, as expression static checking isn’t even done yet, but the C# spec defines the available builtin operators in terms of function overloads, and that seems like a clean way to do it. Hopefully I’ll get to codegen sometime this century. Other things that are outstanding are storing location information on AST nodes for error messages with actual locations, and adding memory tracking so I can make sure there aren’t any leaks.
So, that’s the project status. I am feeling kind of crappy recently because I haven’t gotten much of anything done and I feel like I’m atrophying just sitting here not coding anything. Usually when that happens I open up SS++ a little or think about tinkering with FE or low-level rendering, but never get around to it.
HOLIDAY STUFF
I got to see Tim while I was in California. He’s pretty much always up to something and this time was no exception. Here is a brief list of things we did:
Spent forever trying to get Defcon netplay to work on a hotel wireless network. Once we finally did get it to work we found out my laptop hard freezes a few minutes into the Defcon stage, so that was kind of lame. Next time I am going to just bring a wired switch so I don’t have to start considering scavenging a hotel ethernet cable to make a crossover cable. Oh, and get a new laptop that isn’t subtly broken.
Watched Tim do some parkour crap in public places. I am pretty sure somewhere there is a little kid jumping off his roof because he saw a little Asian man do it at the park.
Walked around in downtown Pasadena while everyone was sitting on the roadside claiming spots for the Rose Parade. We were looking for some bizarre kind of shoes Tim wanted but the closest he could find were freeking expensive.
Played Megaman X ‘together’ by exchanging the controller. I totally beat Sigma on the first try. I wasn’t so hot at Mega Man X2, though, I had to actually use the boss’s weaknesses against them.
The whole thing made me really want to work on FE more, despite already having too many projects and not getting any work done on any of them.
Also, apparently captchas (or the captcha I added) aren’t good enough for comment spam protection, let alone trackback spa protection. I am really getting tired of this.
My evil plan to build an actual sentry turret from Portal is coming along smoothly, as my Arduino and parts from Digikey came in the mail. I already have the audio IC working, controlled with serial commands from the Arduino, and the eye dimmer working using one of the PWM pins. Crappy low-quality video from my cellphone, including crappy low-quality sound:
STEP ONE: Create your characters. You can choose from a wide range of possibilities, such as muscley guy in the military, or the other extreme, muscley guy who is a mercenary.
STEP TWO: Choose their heads. Flip coin to decide of head is shaved.
STEP THREE: Attach form-fitting futuristic body armor. This step is extremely important! STEP FOUR: Profit! (Unless you’re Silicon Knights, in which case: Lawsuit!)
The type system used for throwing around basic values (ints, floats, pointers, etc.) in the reflection code is much improved. To summarize, StaticType(T) (Wordpress is eating my angle brackets, bear with me) implements traits and traits functions for certain basic types, and you can create a DynamicType ‘binding’ of the static type information to pass around at runtime. (StaticType(T)::Alignment becomes dynTyp->getAlignment() where dynTyp is a DynamicType*.) Information about whether types need constructors/destructors/copy operations is included, so you can do things like create properly aligned struct layouts in memory based on purely dynamic information.
Implemented a function call system that works off of this, so it’s fairly easy to pass parameters to a function dynamically but also generally without ANY heap allocations — no boxing, pretty darn fast.
PyBind (the new binding system works entirely off dynamic reflection info rather than SWIG) is getting pretty functional. Unfortunately most of the classes aren’t currently marked up or designed to work with the reflection system, so that’s an issue
Finally shoveled all the C++ reflection-related stuff into a subnamespace (Common::Reflect), which is a lot nicer cognitively I think.
Working on a system that should supercede making *actual* scripts for many cases where it’s just value fill-in, and also allow a common base for serializing non-binary data. I could have gone with XML for the format but I ended up writing a parser for what I’m currently calling “def files”, which look very similar to OGRE scripts. It’s much easier on the wrists to write than XML, and simpler to read, but of course the parser isn’t as well-tested as TinyXML yet The reason this is neat is because 99% of the entity definitions Tim wrote in Python were actually just filling in properties, so I’m going to try to direct things towards more of a “property-fill-in” approach than a script subclass approach. (In fact, it would be really simplifying to just throw out scripts entirely — not sure if that’s doable though.) Anyway, we can do several things with a ‘centralized’ definition file system:
For named “resource objects”, i.e. things that represent individual, named, unchanging object instances (physics materials, map information), it will use a cache so you can basically go “get me object “, and it will try to locate and deserialize it if necessary, or just return the already-loaded object if it’s in the cache.
For “templates”, i.e. object definitions that end up being used to initialize multiple instances throughout the process’s lifetime (ragdolls, UI, entities), you can go “make me an object “, and it should deserialize and fill it in for you.
For miscellaneous configuration information (keybinds, highscore, etc.) it should be possible to represent these as normal reflection-enabled Objects and serialize/deserialize to specific filenames directly without having to write any load/save code, just mark up what properties exist.
I’ve also been doing some preliminary work on SHilScript++, and have a small prototype (VERY small — don’t get excited) started in C#. So far the current plan is:
ANTLR-generated frontend (grammar almost finalized)
Stack-based safe bytecode (like JVM or .NET — compact, easy to generate)
Bytecode packages represent an entire group of classes, more like a .NET assembly than a Java .class file
Eventually an LLVM-based backend. I might mess around with generating CIL from C#, which might end up being fairly easy because of the similarity between CIL and SS bytecode. (You might ask what the purpose of SS bytecode existing separate from CIL would be in this situation, and the reason is that eventually I’m gonna do this in C++ and won’t have the luxury of .NET just sitting there for me to use. So it has prototyping value, basically.)
It’s also pretty easy to implement a “reference” VM for stack-based bytecode, even though it’d probably be hilariously slow.
I’ve been looking at the mcs (Mono C# compiler) implementation some to get a feel for how they organize things, because C#/.NET and SS are “similar” as far as syntax and runtime model. I’ve also been brushing up on my optimization/machine code/compiler building/grammar building skills, which is fun because you get to feel much more smug than normal if you have a reason to talk about pipeline stalls or register allocation or branch prediction.
I’m still in the process of absorbing a minor epiphany I had earlier this month about data-drivenness. You’d think I’d have all of these types of epiphanies out of my system by now, but I suppose I missed this one because it tends to go against certain OO/minimalism ideas. Anyway, the thing I noticed was, it’s way easier to to add a few more properties to a base class and complicate that class’s code a bit rather than than deal with lots of base classes or strategy objects. Another component of it is that it’s kind of an un-mentioned pattern in gamecode to have LOTS of these kinds of properties. A year ago, if I saw that a certain game object in an engine had 50 or 100 properties, I’d have thought someone was just not trying hard enough to get it down to a set of classes with each around 10 or so. However, in the long run, it’s much easier to have one moderately complex class and be able to make 95% of the behavior variations you need by just changing values — no actual “scripting” or subclassing or anything involved — than to go and treat everything that COULD be an object hierarchy as an actual object hierarchy. This also has benefits because if you work on a team with dedicated, non-programmer designers, it’s way easier to comprehend setting values to change behavior than defining logic. In summary: when you see “data driven”, think property/value settings in files before actual logic scripts in files. And when you think of class customization, think small, shallow hierarchy that can allow for most of the detailed variations just by changing properties, not by doing virtual function overrides. I’m not sure if that makes sense to anyone, but it’s an idiom I seem to have zoned out on and now I’m happy I found it, because it makes a whole lot of things I see somewhat more rational.