Tutorials

Tutorials - rubenwardy's blog https://blog.rubenwardy.com/tags/tutorials/
Cover image for SDL_GameController: Making gamepads just work
14
SDL_GameController: Making gamepads just work

When implementing controller support in a game, it’s desirable for gamepads to just work without a lot of user configuration. Platform APIs are pretty useless for this, the solution is an API like SDL_GameController that allows you to target a large number of gamepads without much effort.

Each operating system has its own API for gamepad input. Windows has XInput, and Linux has the joystick and evdev APIs. When a gamepad button is pressed, applications will receive a button id. This is a number, there’s no OS way to know which button id corresponds with which button. The ids for a button are not the same on different gamepads and platforms, making it super hard to support more than a couple of devices.

if (SDL_JoystickGetButton(joystick, 8)) {
    std::cerr << "no idea what button 8 is" << std::endl;
}

One thing platforms do give you is the name, model, and manufacturer of the game controller. If you test with a large number of gamepads, you can create a database from gamepad name to layout. Luckily, SDL_GameController has already done this for you. Instead of a random number, you can use a named button that will work no matter the gamepad and platform:

if (SDL_GameControllerGetButton(controller, SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X)) {
    std::cerr << "X was pressed!" << std::endl;
}
Cover image for Minetest on Steam Deck: usage and review
5 27
Minetest on Steam Deck: usage and review

A few months ago, my Steam Deck arrived. So, obviously, one of the first things I did was play Minetest. Whilst Minetest isn’t available on Steam yet, it is available on Flatpak and so can be installed from desktop mode.

Minetest plays very well on the Steam Deck, it performs great and Steam Input makes setting up controls easy. The Deck is an open console, so there’s full support for modding and you can cross-play with other platforms.

In this article, I will explain how to set up Minetest on the deck, and review the controls, performance, and experience. I’ve already written my thoughts about the Deck in another article, and recommend checking that out.

Cover image for Setting up fingerprint auth on Kubuntu (Thinkpad X1)
3 3
Setting up fingerprint auth on Kubuntu (Thinkpad X1)

Using a fingerprint to unlock your computer or elevate privileges (sudo) is a nice convenience, saving time during daily use of a computer. This article will show you how to set up fingerprint authentication on Ubuntu KDE. You’ll still need to enter your password to login, but once logged in you will be able to use a fingerprint to unlock or use sudo.

This guide is based on a Thinkpad X1 running Kubuntu 22.04, but it should work for most laptops with supported fingerprint sensors. You can check whether your fingerprint sensor is supported by searching for “Linux fingerprint” and your computer’s make/model. The Arch wiki is especially useful for this sort of thing, even if you don’t use Arch.

It goes without saying that this comes without warranty; backup your data, and have a LiveUSB ready. There are some pointers on recovering from mistakes at the bottom of this page. Luckily, I never needed to use a LiveUSB, I could easily recover from a virtual console.

Cover image for Devkit CLI: Upload your game to Steam Deck from your dev computer
2
Devkit CLI: Upload your game to Steam Deck from your dev computer

Steam Deck is a new portable gaming console from Valve. The Deck is a very open platform as it’s a full Linux PC, making it very easy to use third-party games and stores. All Decks can act as a devkit machine, and come with devkit tools preinstalled. There was a Steam Deck Devkit edition, but that was a preproduction version of the hardware to allow game developers to test their games.

This article will show you how to upload and run your games on the Steam Deck from your development computer, using a VSCode task or a script you can use in any editor. Whilst you could develop on the Deck directly, it would require setting up a new dev environment. Being able to develop on your computer and test on the Deck allows you to reuse your current dev environment.

Cover image for Creating worker NPCs using behavior trees
5
Creating worker NPCs using behavior trees

I’m a huge fan of RimWorld, a base building game where you manage a group of colonists. Rather than directly controlling the colonists, you place blueprints for buildings, mark trees for cutting, and animals for hunting. NPCs will then decide what to do automatically, based on their skills and priorities.

I’ve made two games recently with similar mechanics. The first was Ruben’s Virtual World Project (RVWP), a hybrid basebuilder/topdown shooter. The second was Tin Mining, a mining sim created as an entry to Ludum Dare 48. Both of these games allowed placing building plans that NPC workers would then build out.

In this article, I will explain how I implemented the NPC AIs, and the problems I faced.

Cover image for Securing Markdown user content with Mozilla Bleach
2
Securing Markdown user content with Mozilla Bleach

Markdown is a common choice for rich text formatting due to its readability and ease-of-use. Unlike a lot of markup, it aims to match natural text. It’s even easy for beginner users, and there are WYSIWYG editors available.

We will be using the Python Markdown library to convert Markdown to HTML. Markdown doesn’t have a well-defined standard. The library aims to comply with what little is defined by the Markdown syntax specification, meaning that it is also often stricter than other parsers.

Cover image for Extending sol3's implicit type conversion
2
Extending sol3's implicit type conversion

Many APIs in my game push Vector3s to and from Lua. It’s such a common operation, that most of my functions used to look like this:

sol::table add(sol::table tPos) {
    Vector3f pos = TableToPos(tPos);

    // do something
    return PosToTable(pos);
}

One of the benefits of sol is that it is able to bind Lua arguments to C++ function arguments, converting types implicitly. Having to convert from a table to a vector ourselves is quite annoying. It would be much nicer to have sol do it for us. Luckily, sol allows you to customise how types are retrieved and pushed to Lua using Customisation Points.

When trying to convert a type from Lua to C++, sol will call certain templated functions. We will be customisating sol’s behaviour using a technique called template specialization, which allows us to specialise a specific instance of the templated functions and structs. By the end of this article, we’ll be able to use Vector3 directly when using sol, allowing the above code to be turned into this:

Vector3f add(Vector3f pos) {
    // do something

    return pos;
}
Android: Complete, generic data-binding RecyclerView adapter

Data binding greatly reduces the amount of code you need to connect user-interfaces with ViewModels. It keeps Activity and Fragment code small, and makes it easier to manage lifecycles.

<EditText
    android:id="@+id/username"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:text="@={viewModel.username}"/>

I discovered that there was no attribute to bind the elements in a RecyclerView, due to the fact that a RecyclerView needs an adapter to be able to create element views. It would also be nice to automatically use data binding to create the viewholders. There are a number of guides to do both of these halves, but I now present the code to do the whole.

Cover image for A Comparison of SFML GUI Libraries: TGUI vs SFGUI vs ImGui
A Comparison of SFML GUI Libraries: TGUI vs SFGUI vs ImGui

SFML is an excellent library that can be used to create 2D games and similar applications in C++. It’s an abstraction over OpenGL and various system APIs, presenting a consistent and easy-to-use interface.

Providing a Graphical User Interface (GUI / UI) API is out of scope for SFML. GUIs are complicated, and there’s no single good way to implement them. The S in SFML stands for Simple but GUI code rarely is.

There are many different options to choose from when making GUIs. This article is an in-depth comparison of the options for making GUIs in SFML, discussing their pros and cons.

Getting user profile data from external phpBB forums

I recently wrote and released a python module to allow fetching of profile data.

You can install it using pip:

pip install beautifulsoup4 phpbb-parser

Here’s how you import and use a profile:

import phpbb_parser as parser

username = "rubenwardy"
profile = parser.get_profile("https://forum.minetest.net", username)

if profile:
    signature = profile.signature.text
    location = profile.get("location") or "unknown"
    github = profile.get("github") or "none"

    print(username + " from " + location + " has github " + github)
    print("Signatue: " + signature.text)
else:
    print("Could not get profile!")

profile.signature is a beautifulsoup4 object.

Next: Linking a user account to an external phpBB forum.

Convert folder of images to PDF with filenames

Here is a shell script specific for GNU/Linux based operating systems to use. On different operating systems the convert commands will be the same, but the for loop will be different due to a different batch file syntax.

rm /tmp/imageex -r
mkdir /tmp/imageex
for filename in *.png; do
    echo "Processing $filename"
    convert $filename -background White \
        label:$filename -gravity Center \
         -append -pointsize 14 \
        /tmp/imageex/$filename.png
done
echo "Exporting to PDF..."
convert /tmp/imageex/*.png output.pdf
echo "Done."