Deck & Conn, Log 5 – World Gen & UI

It’s been a hot minute since I did a dev log, and that’s partly because what I ended up doing in the last little while took a lot more time than expected – or, more to the point, I got a lot more done than I expected.

In short, I worked on world generation, some pen ‘n paper UI design and fixed a pile of bugs I’d missed.

World Generation

I had previously done crew & ship generation, but that was relatively easy – this time I decided to burrow into the complex part – world generation.

But first, a little backstory as to what I’m doing.

Star Trek (1971)

The original game I am cribbing the core mechanics from for Deck & Conn generates a procedural world that’s fairly simple – an 8×8 grid of ‘sectors’ that make up a quadrant, and each sector contains an 8×8 grid of locations.

Inside each sector are a few stars, a few random planets, and sometimes a few Klingon warriors to be destroyed by your heroic Captain [InsertCaptainNameHere].

Deck & Conn

Early debug output of the world generation.

Due to some minor tweaks to gameplay (such as the ability to actually not be able to detect certain ships – or remain undetected yourself if you use the right setting and jump into the right part of the sector) am increasing the size of the sectors – and the quadrant. For now it’s 12×12, though I may expand that further later on as I do gameplay testing.

After doing basic generation, I printed out the results quickly, so I could ensure my generation techniques were working. It’s in terminal mode, as I made the nav com rendering later on.

Other differences between 1971 and D&C include that I am naming non-empty sectors and planets. I generated a system that for now will do – it’s internally consistent, so it helps the experienced player determine what they can about places just by names.

Sector names are simple – generated from a list of names and optional suffixes to generate scifi-sounding names, some cribbed from Star Trek and other shows, with others from real life.

Planet names have a few variations, but for now they have two basic principles:

  • The planets are named after their order. If they’re barren they’re given numbers – so the closest planet to the star is named ‘One’, the second ‘Two’, etc
  • If the planets are even vaguely habitable (I’ve broken up planets in this universe to Category A thru D. A are goldilocks zone planets, B are maybe-habitable – they have some kind of atmosphere, C are barren rocks in space, and D are gas giants) they have my own mucked up version of a retro military radio phonetic alphabet, so we get names such as “Arcturus Able” as the first planet, which is potentially habitable (or is inhabited).
  • Some colonised planets, especially bigger ones, have a proper name from the colonists. these are generated from a pool of things from, as above, scifi movies to vague ideas I had.

As for actual placement within the sectors, I initially began with a simple “random placement within a radius” thing, but that was too messy. I don’t want planets within a tile or so of each other, for gameplay reasons, so I found it easier in the end to just limit myself to 4 planets due to sector size, and place them in either of the four “sub-quadrants” of the sector – top-left, top-right, bottom-right, bottom-left.

I also randomise which they go in, so if there’s just, say, 2 planets, they could be in any two parts of the sector.

I’ve also allowed for some sectors to have binary stars, which I kinda like.

User Interface

So, here’s where we’re at now:

As always, excuse the coder-art

You may notice a subtle (cough) change – there’s a star map in the middle screen now, and the terminal has been moved to the bottom-right corner. Beyond that, you may also notice that the panels have changed shape. And here’s why:

Scribbled in my brand new gaudy and en-stickered design sketch book is my first rough pass at the layout of the desktop version of the ship design, changing the size of the panels I’d mocked up, and giving them more specific purposes. In short, these are (going from the top, clockwise):

Damage Control panel on the 2003 Battlestar Galactica (source)
  1. The main nav com screen – showing the sector you’re in (or the quadrant view if you’ve got that selected).
  2. Power / Engineering – a management and view screen for your ship’s power generation and the status of the machinery driving your ship.
  3. Terminal – by default in normal operation, this won’t have a text interface – it’ll be used to show the current list of commands to execute when your turn ends. Bottom right (or pressed with a hotkey) will be a ‘new turn’ button, of sorts. Though I’ll give it a new command.
  4. Weapons – a small panel letting you place or remove orders to fire rail guns or torpedos, and giving you a display panel showing the the number of torpedos you currently have aboard your ship.
  5. Motion – a small panel with commands to let you initiate movement in the sector, and either spin up, plot a course to, or activate your FTL drive.
  6. Other – There’s a few things that don’t quite fit in this category, such as damage control. This will go here, though I may in future actually entirely change this to a DC panel. Aesthetically, I kinda want it to look not dissimilar to the DC panel on the original Battlestar Galactica reboot (2003) miniseries – I love that scene. (Visual reference to the right)
  7. Sensors & Status – This is another terminal, but a non-interactive one. It will give contextual information – for instance, if you have a location on the nav map selected, it’ll give information about that. If you do not, it’ll have information about the current sector and general ship status.

Kill The Bugs!

In the process of tweaking the UI to have its scale match my design as listed above, I found a few bugs – one of them major.

One of the gotchas I’m not yet used to with Lua “classes” using metatables is this… when you create the base table for an object, you can give it variables. These effectively act as default values for any class instances. For instance, if I set myValue = 2 in the main class and then later on ask for myValue in an instance of the class, if I’ve not set one, I get 2. If I overwrite it, it doesn’t change the base class / default value. Easy.

Except, that is, if you set a default value to an empty table, and never set it to even a blank one in your local instance. If that happens, you effectively get what in C++ would be a static member variable – if you change it in one instance (adding to it), it changes it for every class.

This meant that when I had my Terminal class with a lines member variable in the master class, and added lines to it… it added them to every terminal on the screen.

A simple gotcha with a simple fix, but one that’s stung me a few times as I get used to Lua and metatables.

And Another Thing…

Okay, so I did one more thing I figure it’s worth jotting down here – I re-factored the internal graphics module.

What I had before was very simple – a gfx module that let you display sprites after you’ve loaded them, short-handing a few things such as changing the ‘colour’ to apply to the sprite, any scaling, etc. Simple stuff, but meant I wasn’t directly re-writing the same 3 Löve2D commands.

The down side was, up until now I was loading VERY few images, so I was just making a global variable for them somewhere and loading the sprite into it.

I always knew this had to change, and with the addition of a metric crapton of temp images for the main viewer, I had to fix it.

So for now I’ve got a system where I simply note all the sprites I want (a tiny python script generates it for me whenever I alter the gfx/ subfolder), and when the game loads, so do all the images. I simply refer to, say, “nav_planetd_3” as a string and the gfx module looks in its data table, and maps that to the loaded sprite “gfx/nav_planetd_3.png”.

It’s not ideal as it’s, of course, loading ALL the graphics when the game loads, but frankly this is a pixel art game on modern computers. Even on the oldest of iPhones, it can handle loading a meg or two (at most) of graphics of the size I’ll have in the final game.

And now… on to implementing more of the UI and basic gameplay…