Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Mac Port Automation Finished, and 60 FPS Fest

In my last report, I mentioned how my back pain was preventing me from making substantial progress in the previous few weeks, and that I was working on automating my Mac port build for Toy Factory Fixer and needing to prepare for a festival.

I continued to do the work as my body let me.

Sprints 69: Ports

Planned and Complete:

  • Automate Mac port

I have been able to sit at my desk for longer periods of time, and so I was able to be a lot more productive than I have in weeks.

I managed to update my libSDL2 libraries so that they could be found properly by my project, but I struggled for some time trying to get CMake to configure my Xcode project so that it would embed and sign those libraries.

SET_TARGET_PROPERTIES(${GB_PROJECT_NAME}-bin PROPERTIES XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION)

This line seems to be needed to get the libraries that are found with FIND_PACKAGE to show up in the “Frameworks, Libraries, and Embedded Content” section of Xcode. But they would be listed as “Do Not Embed”.

SET_TARGET_PROPERTIES(${GB_PROJECT_NAME}-bin PROPERTIES
    XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
    XCODE_EMBED_FRAMEWORKS "${SDL2_LIB_DIRS}/libSDL2.dylib ${SDL2_LIB_DIRS}/libSDL2_image.dylib ${SDL2_LIB_DIRS}/libSDL2_ttf.dylib ${SDL2_LIB_DIRS}/libSDL2_mixer.dylib")

I found a number for forum posts, pull requests, and pieces of CMake documentation, and I felt pretty frustrated that I couldn’t get things to work properly. I made sure to have the latest version of CMake so I had the ability to set XCODE_EMBED_FRAMEWORKS and work with dylibs, but when I did the above, all I got was libSDL2_mixer to show up as “Embed & Sign” while the rest continued to be appear with “Do Not Embed” instead.

I found that no matter how I specified everything, it was always the last library in the list.

Well, luckily, someone runs a great account on Twitter, so when I was frustrated enough to end my day by complaining about my situation, I got a reply that helped me learn more about CMake:

Lists are semicolon separated?!

Now, I’ve used CMake for years, and the documentation has always felt a bit obtuse to me. It is very much a reference document and not meant to be a tutorial.

But I have never known that lists were semicolon separated before.

I mean, even the unit tests for this feature don’t feature semicolon separated elements of a list. They are separated by spaces.

But someone on IRC told me that “Semicolon separated lists is how CMake does lists. It automatically adds the semicolons if you don’t quote your items.”

So the following examples would work out in this manner:

foo bar baz --> "foo;bar;baz"
foo "bar" baz --> "foo;bar;baz"
"foo bar baz" --> "foo bar baz"

So I took some deep breaths to calm myself down, and made the following change:

SET_TARGET_PROPERTIES(${GB_PROJECT_NAME}-bin PROPERTIES
    XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON
    XCODE_EMBED_FRAMEWORKS "${SDL2_LIB_DIRS}/libSDL2.dylib;${SDL2_LIB_DIRS}/libSDL2_image.dylib;${SDL2_LIB_DIRS}/libSDL2_ttf.dylib;${SDL2_LIB_DIRS}/libSDL2_mixer.dylib")

And now all of the libraries show up as “Embed & Sign” like I wanted. Nice!

On a separate note, I learned that properties in CMake similarly have some flexibility in terms of what arguments can be provided.

So I have seen XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY take the argument ON in unit tests, TRUE in forum posts, and YES in examples I found on GitHub. And they are all correct, apparently.

One last thing was that I wanted to make sure I could build a release version in Xcode, but the default was Debug. Basically, I wanted to create a release by merely building the project, rather than needing to do a separate archive step.

When creating Makefiles, you can use CMAKE_BUILD_TYPE with arguments as Release or Debug, but Xcode needs you to use CMAKE_CONFIGURATION_TYPES instead.

Of course, I found that even when doing so, the release build it creates is a little different in size from the release build that gets created when using the Archive functionality of Xcode, so it might be a moot point.

Anyway, after I got the Mac port automation done, I wanted to leverage it to create the desktop ports for Toytles: Leaf Raking, but there was a game festival I needed to do some last-minute preparations for.

Last Friday, I had a table at the 3rd 60 FPS Fest, and it was gratifying to hear the first player, an 8-year-old, say, “This is definitely a fun game.” B-)

Toy Factory Fixer at 60 FPS Fest 2022

He also had a lot of ideas for how to make the game better, so I wrote some down. Thanks, Rowan!

One of my favorite pieces of feedback was hearing someone laugh about the toy parts getting “yeeted” to the inventory.

Toy Factory Fixer

I will say it was a bit humbling to see the number of people who struggled to know what to do when they started playing. I know I worked on tweaking the interface to funnel new players to what they needed to do, such as making the START button huge and obvious, or setting the default menu to the Hire Menu so you immediately know you need to hire someone. I also made the workers flash to indicate that you can tap/click on them when you have enough toy parts in inventory to create Good Toys.

And yet, it was very obvious as I watched new players struggle that I still had some work to do to make it more intuitive and easier to figure out how to play the game. Clearly whatever I’ve done so far is too subtle. I especially felt bad when a player felt incompetent or “bad at games” because it felt like a failure on my part to make it enjoyable from the beginning.

So the festival was a successful one, if only because I learned some ways to improve the game, especially for people who won’t have me standing next to them to help when asked. I also got some positive feedback from a number of new fans, including parents who were looking for non-violent, family-friendly entertainment that they could trust.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Back Injury Setback, Automation Work

In my last sprint report a couple of weeks ago, I managed to get the Mac port of Toy Factory Fixer published and working properly with music.

I set out to automate some of the Mac port work that had been manually done before.

Sprints 67 and 68: Ports

Planned and Incomplete:

  • Automate Mac port

I mentioned that I hurt my back a couple of weeks ago. I don’t know what I specifically did, other than contort myself earlier in the week to fix a leak under the bathroom sink, and I have not been as diligent about my yoga routine recently. I might have been putting strain on my lower back by leaning forward a lot as I read or worked at my desk, or maybe I was leaning forward because I was already uncomfortable sitting and didn’t realize it.

Either way, I have not been able to comfortably work on anything for a couple of weeks.

Which is frustrating partly because I have been trying to take care of my back so that I didn’t have setbacks like this anymore, and partly because I am getting antsy about moving on to porting Toytles: Leaf Raking and wanting to work on my next project.

Also, 60 FPS Fest is this coming Friday, which is a gaming festival that is free and open to the public, and I will have a booth there. I participated in the first two iterations of the Fest, and I look forward to being part of this one. I was hoping to have a new game in development that I could show off, but it is not looking likely.

Still, it will be the first time I get to show off Toy Factory Fixer in a public venue, and being able to tell people that Toytles: Leaf Raking is available on more platforms will be great as well.

Anyway, I finally had the ability to sit for more than a few seconds without pain, and so I was able to get some automation work done on Toy Factory Fixer’s Mac port, which means that I am that much closer to automating Mac ports generally. Basically, I created a build script that builds the libSDL2 libraries and updates their internal install directory to point to “@executable_path/../Frameworks” and then spent time trying to figure out how to tell CMake to generate an Xcode project that can refer to my custom libraries in the General > Frameworks, Libraries, and Embedded Content section.

Toy Factory Fixer Mac Port

I’m still in a bit of pain, especially when I stand up after sitting for a length of time, but I seem to be getting better each day.

I think getting prepared for the Fest this week should be no problem, assuming I don’t have a setback on top of my setback.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Mac Port Finished

In last week’s report, I discovered that my Mac port of Toy Factory Fixer had no music.

I set out to fix that issue this past week.

Sprint 66: Ports

Planned and Completed:

  • Create Mac port

About halfway through the week, I hurt my back somehow, which made it painful to sit or otherwise be at my desk, so I only did a couple of hours of work all week. In fact, I might rush through this report because it hurts enough to stand at my makeshift standing desk, which feels slightly better than sitting.

But a couple of hours of game development was enough to figure out that the SDL2_mixer I bundled with my Mac port depended upon libvorbis being installed on the player’s system, which is not what I wanted. I even tried using the configure setting that says to not use shared dynamic libraries, but I later found a forum post saying that it is explicitly disabled for MacOS, so that’s fun to discover.

However, just days before, I saw that libSDL2_mixer had a new update, v2.6.0, that used single-header libraries, so instead of depending on libvorbis, it uses stb_vorbis. I built it, bundled it, and found that the game had music!

So, if you want to get the Mac port, you can get it at itch.io below:

Now, what I still need to do is automate some of the steps, and I have been trying to figure out what notarization looks like so that people playing the game on newer Macs don’t get the scary message about how Apple can’t verify the source of the app.

But I think I have enough to get Toytles: Leaf Raking ported fairly quickly. We’ll see how my back feels after my doctor appointment.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Mac Port Just About Finished

In last week’s report, I was figuring out how to bundle the Toy Factory Fixer binaries and dependencies for the Mac desktop port.

And the work continued.

Sprint 65: Ports

Planned and Complete (er, I thought):

  • Create Mac port

Well, it mostly continued. It was a very unproductive week, as I only managed to put in a total of 2.5 hours of game development.

I think part of the reason for the lack of hours was that I was pretty much finished with the work, and then I had trouble finding someone to help me verify that everything worked properly on a machine that wasn’t mine.

I had to change the install path of the SDL2-related libraries so that they reference “@executable_path/../Frameworks” although I annoyingly can’t set it using the configure script because it expects an absolute path.

So basically I had to do a two-step process for each library: run “configure –prefix=[install path] && make && make install”, then use the install_name_tool to change it.

And since the SDL2_image, SDL2_mixer, and SDL2_ttf libraries also refer to the SDL2 library, I had to change each of their paths to that library, too.

Once I had the libraries setup correctly, then it was a matter of telling Xcode to bundle the libraries. Ideally I could get CMake configured to do it for me, but for now I found that I can add the libraries manually to the “Frameworks, Libraries, and Embedded Content” section, AND I can get it to handle embedding and signing for me.

Toy Factory Fixer Mac Port

And as far as I can tell in my testing, it works!

The problem is, I didn’t know if it would run properly on a machine that didn’t have my development libraries installed, or even if it would run on a Mac due to the app not being signed properly for it.

Well, it turns out that as I write this, someone was able to verify that the game runs on their machine. So, good!

Unfortunately, there was no music and some sound effects were missing. So, not as good.

My best guess is that while in the previous week I was able to fix the libSDL2_mixer dependency on libvorbis so that it can provide support for loading and playing OGG files, the library still depended on using the system-installed libvorbis to actually do so at runtime.

And I don’t bundle libvorbis, so it is essentially missing on someone else’s computer if they don’t have it installed, which means no OGG support in my game again.

As far as I can tell, I don’t have this same issue with the Linux version. When I check the dependencies on my game’s binary and on my SDL2_mixer library, I don’t see libvorbis mentioned, but then again, I don’t see it mentioned in the dependencies on my Mac either.

So either something weird is going on with the Mac port, which might be as simple as needing to bundle libvorbis or some other dependency, or something is wrong with my Linux port as well that I didn’t detect in my own testing.

If someone is running into something similar, I will throw out that I recently learned about libSDL_sound, which uses a lot of single-header libraries and should not run into this problem. I am not sure if I want to switch from SDL2_mixer to SDL_sound, though.

Anyway, the Mac port is done in that it runs and you can play the game, but it isn’t done in that somehow I need to make sure it plays music properly, which I only just discovered wasn’t working.

After I fix this issue, I’ll port Toytles: Leaf Raking next.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: More Mac Porting Work

In last week’s report, I mentioned being frustrated with CMake’s documentation as I tried to port Toy Factory Fixer to the Mac desktop.

I continued the work last week.

Sprint 64: Ports

Planned and Incomplete:

  • Create Mac port

Shortly after my last report, I actually got the game to run!

Well, it ran, but the screen was black. Using some strategic mouse clicks, I determined that the game was, in fact, working as I was able to maneuver through menus and quit the game, so the problem was that the game didn’t have any art assets to load.

I had to determine what was different between the iOS configuration and the Mac configuration to get my art and audio resources into the bundle. For instance, storyboards aren’t supported, so I didn’t need to worry about using them.

Toy Factory Fixer Mac Port

So eventually I got the graphics and sounds in the game, but I noticed that some sound effects and all the music was missing. It turned out that the custom-built SDL2_mixer didn’t know where to find libvorbis, so it didn’t have support for .ogg files. I would get an error along the lines of “Unrecognized audio format.”

So this sounds familiar! I ran into this when I created my Linux port, and the way to solve it was by installing libvorbis-dev using my distro’s package manager.

Well, I had homebrew installed on my Mac, but I couldn’t find libvorbis-dev as a package. Was I out of luck?

No, strangely, I just installed libvorbis, and everything worked. Go figure.

Then I needed to get the app icon set. On iOS, I provide the app icons in Images.xcassets/AppIcons.appiconset. Basically, there are a bunch of PNG files that correspond with the expected app icons needed.

After trying a few different things in my build configuration, I eventually figured out that inside AppIcons.appiconset I had a Contents.json that was specifying all of my icons as iphone or iPad icons. In Xcode, I could check a box that said I wanted Mac icons, and so I created a new Contents.json with only Mac icons specified, then created the icons in the dimensions at the Mac app icons expect.

Now it was at this point that I was trying to figure out why everything seemed fine AND the .app was only a few MBs.

Well, it turned out that the app has a dependency on my custom SDL2 libraries, and specifically where I built them (as opposed to where I placed them), and they are not getting bundled. So that’s the big thing that is left to do is to make the application standalone and not require third-party libraries to placed in arbitrary places.

And as I expect to put this .app on itch.io, I believe I don’t need to worry too much about certificates and signing unless I also want to distribute it on the App Store.

Assuming all goes well, I expect to have a Mac port finished soon.

Then I think it makes sense to port Toytles: Leaf Raking and finally, finally start work on my next Freshly Squeezed Entertainment game.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Mac Porting Work

In my last report, I was working on a Windows port of Toy Factory Fixer, and I created a page on itch.io, preparing to publish.

I did not have a report for last week due to being on vacation with my spouse (we celebrated our 10 year anniversary), but shortly before that trip, I did publish the game officially.

Since then, I have been focused on creating a Mac port.

Sprints 62 & 63: Ports

Planned and Incomplete:

  • Create Mac port

Between one week getting cut short due to the start of my vacation and the next week starting late due to the end of my vacation, I had about the equivalent of a single week’s worth of effort available. Even so, I managed to make some decent progress, I think.

My project uses CMake, and while I love how I can have one set of scripts produce builds on multiple platforms, getting there is frustrating.

The CMake documentation is a great reference document if you already know what you need, but if you don’t, it’s hard to navigate, search through, and quickly figure out what you need to do.

Each time I wanted to find what I could about Mac-specific commands and arguments, the results I found through discovering a completely different website mentioning them just don’t turn up.

For example, for my iOS build, I have a toolchain file that sets CMAKE_OSX_SYSROOT to “iphoneos”, and I figured that I needed it to be set to something that indicated the Mac desktop. The only thing is, I don’t know what to specifically set it to.

Looking at the docs for it, it says:

Specify the location or name of the macOS platform SDK to be used. CMake uses this value to compute the value of the -isysroot flag or equivalent and to help the find_* commands locate files in the SDK.

Now, one of the benefits of using CMake is that you don’t generally need to know how to do things on every single platform. It abstracts away certain concepts, such as defining a library and saying where to find the source files that should be built to make that library, and then it produces the platform-specific build scripts to do it.

But one of the challenges with using CMake when you need to use a platform-specific piece of it is that you now do, in fact, need to know how the platform in question works. In this case, the docs won’t tell you what the valid values could be. That’s going to require homework on your part to figure it out from the MacOSX docs.

It turned out that the value for CMAKE_OSX_SYSROOT should be “macosx”, but I had tried “macos” first before figuring it out.

Granted, part of this is that I am not a native Mac developer, so there is a lot I don’t know about Apple’s developer ecosystem, and frankly, the less time I spend inside Xcode, the happier I find myself.

Luckily, a lot of my iOS-related CMake scripts seem to still be relevant on the Mac port, so I don’t have to start completely from scratch, but I am looking forward to when I can run the cmake command with my MacOSX toolchain file, produced my Xcode project with all of the code signing and configuration setup for me, then simply build and archive the project.

But to get there, I need to figure out how the Mac Info.plist is different from an iOS app Info.plist, which configuration options are required, which ones are a good idea to have entries for if optional, and what code needs to change.

I have very limited platform-specific code, and I hope any Mac-specific code can leverage the iOS work I have already done. This past weekend I found that the iOS code that opens a URL uses UIKit, but UIKit isn’t available on a Mac, so I had to write similar code using AppKit instead.

Toy Factory Fixer Mac Port

Each day I’ve been slowly and steadily making progress, between figuring out how to build custom libSDL2 and related libraries (it turns out I can also use configure && make && make install the way I do on my Linux system), getting the Xcode project to generate, and getting the project to attempt to build. I have fixed some compiler errors, and I am currently fixing linker errors, so maybe I’ll have this thing figured out sooner than I think.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Windows Port and Preparing to Publish

Last week, I reported that I finally finished my Linux-based port of Toy Factory Fixer.

This past week, I set out to focus on the work of actually publishing it.

Sprint 61: Ports

Planned and Complete:

  • Create Windows port
  • Create itch.io page

It’s always a good feeling to finish all of the work I set out to do.

I didn’t know how long the Windows port work would take, and since the Linux port was finished, I wanted to get that into the hands of players as soon as I could.

I wanted to publish my games on itch.io, the open marketplace for independent digital creators with a focus on independent video games. I already have an account there due to some major charity bundles they hosted, and I like how the organization is so creator-friendly and also proactive about keeping the site toxic-free, so I started by learning what it takes to create a page.

And then…I made a page for the game.

The itch.io page editing tools were for the most part quite intuitive, and other than needing to shrink some of my animated GIFs to fit their 3MB limit, it made me wish there was an itch.io-inspired theme for WordPress because I love the way my game’s page looks and would love to match it on my own website.

I’ll be announcing the game’s release quite soon (as in, this week), so sign up for the newsletter (see below) if you want to hear about it first!

In the meantime, I found that creating the Windows port was fairly straightforward, but I also discovered that some code had to be changed that was causing some compatibility issues.

Specifically I have code using std::fabs, which I changed to abs, but it turned out that I was using the C version of it that only handles integers rather than the floating point version that comes from specifying std::abs from <cmath>.

I also realized that my Linux port had no music-playing capability, namely due to the custom SDL2_mixer library not being able to find OGG Vorbis in my docker container. The docs only mention that it needs OGG/Vorbis libraries installed on the system, but until I installed the libvorbis-dev package, I was struggling to figure out exactly which of the handful of libraries to install. So, hopefully that helped you if you ran into something similar.

The main problem with my Windows build was investigating what it takes to sign the executable. Basically, if the executable isn’t signed, then Windows likes to put up a scary modal dialog informing the player that this could be something dangerous from the Internet.

From what I could tell, it sounds like I could sign it with my own credentials, but since no one has my certificate, it might as well not be signed at all. I could pay for a certificate, but it isn’t cheap, especially for a free game, and on top of it all, I am reading that unless a critical mass of users downloads and runs the game, Microsoft’s Defender SmartScreen will see that the game doesn’t have a positive reputation and still flag it anyway.

So, I decided not to sign it for now. Maybe I’ll come back to figuring this piece out if my players worry about it.

Anyway, itch provides a tool called butler, so I spent time figuring out how itch prefers you to upload your distributables. I was expecting to provide .tar.gz files for Linux or an installer for Windows, but with butler, you simply point at your extracted directory and say which “channel” it is in (linux, windows, mac, etc), and it uploads everything in a nice way that allows you to upload updates in simple patches.

On the player’s side, they see .zip files, with the version specified.

Toy Factory Fixer downloads on itch.io

What I don’t like is that when you unzip the file, it extracts the contents directly into whatever director you’re in, as opposed to providing a root directory.

On the other hand, due to how butler and the itch.io’s app work, when you download the game through their app, it automatically creates a root directory with the name you provide for the page. It’s just a poorer experience (I think) for anyone who does a direct download from the page, and providing a root directory myself means a poorer experience for those who use the app.

I will say that the experience with the itch.io app is nice. You say download, then you hit the Launch button, and despite the fact that I didn’t specify a manifest or anything, they figured out which file was the executable so the game just works.

So now I have a Linux port AND a Windows port ready to go, and I’ll soon launch the itch.io page for the game (again, sign up for the mailing list to be the first to know!).

Next up is to create the Mac port, which I worry will not be as straightforward.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: A Finished Linux Port

Last week, I reported that I was close to finishing the creation of infrastructure to create a distributable Linux port of Toy Factory Fixer and other games I have made and will make.

I continued the work this past week.

Sprint 60: Ports

Planned and Complete:

  • Create Linux port

My work was split up into the following tasks:

  • T: Use bind mount to load current project and relevant Projects directories as read-only
  • T: Build custom libraries for 32-bit
  • T: Build custom libraries for 64-bit
  • T: Build game using libraries for 32-bit
  • T: Build game using libraries for 64-bit
  • T: Update Cmake files to package up assets correctly
  • T: Write script to coordinate all of the tasks to put together a finished binary with 64-bit and 32-bit support

Due to the Memorial Day weekend, I did not work on game development earlier in the week, and I put in fewer hours than I have in any week of the last month.

Still, I managed to finish the work, partly thanks to being able to leverage work I did many years ago the last time I tried to distribute a Linux version of a game.

I ended the previous sprint with the challenge that my C++ code was accidentally using C++11 features and so wasn’t compatible with older versions of gcc/g++.

I decided to change my code to not require C++11 compatibility, which required in one case creating an assignment operator to properly handle a member that was a reference, and in another case I learned that std::vector’s erase() can’t take a const_iterator. Luckily in that case I didn’t strictly need a const_iterator, but I found it surprising.

Anyway, once I had the game building in both 64-bit and 32-bit Docker containers using Debian Wheezy images (remember, I am using this older version of Debian to ensure that the game will run on as many varieties of Linux-based systems as possible), I then had to ensure that all of the game’s assets were packaged properly, which basically meant updating my CMake files to refer to my GameSpecific directories.

What’s nice about my Docker-based infrastructure was that I could switch up SDL2 versions very quickly. I just download the latest SDL2 tarball, put it in the appropriate directory, and then spin up my container, which will rebuild the libraries, build my game, and package it all together.

I can not only port Toy Factory Fixer to Linux-based systems, but I should be able to do similar work on Toytles: Leaf Raking. I want to play the game with an eye towards what the desktop might afford in case there are some features like keyboard shortcut support I might want to add.

But otherwise the porting work is done. Now I need to do the work of publishing it. I have vague plans to upload the game to itch.io, but I did not spend time on solidifying those plans last week like I wanted to, so I will be doing so this week, and next I will work on porting to Windows and Mac.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: Very Close to Finishing Linux Port

In last week’s report, I had figured out that my installation of Docker was missing some of the newer features available, which explained why I had to do so much more work to do what seemed like a simple thing.

This week, I managed to make great progress on my port work.

Sprint 59: Ports

Planned and Incomplete:

  • Create Linux port

My work was split up into the following tasks:

  • T: Use bind mount to load current project and relevant Projects directories as read-only
  • T: Build custom libraries for 32-bit
  • T: Build custom libraries for 64-bit
  • T: Build game using libraries for 32-bit
  • T: Build game using libraries for 64-bit
  • T: Update Cmake files to package up assets correctly
  • T: Write script to coordinate all of the tasks to put together a finished binary with 64-bit and 32-bit support

I once again put in more hours than expected, and I successfully built custom SDL2 libraries in both 64-bit and 32-bit varieties.

As I’ve mentioned, I am trying to use an older version of Debian to build my code because I want the resulting binaries to run on as many Linux-based distributions as I can.

So I have been using debian/eol:etch as a base image, but I quickly discovered that the version of CMake available in Etch is v2.4.5, which is too old for some of the features my CMake-related scripts needed.

I tried Debian Lenny, which has a CMake at v2.6, but it turns out that the FindSDL2.cmake that I was using has a QUIET keyword that it didn’t know about.

So I switched to Debian Squeeze, which has a CMake at v2.8.2, which seemed fine. I did run into an issue in which I thought there was yet another compatibility problem, but it turned out to be a problem with an environment variable not actually being passed in.

In trying to build my custom libraries, I have this section in my CustomLibs.cmake:

# Extract SDL2 into build directory (assume only one tarball exists).
# Creates ${SDL2_EXTRACTED_DIR}/build/.libs/libSDL2.so files.
    FILE (GLOB SDL2_TARBALL "${THIRD_PARTY_LIB_DIR}/SDL2-*.tar.gz")
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E tar xzf "${SDL2_TARBALL}" WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/")
    STRING(REGEX REPLACE "^.*(SDL2-[A-Za-z0-9.]+).tar.gz*$" "\\1" SDL2_EXTRACTED_DIR ${SDL2_TARBALL})

And I was getting an error along the lines of:

string sub-command REGEX, mode REPLACE needs at least 6 arguments total to command.

Oh, was this something else that has changed? CMake’s documentation doesn’t seem to indicate anything. I spent quite some time trying to track down what was going on, eventually upgrading to Debian Wheezy before deciding I could downgrade again to Squeeze.

Eventually, I figured out that THIRD_PARTY_LIB_DIR wasn’t set to anything, and so SDL2_TARBALL was similarly not set correctly, which meant the remaining commands were not able to execute properly.

Before this porting work, I had a toolchain file that set THIRD_PARTY_LIB_DIR to a particular directory on my machine that had the SDL2 library’s tarball. That is, a CMake-specific toolchain file set the variable, which meant that the CMakeLists.txt and other files knew about that variable.

Obviously that specific path won’t work inside the Docker container, so I wanted to set that library by use of an environment variable. And I struggled to figure out why my Docker container’s CMD line seemed to be able to output the ENV variable, and the script being called seemed to be able to output the variable, but CMake seemed ignorant of it.

Well, I realized that within my CMakeLists.txt and CustomLibs.cmake, I never needed to pay attention to environment variables before, as I was using that toolchain file to set the variable.

In order to make use of an environment variable, I had to do the following:

IF (NOT DEFINED ENV{THIRD_PARTY_LIB_DIR})
    MESSAGE(FATAL_ERROR "THIRD_PARTY_LIB_DIR is not defined.")
ELSE()
    SET(THIRD_PARTY_LIB_DIR $ENV{THIRD_PARTY_LIB_DIR})
    MESSAGE("THIRD_PARTY_LIB_DIR is defined as ${THIRD_PARTY_LIB_DIR}")
ENDIF()

Note that in the IF statement, I can refer to the environment variable with ENV, but in the SET statement, I need to use a dollar sign to refer to it.

Once I figured that issue out, I found that I needed to install libxext-dev because otherwise SDL2 wasn’t going to build.

Then I ran into a different environment variable being missing, so I solved it similarly to the way I did it above.

And then I ran into a frustrating problem.

My custom libraries get built by extracting the tarballs for various SDL2-related libraries. When SDL2_image got extracted, I then run configure on it with some custom arguments to get as small a binary as I can, then build it.

Except I kept getting the following error:

 aclocal-1.16: command not found
WARNING: 'aclocal-1.16' is missing on your system.
         You should only need it if you modified 'acinclude.m4' or
         'configure.ac' or m4 files included by 'configure.ac'.
         The 'aclocal' program is part of the GNU Automake package:
         <https://www.gnu.org/software/automake>
         It also requires GNU Autoconf, GNU m4 and Perl in order to run:
         <https://www.gnu.org/software/autoconf>
         <https://www.gnu.org/software/m4/>
         <https://www.perl.org/>

I tried installing automake, then wondered if I needed to install a bunch of other automake-related tools separately, but then I came across this Stack Overflow response that pointed me in the right direction:

It defeats the point of Autotools if GNU This and GNU That has to be installed on the system for it to work.

As well as this response:

As the error message hint at, aclocal-1.15 should only be required if you modified files that were used to generate aclocal.m4

If you don’t modify any of those files (including configure.ac) then you should not need to have aclocal-1.15.

In my case, the problem was not that any of those files was modified but somehow the timestamp on configure.ac was 6 minutes later compared to aclocal.m4.

So I checked, and I see that the directory that SDL2_image was being extracted to had files with timestamps that reflect my system’s current time.

If I manually extracted those files on my host system instead of within the Docker container, the timestamps show 2019 as the year, meaning that whatever files were in the tarball, the timestamps of those files were getting preserved.

So either Docker bind mounts do something wacky with timestamps, similar to how virtual machine shared drives can get kind of iffy, or maybe there was a compatibility issue with tar just like how I was dealing with compatibility issues with CMake.

And sure enough, I found that in tar v1.26 around 2011, tar’s –atime-preserve option had a major fix to make it work correctly.

So once again, I upgraded my Docker image to use Debian Wheezy as a base image, and tar was suddenly extracting files with preserved timestamps, which meant that it no longer was asking me to have automake installed.

And the rest of my build scripts were successfully able to build and package up the custom libraries! Woo!

So the next piece to work on was similar. I had to update my scripts to accept environment variables and such, and then I could build the Toy Factory Fixer project just fine.

And the only reason that it isn’t finished yet? I ran out of time in the week. Basically, I ran into an error due to code that requires C++11 compatibility, and Debian Wheezy is using GCC 4.7, which would require the use of a –std=c++0x flag for compatibility.

So either I change my code or I pursue that flag, which I think might require me to install an updated libstdc++, and at that point, why not just upgrade to Debian Jessie?

Either way, I expect that my project will successfully build soon, and then I can work on making sure that my CMake packaging-related lines understand how I’ve created separate directories for my resource files since the last time I worked on it years ago.

After that, I want to make sure all of the library building, project building, and packaging into a single tarball to distribute becomes a one-line script.

And then the port will be done.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!

Categories
Game Design Game Development Geek / Technical

Freshly Squeezed Progress Report: More Docker Work

In my previous report, I talked about how my initial plan to setup Docker containers to help build the Linux-based version of Toy Factory Fixer was a bit unclear. I didn’t know what workflow I was trying to support, which made it difficult to envision how to setup Docker to help me make it happen.

This week, I continued the work with a clearer vision.

Sprint 58: Ports

Planned and Incomplete:

  • Create Linux port

Despite putting in more hours than expected, I only made a little progress.

My work was split up into the following tasks:

  • T: Create 32-bit docker container using Debian
  • T: Use bind mount to load current project and relevant Projects directories as read-only
  • T: Build custom libraries for 32-bit
  • T: Build custom libraries for 64-bit
  • T: Build game using libraries for 32-bit
  • T: Build game using libraries for 64-bit
  • T: Update Cmake files to package up assets correctly
  • T: Write script to coordinate all of the tasks to put together a finished binary with 64-bit and 32-bit support

I only finished the first task, as I spent the week struggling to figure out why Docker’s support for multiple architectures (multi-arch) was not working as advertised.

My host system is using amd64 as the architecture. According to the documentation, I should be able to use a Dockerfile or a docker-compose.yml file, and either way, I should be able to specify the platform as pretty much anything supported by the specific Docker image I’m referencing.

In my case, I am using debian/eol:etch, which has an i386 version out there.

So my docker-compose file looks like:

version: "2.4"
  
networks:
    linuxportbuilder:
        external: false

volumes:
    linuxportbuilder:
        driver: local

services:
    linuxportbuilder64:
        image: gbinfra/linuxportbuilder64
        build:
            context: .
        restart: "no"
        networks:
            - linuxportbuilder
        volumes:
            - linuxportbuilder:/data
        ports:
            - 22

    linuxportbuilder32:
        platform: linux/386
        image: gbinfra/linuxportbuilder32
        build:
            context: .
        restart: "no"
        networks:
            - linuxportbuilder
        volumes:
            - linuxportbuilder:/data
        ports:
            - 22

And my Dockerfile was:

FROM debian/eol:etch

RUN apt-get update && apt-get install -y mawk gcc autoconf git build-essential libgl1-mesa-dev chrpath cmake pkg-config zlib1g-dev libasound2-dev libpulse-dev
 
CMD ["/bin/bash", "-c", "echo The architecture of this container is: `dpkg --print-architecture`"]

As you can see, the service linuxportbuilder32 specifies a platform of linux/386.

But when I run docker-compose up, I see output indicating that it is running amd64.

I tried modifying my Dockerfile’s FROM line to say:

FROM --platform=linux/386 debian/eol:etch

And I still see amd64.

I eventually learned about the buildx plugin for Docker, which uses Buildkit (something I haven’t looked into yet but apparently it is a Thing), but the docs say that it comes with Docker for Desktop out of the box. Well, I don’t use Docker for Desktop, as I just have the docker package that comes with Ubuntu 20 LTS’s apt repos. I would expect that things should work, right?

Well, I find I can download buildx and place it in ~/.docker/cli-plugins. And then I need to use it to create a new builder, then tell Docker I want to use that builder instead of the default one.

And I think I needed to turn on experimental features by creating a ~/.docker/config.json file and adding an entry for it.

And now if I use buildx directly, I can spin up an image and a container that thinks it is using a 32-bit architecture.

But when I used docker-compose, it still seemed to use the old builder. Frustrating. And the docs make it sound like it should just work.

I eventually got it to build a 32-bit image, which I can determine from using docker manifest, but I couldn’t run a 32-bit container because I would get: “WARNING: The requested image’s platform (linux/386) does not match the detected host platform (linux/amd64) and no specific platform was requested” and I get this error DESPITE THE FACT THAT I WAS SPECIFYING THE PLATFORM EVERYWHERE!

But I found that despite a certain environment variable value supposedly being a default, I needed to specify two different environment variables:

DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose up

And then I was able to spin up containers in both 64-bit and 32-bit! Success!

That is, until a colleague informed me that docker compose (note the lack of a hyphen) was a thing.

WHAT?!

So I discover that docker-compose is v1 and old, while docker compose is v2 and the new hotness.

And while I didn’t want to install Docker for Desktop for Linux, I did find that docker compose didn’t exist in the default apt repos, so I uninstalled my existing Docker and Docker-related tooling, added Docker’s repos for my Ubuntu system, and installed those, and now I have the official Docker tooling installed.

And suddenly I no longer needed to setup a new builder or use environment variables. Everything worked as advertised.

And I’m a little annoyed that I spent a good chunk of the week figuring out what was essentially a workaround for using older Docker tools, but I suppose that means now you know in case you need it.

Annoyingly, if instead of dpkg –print-architecutre I had used uname -m, I would still see amd64, even though supposedly the docs claim that it should show the i386 architecture. I see people report this behavior as of posts from a few years ago, so it seems to be the case today as well. I am not sure if there is something special happening with Alpine images or if the docs are just wrong, but it also makes sense, as Docker containers are using the host system’s resources.

Anyway, once I could consistently spin up 32-bit and 64-bit containers, the next step was to get my toolchains and source libraries for SDL2 and such mounted into the containers. It was both easy and hard, because while the mechanism to mount a directory as read-only into the container is straightforward, some of my build scripts assume the directory structure on my host system is in place.

Basically, I needed to change some things to make it more generic so that it works locally on my host system as well as in the containers.

For example, my third-party libraries and my toolchains are located at ~/Projects/Tools but I didn’t want my container to require that my own user account’s name is being used, and it makes no sense to have my home directory be replicated in the container either.

Currently, my CMake toolchains hardcode the value. Instead, I can specify the environment variable myself when I run cmake.

THIRD_PARTY_LIB_DIR=/home/[my_username]/Projects/Tools cmake ../..

And when I create the docker containers, my new docker-compose.yml file has these entries added to volumes:

        volumes:
            - linuxportbuilder:/data
            - ${THIRD_PARTY_LIB_DIR:?err}:/home/gbgames/Projects/Tools:ro
            - ${THIRD_PARTY_LIB_DIR:?err}/CustomLibs:/home/gbgames/Projects/Tools/CustomLibs:rw

And my Dockerfile adds the gbgames user and ensures that the home directory for that user exists.

So now I need to do:

THIRD_PARTY_LIB_DIR=/home/[my_username]/Projects/Tools docker compose up

And the resulting containers will have my Tools directory mounted read-only. If I don’t specify the environment variable, it fails instead of silently trying to continue to spin things up. I am also pleased that I can make a separate subdirectory read-write, as my current scripts like to build the custom libraries and place them in that directory, which means I won’t need to change my scripts too much.

Next up is mounting my current project’s git repo. I think I will similarly want to use an environment variable here to specify the source directory to make things more generic across projects.

But now that I don’t have to fight against tools that aren’t matching the docs, I should have an easier time of it.

Thanks for reading!

Want to learn when I release updates to Toytles: Leaf Raking, Toy Factory Fixer, or about future Freshly Squeezed games I am creating? Sign up for the GBGames Curiosities newsletter, and get the 19-page, full color PDF of the Toy Factory Fixer Player’s Guide for free!