Deck & Conn, Log 4 – A Touch of Class
So, the last few days I’ve been working on Deck & Conn, but… not much that’s exciting. Not to anyone seeing visual progress, that is. In fact, really only ONE new front-facing feature was added. What I was actually doing, however, was quite interesting to me, and very useful for the project as a whole. So here’s a run-down, starting with back-end changes and ending on the major front-end one.
Almost Everything Is A Class
When I first began this project, I took one look at Lua’s relatively non-existent classes & inheritance, and just… decided to do it all procedurally. Which is fine, I suppose, except that I’ve been doing OO stuff for two decades now, and thinking procedurally for large projects all but gave me a headache.
The thing is, though, Lua does have classes. Well, sort of. As someone on mastodon impressed upon me, while tables (the main data structure in Lua) have no real copy, instance, or inheritance features like in C++, they do have metatables… with which you can do an awful lot of class-like things.
And so, finally realising that my instinct to avoid the feature entirely was a bad plan. The language was clearly engineered around metatables as a core element, and in my experience it’s almost always better to utilise, rather than fight against, the way a language is engineered.
I spent a day or two moving most of the simple structure-like things I had into (effectively) classes, with constructors and default values.
In the end, I grew to appreciate some aspects of this approach.
Everything Is A Widget
When I first coded the basics of the game, last-week-Elissa made non-interactable objects ‘gfx’ objects, and when I made the button objects, I made them ‘ui’ objects.
Last-week-Elissa was wrong. I’ve now moved all of these to, same way I would were I doing this in C++, UI objects that inherit from a Widget super class. Widgets can be interactable or not, and on that basis they are put in lists of general widgets to render, and also ones that need to be consulted when mouse over or touch events happen.
It’s worked much better. Now, my widgets are all items in a subfolder, along with a _template file I copy every time I want to make a new one.
It has, as intended, reduced the amount of duplicate code and made the process of making new visual elements entirely different. The other major advantage is that given widgets are passed settings, filenames for visual elements, and pointers to functions to retrieve data about states and the like, it means all the UI code is now not game-specific – it’s quite portable. Should I want to make another game using Löve and Lua, I could bring all my UI code with me, giving me a huge head-start over doing this all again.
Everyone Loves to Type
And finally… the big visual addition: text interfaces for terminals.
The overall use for this in-game is to be able to type in commands to your ship when other interfaces get damaged, and operating the mail / communication terminal.
To my delight, I found Löve made implementing this staggeringly easy. When implementing this in Objects in Space (using C++ and Cocos2D-X) I had to deal with implementing such things as key repeats, and even just basic things like “which buttons do I want to pass through?”. Alphanumeric and space, for sure. But what about colons? Brackets? Carets?
Löve has a cute little side function to the expected love.keypressed function – it also has love.textinput. Using this, I was able to use a well-coded key repeat feature and even a basic vetting of what characters I might want to use in a terminal. In all? Implementing typing and even side scrolling when you pass a full length of a line took me about 2 hours. That’s some good stuff right there.
And now what?
There’s typing in terminals. There’s buttons. There’s gauges. There’s lights. There’s data for the ships and crews. Which means it’s time, without any further ado, to generate sectors – planets, stars, etc, and implement actual ship controls.
Not gonna lie, I’m excited for this bit.