Roguelike, step 1: Lua and Gideros, an introduction

Previous tutorial –  Download files –  Next tutorial

A simple plan – In which a Cloud drive allows local Wi-Fi testing – the many resolutions of iOS devices – BLACK is the new black – Stage Sprites – The long dark of Moria – Invisible, candy-coated red buttons – Events transpire which finally lead to action on stage.

A simple plan

Before we start coding a game, let’s talk about what we’re designing.  Rogue, Roguelikes, and Roguelike-likes (yep, that’s a thing) have run the gamut from the original Unix console games:

rogue_unix_screenshot_car

to real time multiplayer games like Blizzard’s Diablo series.  I envision something like this:

screen

This will be a game that’s played in landscape mode with buttons for movement, attacks and other player actions.  We’ll try to check most of the Roguelike boxes:  turn-based gameplay, tile-based graphics, procedurally generated game levels, and permanent death of the player-character.  While the game will be complete, it will also be pretty simple and will essentially be a framework to build a more full-featured — or at least, more personal — game on top of.

I’ll describe almost every line of code you’ll need to get a game running on your system.  If you really want to learn this stuff, I highly recommend just typing it up as we go along.  There’s no better way than doing it yourself.  Of course, if you just want to browse someone else’s code, everything described below can also be downloaded here.

In which a Cloud drive allows local Wi-Fi testing

Let’s get going.  Download and install the latest release from giderosmobile.com.  While you’re there, check out all the little descriptions, guides and resources.  As the introduction to the programming environment makes clear, it’s very easy to use the Gideros Player to test your game as you go.  It’s also very fun to immediately test on your phone or tablet.  I found Gideros AndroidPlayer.apk in my Gideros folder on my Windows computer.  I was able to install it on my android phone or tablet by putting it in a Dropbox folder and then running it on my android device.  As long as Gideros AndroidPlayer was running on my phone and my phone was connected to my Wi-Fi, I could hit play and test the game in progress on my phone.

Have you checked out the example programs that come with Gideros Mobile?  If not, browse over to the installation directory and check out Gideros/Examples/Graphics.  You can learn a lot just by looking at the included programs.  Most are written by way better programmers than me.

When you’re ready to start your own program, choose new project from the file menu.  In the project window, right-click on the project name and add a new file called main.lua.  This is the only file we need to run a Lua program.  Of course, we’ll have more.  Many many more.  For now, if you haven’t done this before, left-click on main.lua.  The main programming window is now open on the right and you can type

print("Torch in hand, you're ready to enter the old ruins.")

When you click run, in the output window you’ll see

main.lua is uploading.
Uploading finished.
Torch in hand, you're ready to enter the old ruins.

That’s basic Lua 101 in the Gideros Mobile environment.  But we want to do more than just play around with Lua, so read on.

The many resolutions of iOS devices 

The code below sets the screen size and landscape orientations.

application:setLogicalDimensions(1200, 1920) 
application:setOrientation(Application.LANDSCAPE_LEFT)

By setting the application settings we can easily define what our program will do, irrespective of whatever device we’re deploying to.  That being said, there are a lot of screen sizes to work with.  The thinking behind using 1200×1920 is that gives a width:height ratio of 1.60 which is midway between the older phone ratios of 1.50 and the newer ones which are 1.78.  For instance, the original iPad screen was 768×1024 for a width:height ratio of 1.33.  iPhones and iPads change their screen sizes constantly.  The iPhone 5 retina was 640×1136; then the iPhone 6 was 750×1334; followed by the iPhone 6 plus at 1080×1920.  My Nexus 7 tablet is 1200×1920 which works out to 1.60.  My widescreen desktop monitor and a lot of phones are 1080×1920 which is 1.78.  Gideros can deploy to them all.

 application:setScaleMode("letterbox")

By setting the LogicalDimensions and using the letterbox ScaleMode, you leave it to Gideros to make it work on all the different size screens.  And for the most part, it will.  There will be either blank areas above and below your LogicalDimensions or left and right depending on the device you run your game on, but there are tricks you can use to fine tune for each screen you plan on deploying to.  See the forums for more advice and peruse the screensizes.xlsx spreadsheet I include with the project files.

BLACK is the new black

The following code sets the background color to black:

BLACK @ 0x1A1A1A 
application:setBackgroundColor(BLACK)

Macros were recently added to Gideros.  The use of constants combined with the syntatic sugar of macros, allows us to define what we’re doing in english.  Of course, as programmers, we also have to understand hexadecimal.  Colors are represented as 0xRGB, where R=00, G=00, B=00 is black; while R=FF, G=FF, B=FF is white.  So, in hexadecimal-speak, 0x1A1A1A is a slightly off black and a bright, bobbydazzling green is called 0x00FF00.   If you’re using a program like paint.net to create and edit your images – and you should be – then you’ll find the hexadecimal codes for your favorite colors by clicking the More button on the color palette.

color.png

Stage Sprites 

At this point, we have a black screen.  Let’s get something more interesting on the screen.  While we were playing around with hexadecimal codes in paint.net, we also created a 720×1200 image to fill the right side of our game screen.  Our first piece of game art.  Congrats.  We’ll save that image in an images folder in the same directory as our RPG tutorial project.  Simultaneously, we’ll right-click on the project name and add a new folder called images. Then we can right-click on the images folder and add the existing file called “foreground.png”.  We can now refer to it in our code.

local fg = Bitmap.new(Texture.new("images/foreground.png", true))
fg:setX(1201)
stage:addChild(fg)

To see something in Gideros, you need to put it on the stage.  As the documentation describes, the stage is the top of the scene tree hierarchy.  And what do you put on the stage?  Sprites.  In Gideros, a Sprite isn’t a small fairy or any old two-dimensional object.  Bitmaps are Sprites and so is a TextField as we’ll see shortly.  Sprites are the basic scene building blocks as you’ll learn if you click on Sprite via the API documentation accessed from the Help menu.  So once we create our Bitmap, we add it as a child to the parent stage.

The long dark of Moria

Taking a clue from Moria, er, Moria, to put words on the stage is as simple as:

YELLOW @ 0xDAD45E 
local title = TextField.new(nil, "The Long Dark") 
title:setTextColor(YELLOW) 
title:setPosition(1320, 100)
stage:addChild(title)

The bad news is this uses whatever default system font is available.  Definitely not desirable behavior in a program.  Fortunately, Gideros allows you to use any true type font you can find.  As the Fonts project in Examples/Graphics/Fonts makes clear, if we have a .ttf file called immortal in a project folder called fonts, we can define it as a constant and use it as our game font.

FONT_MEDIUM @ \Font.new("fonts/IMMORTAL.ttf", 60, true)\
local title = TextField.new(FONT_MEDIUM, "The Long Dark")

Play around with different fonts and different sizes.  Like our screen size, our font size is something we have to consider for the screen size we’re targeting.   Once we’ve decided on the size we want, best practice is to use the included Gideros Font Creator and save  immortal_medium in the size we want in our fonts directory.  With “fonts/immortal_medium.txt” and “fonts/immortal_medium.png” in our fonts folder, we can change the definition of FONT_MEDIUM.

FONT_MEDIUM @ \Font.new("fonts/immortal_medium.txt", "fonts/immortal_medium.png")\

The reason to use this definition of our font instead directly using the true type font is that it will consistently stay the same size regardless of the screen it ends up on.

Invisible, candy-coated red buttons

We can add graphics and text to the screen.  What about interactive elements?  Specifically, let’s create four buttons that respond to the player wanting to move the hero either north, south, east or west.  Fortunately, there’s a button.lua file in the Examples/Graphics/Button directory that suits our purpose perfectly.  If we create a classes folder in our project’s directory and then right-click a new folder called “classes” in our project we can then add Button.lua to our project.  A Button is basically a piece of code that displays one of two Sprites.  We create the Sprites.  In this case, we create TextFields, but it could have just as easily been Bitmaps that load images of candy-coated red buttons.  To create an instance of the Button class we call Button.new with our two Sprites, and it handles the rest.  Here is the compass button for north.

local buttons = Sprite.new()
local north = {}
local up = TextField.new(FONT_LARGE, "N", true)
local down = TextField.new(FONT_LARGE, "N", true)
up:setTextColor(WHITE) 
down:setTextColor(BLACK)
north = Button.new(up, down)
north:setPosition(1500, 800) 
buttons:addChild(north)

Instead of adding the button directly to the stage via stage:addChild(north), we add it to a parent Sprite called buttons.  So Sprites can also be collections of Sprites.  When they are, they’re called parents with individuals in the collection referred to as children.  We then add the rest of the compass buttons to the buttons Sprite.  Finally, we add the buttons Sprite to the stage and it, as a parent, adds all the child Sprites to the stage for us.

stage:addChild(buttons)

Events transpire which finally lead to action on stage

The Button class does more than display two different Sprites if we click or touch them.  It also generates a click event as defined in the function Button:onMouseUp(event):

self:dispatchEvent(Event.new("click"))

We told the Button instance what to display.  In return, it tells us when it’s clicked.  Since each button is sending out “click” Events, we just need to write some code that responds to these Events.  The code we need is addEventListener() and for now, we’ll just have it print out the name of the button that was clicked:

north:addEventListener("click", function() print("you clicked north") end)
south:addEventListener("click", function() print("you clicked south") end)
west:addEventListener("click", function() print("you clicked west") end)
east:addEventListener("click", function() print("you clicked east") end)

So there you have it:  action on the Gideros stage.

Summary

We now have the beginning tools necessary to create our game.  That is, we can  put things on the stage and respond to them.  Granted, we don’t respond with much besides a little click and an output that only we, the programmers, can see.  But it’s a start that can lead to more exciting action.  Let’s pause for a moment and realize we just got up and running in our little home a framework written in Turkey using a language created in Brazil.

Done pausing?  Okay, moving on.

Next up:  putting a map on the screen and moving around.

2 thoughts on “Roguelike, step 1: Lua and Gideros, an introduction”

  1. hmm, it seems [FONT_MEDIUM @ \Font.new(“fonts/IMMORTAL.ttf”, 60, true)\] doesn’t work. I changed Font.new to TTFont.new and it works

    Like

    1. Hi HSW,

      Thanks for the comment. There are two ways GiderosMobile uses fonts. One is with Font.new and the other is with true type fonts method TTFont.new. True type fonts are the easiest to code as your comment shows, but if you use Gideros Font Creator and have a .txt file and a .png file available, I think Font.new is better than TTFont.new. The reason is that TTFonts will behave differently depending on the screen size you use. So you optimize FONT_MEDIUM to look good at 1920×1200 and when you deploy to an iPad with a resolution of 2048×1536. No problem. GideroMobile will make sure Font Creator fonts look good at that new resolution, but the TTFont will try to compensate by itself for the increased resolution and will look slightly different.

      My experience and understanding says to use Font.new for games so they behave the same on all devices. Just make sure the two files for the Font.new method are available and in the right directory.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s