i want to make a jrpg, and have eye damage.

Posted 2020-04-20

I saw an eye doctor today after a week of pain. I have damage likely from being a computer worker. Should be treatable but if you have eye pain and/or dry eyes... talk to your doctor without waiting months like I did, it is likely to just get worse. And if you are feeling fine, remember to blink while working and frequently look away from the screen to stay that way!

Also gonna tell about my long-time desire to make an old Final Fantasy style game.

Core D Development Statistics

In the community

Community announcements

See more at the announce forum.

What Adam is working on

Personal Background

The Before Times

A major reason why I got into programming in the first place, back in 1999, is that I wanted to make a game in the style of the original Final Fantasy; a 2d jrpg.

When I got a computer at home, a hand-me-down Pentium 1 computer, around 2002, I made some real progress - at first, a text-mode display you could move around (which I called "m" for "movement"), then moving on to a graphics mode (320x200, bios mode 13h on DOS lol) implementation of the same idea (which I called "m2"), along with a really simple map and tile editor, all keyboard driven 16-bit DOS applications (compiled with Digital Mars C, of course!)

Pretty exciting! In 2003 though, I wanted to get with the times and start using the Windows 95 API instead of DOS (the computer always ran Windows 95, I just did my programs 16 bit and it all just worked). Meanwhile, I let my fantasy run wild and told myself I'd make the ultimate game - merging everything from FF1 and Dragon Warrior and the Phantasy Star series - I'd just do it all in this new system. I even flirted with the idea of making the code generic too, running on DOS and Windows and maybe even the Sony Playstation! I'd do everything and do it all perfectly.

This "m3" idea, as you might expect, never came to pass. I floundered for a few years getting absolutely nowhere. When I switched to Linux in 2005, I added that to my platform support list but that just made the already impractical ideas even harder.

I switch to D

In 2007 (a huge year for me personally for a lot of reasons), having a bit of nostalgia for the old m2, started messing with DOSEmu and DOSBox and I went to the Digital Mars website to see if I could grab an update to that old compiler... but this time, that "D" link on the side actually kept my attention (previously, I had discarded it because it looked too much like Java and I was ridiculously biased back then. I used to be one of those "GC is useless and only used by idiots" people!)

And, of course, I loved it. I immediately wanted to make m3 in D. I made a little game library based on SDL and made.... a real-time strategy game. My sights were still too high for m3, but I knew at this point I'd definitely make it in D. I slapped together a Lisp-like interpreter for use in the game among other pieces.

But, around this same time, I also started working full-time as a web programmer and my hobby games got sidelined. My fictional company, ARSD, became the namespace of my D packages and became more focused on web. Especially after I couldn't stand PHP anymore and wrote dom.d and cgi.d so I could start doing web stuff in D! But the game stuff sat dead for a couple more years.

Revival with D libraries

Around 2011, I wanted to revisit the game idea again, and this time, get away from all the random third party libraries. I started making arsd.simpledisplay.

As time went on, I made more stuff, some just for fun, some for other proposes, but some part of me was still looking at making my game. arsd.script was primarily just because I could, but I also knew I needed something for my game eventually. arsd.minigui and arsd.png are multi-purpose, but I knew I'd need a lib to make the game editors. arsd.ttf, arsd.apng, arsd.joystick, and arsd.simpleaudio all exist specifically to support my game ambitions.

These have been slowly built up over the years and just recently passed the bar where I feel I can start working on the game itself, rather than the support libraries. (It isn't actually 9 years of work btw, just I'm also busy with a lot of other things. I basically get to spend a few days on this then don't come back to it for months.)

Where it is now

I labeled m3 a failure and a lesson in the "second system syndrome" and now am making m4. I reined my ambitions back to my original idea of being like the NES games and having it work just on Windows and Linux. I'm still doing all the libraries myself, aside from OS-level stuff, but that's essentially ready - the arsd repo isn't perfect for it all, but it is good enough to make real progress now.

So, last weekend, I finally started writing code for the game itself! Despite my eye problems, I made a lot of progress in a little time thanks to the capabilities of my D libraries. I'm already able to move the character around a map by keyboard or by gamepad, which is created and edited in a gui, using art I can create in my own gui, and certain tiles trigger events written in script.

There's still a long way to go, but for the first time in 17 years, I feel like this game is actually moving forward again! And the code is pretty cool. Let me show you a couple tidbits:


minigui's dialog function pops up a window to build a struct. It inspects the parameter type and constructs a dialog based on the static types and then calls the given function when the user presses OK.

var toArsdJsvar() {
        return var(definition);

static MapEvent fromJsVar(var v) {
        if(v == null) return null;
        auto me = new MapEvent();
        me.definition = v.get!Definition;
        return me;

arsd.jsvar will call these functions on an object if it exists, making my save/load functionality very simple even with nested objects. The member struct definition in there holds what is saved in the file, then other members can be runtime state. arsd.jsvar.var.get is a templated type that uses struct introspection to load the dynamic data into the statically typed world.

interpret(event.definition.scriptOnStep, scriptGlobals);

arsd.script builds upon arsd.jsvar to interpret scripts as well as just working with dynamic data objects. That simple interpret function, passing scriptGlobals as an object that contains user state across calls as well as what you want to make available, is all that's needed. The modules are self-contained so no library hassle.

Adding stuff to the script environment?

var scriptGlobals;
scriptGlobals.party = wrapNativeObject(party);

I mark items @scriptable that I want to expose there, then can restrict the user API in the script world at very little work. And I can use adrdox to generate all the api documentation too.

If you've been following my D work for a while, none of this is terribly new. But it is now actually being used for what I got into programming to do!


The build process is trivial: dmd -i main.d. All stuff just works on windows and linux (assuming the arsd directory is right there too).

Can I play it?

not now. maybe never. i haven't decided if I will even release this yet, it is mostly just for me. But who knows I might share it later. Maybe other people could make NES style games too - the same map editor might be usable for a game like Legend of Zelda too... and maybe even a Warcraft style game (with new D code but I am pretty sure much can be shared).

Hopefully I can just find some time to actually finish this up.