Porting Teleporter - Day 1

Feeling lost? Check out the previous “Porting Teleporter” posts!

Objectives

I want to start small and have enough visual things happening to keep my dopamine levels high and interested in this mini-project. For today, I want to:

Organizing the project

Files and Directories

This is the mess I had.

Screenshot of the messy directory containing all files from the project. There are no sub-directories, just dozen of files having a party.

I started organizing the project to at least have the assets and the code in separate directories. This structure might suffer some changes down the line, but I feel like this is the bare minimum:

Screenshot of the new directory structure.

I went ahead and replaced all of the old assets from the backup at once and prayed I didn’t change their names too much. If I did, I will have a mix bag of old and new assets flying around.

The constants.lua File

A staples in my coding is to always have a place to store constants and paths. Right now, all paths are being written as a string directly in the code. Here is an example of what I found:

...
backButton = display.newImageRect("return1.png", 40, 40)
backButton.x = 20
backButton.y = 300
...

I created a constants.lua file to store all of these paths and extra information that I might need in other parts of the project. It ended up looking something like this:

local M = {}

-- Screen dimensions
M.screenWidth = display.contentWidth
M.screenHeight = display.contentHeight
M.centerX = display.contentCenterX
M.centerY = display.contentCenterY
-- Strings
M.contactEmail = "geral@danvj.pt"
-- Asset paths
M.imagesPath = "assets/images/"
M.soundsPath = "assets/sounds/"
-- Splash image files
M.logoSplashImage = M.imagesPath .. "screen1.png"
-- UI image files
M.backButtonImage = M.imagesPath .. "return1.png"
M.restartButtonImage = M.imagesPath .. "restart.png"
M.feedbackButtonImage = M.imagesPath .. "feedback.png"
M.bugReportButtonImage = M.imagesPath .. "bugreport.png"
-- Sound files
M.teleportSound = M.soundsPath .. "Teleporttest3.mp3"

...

This allows me to go into the individual files that are making use of these assets, and changing the paths there to point to the constants file:

constants = require("constants")
...
backButton = display.newImageRect(constants.backButtonImage, 40, 40)
backButton.x = 20
backButton.y = 300
...

In the future, if I have to change the name of the file, or restructure the project, I can just make the changes through the constants file.

First try?

After replacing the assets and fixing the paths, I decided to run the simulator and see how everything looked. The splash screen looked a bit odd:

Screenshot of an odd looking Splash Screen that seems to have been squeezed.

And the main menu… looked like this:

Screenshot of a broken Main Menu that looks like it was thrown against the wall

Okay, so I had a problem, but thankfully it didn’t take too long to solve. It seems like there is a Project Sandbox in the Solar2D Simulator, and for some reason it needed to be cleaned before testing. On the second try, the Main Menu looks a lot better, although it is still far from perfect:

Screenshot of a Main Menu that looks slightly better than the first try

Now it seems to be a good time to try and build an APK.

Building an APK

The mysterious password

I tried to build an APK using the Linux version of Solar2D, but unfortunately I got stuck here:

Screenshot of the build screen

I read the documentation and a couple of forums, and the suggestion was to use android as the password. I tried it, but it didn’t work:

Screenshot of the incorrect password error

I went to the Solar2D repository and found an open issue that describes my exact problem. The only comment on it was hoping that this pull request would solve the problem, but, spoiler alert, it didn’t.

Maybe Windows can help?

I try my best to only touch the Windows OS when I absolutely have to. My lack of ideas lead me to try and install Solar2D on a Windows VM and build the APK there. Unfortunately, whenever I try opening the Solar2D Simulator, the software crashes and complains about the VM not being able to support OpenGL 2.1:

Screenshot of the OpenGL error

I decided that I would not waste more time trying to make it work under a VM.

Updating the version on Linux

On my last post I described how found the Solar2D project on the AUR and to installed it from there to avoid using snaps. Well, the version in the AUR is the version 2023.3697, and the current version is 2024.3706. Maybe something in this version is causing the problem? Let’s find out.

Still trying to avoid installing snaps, I modified the PKGBUILD file to use the latest version available. If someone finds this interesting, here is the diff:

diff --git a/PKGBUILD b/PKGBUILD
index b01309c..63a357a 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -5,7 +5,7 @@
 # I probably won't read your email

 pkgname=solar2d-bin
-pkgver=2023.3697
+pkgver=2024.3706
 pkgrel=1
 pkgdesc="Simple to learn and use, completely free and open source 2D game engine"
 arch=('x86_64')
@@ -14,9 +14,9 @@ license=('MIT')
 depends=('glu' 'zlib' 'openal' 'freetype2' 'libpng' 'libjpeg' 'openssl-1.1' 'curl' 'sdl2' 'java-runtime')
 makedepends=('squashfs-tools')
 # The license file is available in the same commit from which the snap was built from
-source=("https://github.com/coronalabs/corona/releases/download/3697/Solar2D-Linux-${pkgver}_amd64.snap"
+source=("https://github.com/coronalabs/corona/releases/download/3706/Solar2D-Linux-${pkgver}_amd64.snap"
         "https://raw.githubusercontent.com/coronalabs/corona/685b98d1154c140b5bac138317621dc8ee2fa103/LICENSE.md")
-sha256sums=('509a1aaf622bf41490dcfe63aa040ba4f327e9e1a4c2a7b5aa32c749a059f31a'
+sha256sums=('0cfa1fcf2629d6314b74fc74ed89ac6efdfe5cc5f84a2b09f456558c6486f466'
             '8b3bad18f5a69906b8f03a4c525af48b76bdc7a46540c633ea0b1bdcc43b4176')

 prepare() {

After installing version 2024.3706, I ended up having the same issue as before. Well, at least I am all up to date on the Solar2D versions, right?!

Pause for some WINE

WINE is one of those projects that I have a tremendous respect for, and has helped me countless times along the years. Maybe if I can run Solar2D under WINE, I could finally get rid of this issue. Since I couldn’t be bothered to waste too much time on this, I just used Bottles which usually works extremely well.

Screenshot of Bottles

Everything looked very promising, and the build seemed to be going smoothly… until it wasn’t:

Screenshot of the Solar2D build error under WINE

The error message suggested that there would be more information on the Simulator console, but nothing extremely helpful:

Screenshot of the Simulator console

I was stuck and decided against mindlessly digging on gradle files and logs.

I’ll be back!

Okay, so no APK for now, but I won’t give up! Maybe I will try building it in a bare metal Windows machine. Or maybe in my MacOS VM. Who knows?

Cleaning up the mess

Since I really like Lua, and it has been a while since I have used it, I decided to take a second look at the code base. I saw a couple of things that looked like they could be cleaned up further and minor bugs that I could get rid of.

Scenes, components and modules

The files that I had before were very messy. It was hard to understand what each file did. I started looking at some of the smaller files and abstracting some logic inside of them. For example, I removed the code that created the Play Button from the Main Menu code, and isolated in a component:

local constants = require("constants")
local composer = require("composer")

local PlayButton = {}

function PlayButton.create(size, xPos, yPos, targetScene)
    local playButton = display.newImageRect(constants.playButtonImage, size, size)
    playButton.x = xPos
    playButton.y = yPos

    function playButton:touch(event)
        if event.phase == "began" then
            composer.gotoScene(targetScene, "fade", 150)
            return true
        end
    end

    playButton:addEventListener("touch", playButton)
    return playButton
end

return PlayButton

This way, in the Main Menu file, I only had to call PlayButton.create() with the correct arguments, instead of having to call display.newImageRect() and then add the event listener, etc.

The directory structure is now much cleaner, having only the main.lua, config.lua, and constants.lua files in the root directory.

Screenshot of the new AND IMPROVED directory structure.

Bugs and other fixes

A bug that was easily fixable was the fact that if you played the game, and on the Gameover screen you selected to retry twice, the Game screen would get stuck:

Screenshot of the stuck Game screen.

This was simply fixed because the gameover screen was never being removed from the composer, so adding these lines to the game screen fixed it:

-- Remove scenes from the composer
composer.removeScene(constants.mainMenuScene)
composer.removeScene(constants.gameoverScene)

I also went ahead and fixed the incomplete menus that I mentioned on the previous post. Here is an example of the Shop Menu still missing most of the components:

Screenshot of the incomplete Shop Menu.

A couple of notes

It’s a shame that the Linux version of Solar2D is so buggy. I know that the original maintainer left the project, but it seems like there hasn’t been much interest for this particular project from the Linux community. It’s not like Solar2D is bad, it’s just that there are so many other game engines, and more feature complete, out there, that the attention that this project gets is obviously going to be limited.

The PKGBUILD file I modified could probably be improved, and I will try and write a comment to the original maintainer to suggest these changes if I have some time. For example, the version number and the version year could be separated into two variables, since the version number is then used to build the URL for the download.

That’s all for now, I am excited to continue this port since, at least, it gives me an excuse to be using Lua again.