An impossible future as a game developer

This section contains the story of The Caveman, a platformer by yours truly, where jumping is broken.

And when I say broken, I mean broken in all senses of the word. It is not only a massive hack in its implementation, but is also implemented in a way that can trivially overcome the obstacles, no matter the difficulty level. You see, both the jumping and the obstacle generations were built around a game loop which essentially left obstacle generation happening at pretty much the same rate, while also allowing for autojumping by holding the jump button, and because obstacles could not generate as more than one at a time on screen, combined with the character not really running (I didn’t even try to implement the illusion of running that well), the game felt more like the obstacles moving towards you instead of the other way around, and with the speed acceleration and deceleration feeling more like moving around instead of instead changing the speed. This made for a relatively easy and effortless experience. (For those unfamiliar with game design, you do NOT want your game to be too easy) So that was undoubtedly a problem. A problem I never fixed because this game was ultimately made for a college assignment, and I got the grades I needed so it doesn’t really matter that much.

I want my Workspaces!

Workspaces are a feature I really fell in love with. For those unfamiliar, many Desktop Environments across different OS-es allow you to create virtual workspaces to separate your windows in whichever way you want, to allow for better separation and navigation. Now, I got introduced to Workspaces via a Tiling Window Manager called AwesomeWM, which, much like most standalone Window Managers, has workspaces built in and encourages their use as more of a navigation tool, rather than separation of windows by usage, for example for Work and Personal use. In short, all you need to know is I got used to having indicators for 9 workspaces, blatantly named 1-9.

So what happens when this indicator isn’t there as I want it?

There are 2 scenarios I want to explore here (and one about a different use of Workspaces):

Waybar and Hyprland: A cheap hack in the config file

When I was first doing a switch to Wayland about a year and a half ago, I was first using RiverWM, which worked fine but lacked a feature I desparately desired: rounded corners (I know, I know). There was only one Tiling Window Manager on Wayland at the time, that could provide that: namely, Hyprland. The issue was that the only bar currently on Wayland, that supported Hyprland was Waybar. And while I used Waybar on River without problems, the module for Hyprland didn’t have some features that the module for River did. As such, displaying static workspaces with no windows in them on the bar was impossible…. unless I filled all the windows. But why should I fill all workspaces with windows? So every workspace will be constantly taken, and every time I need a new one I’ll have to free it? Not exactly. Ladies and Gentlemen, I present to you, Window Rules! More specifically, the rules that allow a window to only spawn at a certain workspace, but also whether it can gain focus, and whether it’s floating or not, its size, location and opacity, all of which were used by this hacky solution. It was a simple plan:

  • Step 1: Add an exec-once to the Hyprland Config file to spawn Terminal windows, with titles in the format PERSISTENT_WORKSPACE_{1-9}
  • Step 2: Set Window Rules for each of those windows to ensure they are spawned in their respective workspace by matching the title with the workspace
  • Step 3: Set the following Window Rules for every window whose name matches PERSISTENT_WORKSPACE_* : float, nofocus, noblur, size 0 0, move 0 0, opacity 0
  • Step 4: ???
  • Step 5: Profit

Now, this approach had loads of issues, the main ones being waiting for the static workspaces to get set up, and the performance overhead, especially as I was using Alacritty at the time, one of the heavier Terminal emulators in terms of resource usage. Of course, all of these issues disappeared when persistent workspaces were finally supported in Waybar.

COSMIC DE: A cheap(er) hack, slower and lesser

After discovering COSMIC DE (at this point, a Hyprland user), I was impressed by the idea of a Tiling Desktop Environment. No longer would a user need to dive into thousand-line configuration files to get their key bindings set up. And I was right (at least when the key binds feature got added to the settings, it was a config file before then). And above all else, a consistent set of applications was available to use. Over time, most issues I had with COSMIC got ironed out. Most recently, Sloppy focus was added and it’s quite good (not as good as in a tiling window manager, but close enough). So at that point, there was only 1 feature I was really missing from COSMIC: static workspaces. Great! I can just do the same thing as Hyprland, right? Wrong. At the time of writing this, COSMIC still doesn’t have Window Rules, so that’s not possible. What then? Well, let’s just say if you thought the Hypland hack was cheap, you ain’t seen nothing yet! If I can’t make a Window automatically spawn in a Workspace, I’ll just skip all this and make my own workspace indicator widget! … Is what I would have said (alongside: “It’s a perfect exercise to help me learn some Rust”) if COSMIC’s Workspaces worked like Hyprlands, but they don’t. You see, in Hyprland, when you bind switching to Workspace 1-9 as Super+(1-9), you can press Super+9 and be transported to the 9th Workspace, regardless of whether the previous 8 are in use or not. You can’t do that with Hyprland. So I can’t do this new approach and I can’t do the old one either, or can I? Time to stack a hack on top of a hack! I can’t bind a window to a Workspace? I’ll just use keybinds to switch to each Workspace, starting from Workspace 1. You see, in COSMIC, the idea is to always have 1 empty Workspace, so if Workspace 2 is filled, the Workspace Manager creates Workspace 3. So if you fill each and every Workspace up to and including 9, you get 10 workspaces showing and practically 9 static workspaces. But wait, what about making the windows disappear? If you can’t make it disappear and be unable to gain focus, there’s no point, right? You don’t want 9 filled workspaces, but 9 static workspaces to fill. Well, I present to you, window minimising. That’s right, all I did was minimise each terminal window after creating it, doing so using a custom configuration for these windows to ensure they could minimise via the Shift+A keybind, which, in any other window, would do nothing. Then I use ydotool and some bash scripting to create a script to emulate switching to a workspace, spawning the window, minimising it, and moving to the next workspace. Overall, the script takes about 15 seconds to run because I had to leave some time to let the ydotool daemn launch properly, making this an overly complicated mess. And the worst part is that there is no official way to make it autostart. Autostart is supposed to work from the ~/.config/autostart directory in theory, but in practice, I found it hit or miss. As such, I usually launch this slow, hacky monstrosity myself. I hate it, but there’s simply no alternative currently.

Qutebrowser: A failed experiment

Now that we are on the topic of workspaces, it felt like the perfect time about how I fell in love with using Workspaces in the browser. First, it was Floorp, where I liked them but they felt weak and limited because they couldn’t carry across windows, so I was off to Vivaldi, which is great, except that it’s Chromium, and its UI is proprietary. So, can we find an alternative? Well, there’s this minimal browser (great, I like software minimalism) with Vim bindings (Great, I like Vim and this post is written in Neovim) that is also Open Source and known to be hackable? That’s right, it’s Qutebrowser, as this section’s heading suggested. It really is as great as it sounds. But there are 2 issues with it. First and foremost, there is no support for browser extensions yet. The solution was quite straightforward. Let’s look at my extensions: Tabliss (a custom startpage plugin), Bitwarden (Password Manager), Dark Reader (For Dark Mode), Ublock Origin (An Adblocker), and 5 Youtube-related extensions to handle my favourite, but most infuriating site. Let’s focus on the easiest ones first. For Dark mode, I just enabled it in Qutebrowser’s config file. To replace Tabliss, I created a custom start page to recreate my configuration in about an hour. There is built-in support for ad blocking, but it needs to be enabled and a separate package needs to be installed to make it work. For all the youtube stuff, there was no need for extensions, just using a custom command that launches the video in MPV was (mostly) enough. Nowadays, I’m far more likely to recommend FreeTube, as it also implements SponsorBlock and Clickbait Remover. As for a password manager, I never got around to configuring qute-pass (qutebrowser’s password manager) or the Bitwarden Desktop App, because there was no point. Even after all of these being configured, 1 thing was missing and that was workspaces support. Armed with the knowledge Qutebrowser is extensible, I head off to the Great Online, and find… nothing. Alright, let’s see what Qutebrowser can do and implement a hacky solution. Better than nothing I guess. My plan involved session saving, where I would have keybinds which would save the current session and switch to another session saved in a file. 1 file per workspace, with the current workspace being remembered, maybe in a separate file. Sadly, the plan never came to fruition as I could never make it work. That’s why I’m still on Vivaldi (that and the better adblocking of Ublock origin compared to python-adblock).

The Powerline Effect

As I already mentioned, I use a Tiling Window Manager. One of the key parts of using a Tiling WM is the customisation aspect, which is something that I decided to explore in detail. Something quite interesting is that there is often overlap between some customisations people do it their status bars, and in their text editors. Some of you may be familiar with the powerline effect, which is a way of grouping data that creates an interesting shape-based transition from one widget to another, often done continuously for a list of widgets. I’ve always liked a style of the powerline effect which uses a slant, rather than a triangle shape, and as such, I borrowed the idea of using a unicode character with a specific fontsize to create the powerline effect within my status bar. Over time, however, I found that this is a very problematic approach across different distributions, as differences in font availability and font rendering meant that I essentially needed to maintain multiple configurations simultaneously. That is, until I was met with the Qtile WM, and more specifically with a project called qtile-extras, which had a set of decorations, one of which was the Powerline decorations, supporting different styles, and working everywhere. That made me wonder about its implementation, and while I never really checked the implementation details for the decoration, I got the idea to implement a powerline effect programmatically and after some research, I ended up implementing the powerline effect in Waybar programmatically in its CSS stylesheet and the effect worked across various bar sizes and independently of fonts. It is now the primary way I use a powerline. What it showed me is that the obvious solution is not always the best one and that there is usually more than one way to solve a problem.