Happy Friday everyone!! As usual, it's been too long since my last wall of text, but boy have I been busy since then...and I'm very much hyped to show you all what I've been up to
Last time, I spoke of moving forward with the fun stuff -- that juicy gameplay -- and mentioned that 'perhaps the biggest challenge remaining is moving our PAX demo into mod format.' Yes folks, after 5 years of this, I've actually gotten moderately decent at predicting where I will stumble. And stumble I did...over and over and over again, until I was dreaming of mod files with teeth chasing me down. I tried looking at the problem (of writing in mod format) every which way: upside, downside, yonderside, and they all upset me in their own special little way.
So I said "frak it," and decided to drop modding support...
...in literally zero of the infinitely-many parallel universes of the quantum multiverse, including our own. No one believed that, right?? I'll lay down and die before I give up on making LT the 'OpenSpaceSim' we all want! But in all seriousness, I did get tired of trying to solve the problem of making modular additions to it easy to write with some text format. Frankly, I'm just tired of text. At least, I'm tired of text that represents code. It bothers me every day. I spend most of my life looking at Vim. Yes, I have a deep affection for Vim; yes, I have a tricked-out .vimrc and a lovely custom color scheme crafted to my tastes; but at the end of the day, it's all rather uninspiring. There's a pretty severe disconnect between the Josh that wants to teach the computer to build a beautiful, awe-inspiring universe and the Josh that sits in front of a slate-blue wall of code 8-to-16 hours a day
The harder I pushed to write the game in a modular format, and the more I tried to nail down that modular format, the more I came to realize a devastating (at the time) truth: seeing the big picture and being able to build the big picture from small, incremental changes are two goals that are fundamentally at odds with one another when one's way of seeing the big picture is the same as one's way of changing it. I guess that's a bit obvious when put abstractly, but at the concrete level of writing game code, it felt like a disheartening revelation. But all was not lost. You've glanced at screenshots already, you know what's coming, so let's quit beating around the bush.
I spent two weeks prototyping the viability of a dedicated editor for Limit Theory. At the end of those two weeks, I had something that worked, something that enabled me to see the big picture all at once, while being able to translate my changes behind-the-scenes into the tiny, incremental changes necessary for good modularity. Those two weeks changed the whole ballgame. You may or may not remember that I showed a screenshot or two of a 'failed experiment' in building such a tool in a KS update a while back. So what changed? Well, the viability of building such a tool shifted dramatically when good ole' Adam mentioned to me a library specifically made for getting functional, practical GUI tools up-and-running with minimal effort -- Dear ImGui. Previously, I had used Qt. Qt is great; it's a behemoth of industrial-strength functionality. But the time cost of building things is orders of magnitude higher. Two weeks using Qt left me feeling that I was going to spend more time on tools than I would save on getting LT out the door. Two weeks using ImGui left me feeling that I had an infinitely-more-powerful workflow that would make the road to release so much more enjoyable, shorter, and paved with less frustration. Two weeks with ImGui made me a happy Josh
So then, let's have a look at the new, blossoming development tool that has allowed me to sleep soundly at night!
We'll hop right in to the main editor view:
There's a lot going on in this screenshot, and it's more cluttered than the normal workspace would be since I'm trying to show off a lot of the functionality all at once. In the center area we're looking at the definition of a 'Ship' entity. We can see everything all at once -- the components that make it up, the data and functions imparted by those components, along with Ship-specific data. It's a 'big-picture' view (from the code standpoint) of what a Ship is in LT (note: it's not complete, as I'm not finished building the 'Core' LT mod file yet!)
Something really important to note here is that I've actually got a small test mod loaded in the editor, but that test mod depends on 'Core' (Vanilla LT). Since it depends on Core, what I see in the editor is the result of Vanilla LT plus my changes to it. Big picture view!!
But! Glance over at the center-right panel, and you will see the actual mod file that I'm producing. It's a Lua file, automatically-generated by the editor, that tells the engine all the things that my mod adds/changes/removes. If you take a look, you will see that it's essentially just a list of tiny, incremental changes. Extremely granular, and just about as ideal for seamlessly merging the changes from lots and lots of different mods as one can get. Therein lies the real beauty of being free from a pure-text/code workflow: the big picture that we see is completely decoupled from the description of building that big picture. We get the best of both worlds: the ability to understand everything in the game at once, the ability to modify any piece of it, and the generated mod file that describes those modifications as compactly as possible, thus maximizing modularity.
(If you're wondering, this mod was a test of cross-platform compatibility, making sure that I could load/save a mod, swap between Windows & Linux, and keep working without issue, since I use the latter while Adam & Lindsey use the former. It was a successful test, fyi )
From here on out I'm just going to show some of the functionality of the editor and talk a bit about how it works, why it makes life easy, and so on. Using this tool, we can quickly create new entities, components, events, functions, fields, etc. There is never a question of what file it should go in, how we should structure the syntax, etc. "Minimal degrees-of-freedom" is a major design goal I have for our workflow. Here I'm adding a new function to the Inventory component, to make it easy to transfer items between two entities:
The code view is rough and there's no syntax highlighting or autocomplete or anything like that -- but frankly, the whole point here is to get away from unstructured code as much as possible. As time allows, I'll improve things like that, but my core focus is on making it as fast and intuitive as possible to build new game content, while ensuring that understanding existing game content is always tractable. Note that I'm doing this for me more than anything, because I need a workflow like this to keep a handle on the beastly featureset of LT. It has overwhelmed me once before; but not this time -- this time I have all the power in the world to keep it simple and manageable
After I've added my new function, it shows up in the Inventory component or as part of the 'All Component Functions' listing in any entity that has an Inventory:
On the right I've got a panel showing me the new function. The central area of the editor can have as many 'vertical split' panels as your screen has room for, so it's very easy to look at, for example, an entity and a specific component within that entity side-by-side, or compare two entities, etc.
Ok! Let's do a quick little demo of extending the game (note: in reality, the contents of this mod will be part of Vanilla LT, but this is just for demonstration!)
Creating a new mod that extends Core:
A few minutes later, I've built a new component to hold the data & logic governing a 'population' (like on a planetary colony, or perhaps even a large station). I've added it to the 'Colony' entity, and now every Colony in the game will have this data and run the logic that I made! On the right, you can see the generated mod file:
Notice how everything can (and should) have a description, and how these descriptions pop up as tooltips when you mouse over just about anything in the editor. This is all part of keeping the 'big picture' as clear and understandable as possible! If/when you open Vanilla LT in this editor, exploring and understanding how it works will be a lot more fun than just reading some documentation (of course, I'll provide that too).
I can save my mod and load it again later when I fire up the editor. I'm greeted with this, reminding me of how awesome my little mod is going to be
And there you have it! I've now got a single Lua file that changes Vanilla LT to (presumably) make it even better! Ship it!
I mentioned earlier being pretty disheartened at the lack of an 'inspiring' workflow. We are now in a position to obliterate that issue! On top of the ImGui Lua bindings, I've also written some OpenGL Lua bindings that, among other things, let us put some 'game' back into 'game development'! Here I'm perusing LT screenshots in the file browser:
Goodness, that's refreshing to see some beauty inside the development tool Here we have some really basic OpenGL integration (not exactly beautiful, but the point is that we can use this same tech to visualize LT-related things in-editor):
And finally, a fun addition that I wrote last night (it took all of 30 minutes to do since this is Lua, after which I spent hours playing with it in the editor ): a real-time shader editor for ultra-fast prototyping...and maybe just maybe for boosting a certain graphics monkey's spirits if he's having a rough day
These are just tiny demonstrations of the power that we now have on-hand. If and when we need to see something, to simulate something, to prototype something, to measure something, we can do it in an awesome way without sinking huge chunks of time into scratch/sandbox applications (and without inducing a mental context switch to that other application!)
In closing, I'll summarize a few points just to make clear where we stand with development, the editor, and the productivity level of my past few weeks! Here's what we've got now:
- A finished mod format that's functional, granular, and generally awesome
- Support in the mod format for whatever 'categories' of game content we want to add in the future, for example, Item Types, AI Behaviors, Procedural Generators, Settings, and so on (if you look carefully you can see that the mod format handles these all in the same, unified way)
- Ability to create new mods (that can have any number of dependencies, or none -- Core is built the same as any other mod, it just doesn't depend on anything!), load & save them, automatic backups, visual highlights on changes made by the active mod, arbitrarily-deep undo & redo (which is actually tightly-related to the mod format), ...and so much more
- All of the above written in Lua, making it super-fast for me to add functionality; ImGui functions are bound & injected into Lua automatically
- In-editor OpenGL integration and Lua bindings for OpenGL, making it possible for us to create development visualization & simulation tools limited only by our imaginations (procedural algorithm rapid iteration, material editors, historical simulation sandboxes, dynamic economy simulations, you name it! As a bonus, since it's in Lua, we can run pieces of the game code directly in the editor, no extra work required!)
- An engine-side loader & compiler that takes in an 'active mod list' and compiles the merged data down to code that interfaces with all of our existing tech (ECS/CTypes, engine-side functions, Lua utility libraries, etc.)
- An inspiring workflow!!
- A 'Core' mod representing Vanilla LT that is already well-underway
- A dramatically-nicer workflow and a happier Josh
And in case this wasn't implied, LT will ship with this editor for your use in modding.
Wow. That was quite a mouthful. If you made it this far, thanks for sticking with me! It's always interesting to look back on the devlog process; it really gives me insight into how I'm actually 'feeling' about development, which can sometimes be difficult for me to process, even when...I'm me (which is most of the time :V). To see such an explosion of excited JoshTalk in a relatively small devlog session, and to see it come so naturally and enthusiastically...it boosts my spirits even more. The road to release has thrown us more than a few hardballs, but every now-and-again, we catch a break. I couldn't be more thankful for this one.
I anticipate the next few weeks being focused on continued development of 'Core.ltm.lua,' getting all those lovely entities and components fleshed out, and continuing to leverage the editor at every opportunity to make life easier and development more enjoyable. The next big milestone will be when I can hit Ctrl-R in the editor and have the game launch moments later, running off of compiled mods, thus completing the feedback loop of fast development iteration.
Keep your lasers hot and your missiles locked my good fellow pilots; it's never been a better time to be building universes
You've already seen all of the screenshots, but here's the link to a gallery of this log's images: Limit Theory Devlog Gallery ~ March 9, 2018