Putting Lolo in a Puzzle Room


We’re developing our own engine from the ground up, with only a foundational library called LibGDX to handle graphics and input for us. We are doing nearly everything ourselves for maximum control as well as maximum learning. Here’s where we will begin:



Not exactly a “puzzle” per se, but getting this far still took a lot of thinking


This is one of the first ever screenshots of our then-untitled project. It’s just Lolo in an empty room with a heart frame and a chest. Still, there’s a lot of code and planning behind this screenshot. I think it’s worth talking about it, so let’s travel back in time just a bit and revisit the early thought process behind our game engine.


If you didn’t bring a time machine, you can borrow one
Credit to Jeremy from Sydney, Attributions 2.0 Generic license, cropped slightly.



The game is a “single screen” puzzle game, so there’s no sidescrolling to worry about. Lolo doesn’t even move at this point, though we'll build simple movement by the end of this exercise. Each room will always have walls, so this early build draws the walls and floor as one static image. This means the only other things to draw are Lolo, the heart frame, and the chest. Let’s group these three things together as “Entities”.

If we make a generic "
Entity" interface in our code, then each kind of Entity can implement a draw() method and we can iterate over a collection of Entities calling draw() every frame. Each Entity will implement its draw method slightly differently, for example drawing a different image onto the screen, but the important thing is that our main class doesn't have to think about the differences between each Entity in order to draw() each Entity. I think that’s a pretty good start to a solid design.

What data structure will this collection use? Arrays have a rigidly defined size at start and they don’t grow well, but 
LinkedList is a very flexible kind of collection that can dynamically grow to whatever size we need, so let’s use a LinkedList to store all our Entities. We can have as many Entities as we want now:


I got a bit excited, maybe a bit carried away



Spoiler alert, LinkedList will not be the final data structure for the Entity collection, but we have to start somewhere. We have some efficiency advantages that we can take advantage of–
  1. The code is private and the team is small, meaning changes to the data structure we use have a very small impact with few repercussions
  2. There's no rigid expectations for the code yet, meaning we have great latitude to change code ad hoc
  3. We're in "greenfield" development i.e. totally new code, so even those who are impacted by changes like fellow developers ACalmMind and DevNull understand that the code will change wildly
Put all these together and it means we have an unprecedented amount of freedom to try things, get it wrong, and change it. I believe we should use those advantages to build fast and accept things might change before the engine reaches a "version 1" state. I've worked on large-scale customer-facing APIs and I know that this kind of willy nilly decision-making isn't always practical, but for now, let's use it to our advantage.

Back to heart frames, each heart frame knows its own location and how to draw itself, so we can simply add more 
HeartFrame objects to our LinkedList. Each Entity instance will have unique coordinates, so we may have to add that to the Entity interface. Personally, I’m a big fan of not trying to guess what we’ll need in the future, so I won’t add more stuff to the interface until we know we need it. For now, each object can keep track of its own coordinates so that its draw() method knows where to draw the Entity’s sprite.

Just so everyone’s on the same page, the Eggerland games and Adventures of Lolo games are about moving Lolo around to collect all heart frames. Once all heart frames are collected, the chest will open up and Lolo can collect the shiny treasures within. That’s the core gameplay loop, made more interesting by the addition of other obstacles. Let’s create some of those obstacles.


A very exciting puzzle containing trees, rocks, water, emerald frames, and two conspicuous creatures



This puzzle is a bit more, well, actually puzzle-like than the first one. I think it's pretty simple to anyone who’s played an Eggerland game before, but even simple is a step in the right direction! The gray statue is a creature called Medusa, and it makes stoney-eyes at Lolo when Lolo enters its line of sight. The slug is called Snakey (I didn’t name it, blame HAL) and it does mostly nothing except sit there being an obstacle to everyone, both Lolo and other creatures.

Each new creature or rock or shrubbery will be represented by a new Entity class in the code, each with its own drawing logic. I’m also seeing we’ll need to give each Entity its own logical behavior too, because Lolo will behave very differently from Snakey and Medusa. An 
update() method on our Entity interface will provide the structure for that behavior.

Lolo’s 
update() method will allow him to move around pushing emerald frames and collecting heart frames. Medusa’s update will allow it to catch and petrify (catch-rify?) Lolo when he moves past. Snakey’s update will… do nothing.


Seriously, Snakey’s a bit of a drain on Eggerland society


It’s easy to use LibGDX’s keyboard input stuff to detect keystrokes and move Lolo based on the arrow keys. Things will get way more complicated than that in the future, but again, I’m going to take advantage of early flexibility to avoid overengineering things until we know more about what we’ll need. A simple proof-of-concept for Lolo’s movement will do for now.

Alright, a round-up of what we’re doing here:
  • Creating a static fixed board
  • Creating a collection of “Entity” objects
  • Iterating over the Entity collection to both draw and update each Entity
  • Implementing keyboard input for Lolo’s update, to give players control

I think this is a great start. Next we can build out behaviors for the individual Entities. There’s a lot I glossed over here, like the coordinate system I use and the frame rate, but I think we’ll discuss those in due time. I also glossed over concepts like arrays and linked lists. I assume readers would either know these already or that Google could fill in any knowledge gaps. Let me know in the comments if you want me to teach more about these core programming concepts or if the audience is happy for me to get more technical. Also, start thinking about Medusa, we’ll implement its behavior in the next technical update.


Comments

Popular posts from this blog

Demo is here!

Who Is This For?