gbgcpp – Ribbons using Qt

I’ve been involved in the gbgcpp group, a part of the larger Sweden C++ community, for a couple of years. It is fun to see that there is a lot of C++ developers out there, once you start looking for them.

In the next meetup, this Wednesday, there will be both C++ and Qt. The topic is to implement Ribbons in Qt, based on a seminar by Dag Brück. If you happen to be in the vicinity of Gothenburg, I recommend you to go there!

I’d also like reach out and thank Sylog for hosting the event!

Planning

A new year and a new decade means time for reflection. I try to do this more often than every ten years, but this seems to be a good time to discuss in public.

I’ve split this into three phases. Short-term is what I’d like to do in the coming month or so. This year is my goals for roughly a year, while decade really just means long-term.

Short-Term

Promote an ensure that foss-north 2020 is as successful as last year. You can help by submitting your paper. We’re also looking for sponsors and projects for the community day.

There is also some short-term work for foss-north, i.e. getting tickets sales up and running via our own infrastructure instead of using Eventbrite.

While planning foss-north, I’d also like to keep foss-gbg and gbgcpp active during the spring. Here, the travel part of my work means that I’m seriously short on time. The ambition would be ~10 meetups, but realistically it will be ~5-6.

A part from organizing events, I’m also attending. The next big one is fosdem, which I’m really looking forward to.

Then we have this blog. My goal is to write more, and I’ve been at it for a few months. I’ll try to keep this up.

When it comes to personal health, I try to run regularly. Since my little health dip last autumn, I’ve been fighing to get back and the current goal is to do 5km rounds every week.

This Year

For foss-north, my aim is to do at least one themed event, much like the cancelled foss-north Iot and Security Day planned for October last year. This event will be in the Øresund region or in Stockholm. Feel free to reach out to me if you want to help out.

On a 12 month time frame, I have some professional goals. I’m working with Mbition together with an amazing group of people. We are building a platform for future in-car software. There my goal is to be more focused in what I’m doing – to do more of what I do well better, and less of what I do badly.

Kuro Studio is also in an interesting phase, having a couple of start-ups underway and a constructive partnership in an interesting phase. Again, my personal goal here is to focus more.

Finally, I have my little one-man-box, Koderize, where I do smaller assignments. Here, my goal is to do a few more articles for various magazines, and possibly to find some small development project. Let’s see what I bump into.

Then we come to actual coding. A while ago I came to the conclusion that I need to down-size my projects a bit to actually finish them. Hence Mattemonster an app to teach basic maths for Android created using Godot. It started as a way to get my son to enjoy practicing maths, but this time I polished it just a little bit more and published it on the Play Store. I still have some features on my todo list, as well as publishing it to f-droid.

I also want to spend some time writing a proper Qt desktop application as well. I’ve got some basic ideas, but nothing crisp enough. I’ll probably not have time to dive into this unless I get a really good idea.

My health target this year is to do 5km under 30 minutes, and comfortably do 10km. The stretch goal is to do 10km under the hour.

Next Decade

When looking at a longer time-frame than a year, the goals become fuzzier. This might seem like speculation, but I embrace the fuzziness and use them to prioritize my short-term goal. If I run into something that seems fun, I map it to my long term goals to determine if I should do it or not.

On this time scale, I’d like for foss-north and foss-gbg, I want them to be more independent of me as an individual. To create more a role based setup and stable economical environment (currently the margins are super slim). If I can enjoy a foss-north conference as a visitor in 2030, I’ve achieved this.

For my Mbition work, I want us to reach multiple releases. The reason for the automotive industry to take on more responsibility for software is to increase the reusability. That is why it is key for Mbition to do multiple releases. Then we have proven that our existence makes sense.

For Kuro Studio, we want to continue doing start-ups, more partnerships, building a larger team, meeting more people, and doing more awesome stuff. Getting Kuro properly off the ground is very high on my list of priorities.

Another professional goal I have is to speak more at conferences and speak more about how open source is the way to do software. Transparency is the only way to ensure proper quality, maintainability, and trust – and what better way than open source is there to be transparent.

Since we’re on the really long-term goals part of this post, I’d also like to write another book. I’m not sure about the topic, nor when, but I would not consider myself a proper writer with only one title to my name.

Health wise, it is harder to set a more clear goal than staying healthy, which is what I intend to do. I’ll try to keep running and staying in reasonable shape. If I can still do 10km at a reasonable pace in 2029, when I turn 50, I’m happy.

Next Up

At the end of the day, these are goals and ambitions, not a roadmap for my life. Next up is fosdem. I hope to see you there!

Preparing foss-north 2020

Next year’s foss-north will take place March 29 – 31, with the training day on April 1. Preparations are under way, and now we need your participation to make this event as great as the past years.

The preparations are under way and we’ve opened the Call for Papers. We truly believe that we bring together the best audience with the best speakers. Being a part of this is a great experience, so make sure to get your talk proposal submitted.

Another part of the foss-north experience is the community day. The day before the actual conference, a large set of community groups arrange workshops, hackatons, dev sprints, even mini conferences. This year we’ve already confirmed the participation of KDE, FreeBSD, and “something embedded” arranged by Endian (last year they did a full day workshop on the Zephyr Project).

If you want to be a part of the community day – don’t hesitate to reach out to info@foss-north.se. We help with a venue, food, and promotion. All you need to have is a cause!

In addition to this we are, of course, on the look out for sponsors. If you want to support us, or even take part in the conference with a booth, please join our Call for Sponsors. Make sure to tell your employer that they should sponsor – all sponsor packages include free tickets, so that way you can both participate in the event, and help us making this possible.

Between all of this we’re also working on the infrastructure. I’d like to extend a big thanks to Magnus Hagander from Postgresql. He is helping the migration to their pgeu-system system. This will give us a single system integrating the features we need – tickets, sponsors, scheduling, accounting. So no more Google Forms, Eventbrite, and manual coordination of systems. If you like css, html, and such, you’re more than welcome to help. Some pages still has rough edges.

Long story short: join us at foss-north 2020 – it will be fun! Take the opportunity to see Gothenburg end of March in 2020.

Advent of Code 2019

My work does not involve that much coding any more. I probably spend more time doing email, attending meetings, and preparing presentations than anything else these days. Still, my fingers itch if I don’t get to write some code now and then.

This has resulted in small apps such as Mattemonster, where I pushed myself to get it into a presentable state so that I could publish it to Google Play. Any one with kids starting with maths should try the app – my son loves it!

It also results in me doing the Advent of Code for a third time in a row. It is a nice exercise in problem solving, basic data structures, and algorithms – something that I have way too few excuses to exercise with. I’m still frustrated with day 15 from last year. I also remember day 16 fondly.

This year I considered doing the AoC in Rust, to learn. But I ended up with Python to save time instead.

Tech Day by Init

Last Thursday I visited Tech Day by Init and had the opportunity to talk about a topic close to my heart. I decided to do a talk about Open Source Anti-Patterns (you can find the slides over at Kuro Studio).

It is always fun visiting TDBI (it is my third year speaking). The audience is very well read up on the topics and the questions are always good. Also, I got a high five from a guy for my speech during the beer event ;-)

Play-ing with Godot

I’ve finally come to a point where I have a project that is useful, and at a good enough quality (anyone with graphics skills who wants to help?) to be shared with the broader world: Mattemonster. What I’m trying to say is that I just went through the process of publishing a Godot app to the Google Play store.

There is already good documentation for how you export a Godot app for Android, and detailed guides how to publish to Google Play. This blog is not a step by step tutorial, but instead mentioning some of the things I learned or noticed.

First of all, when setting up the Android tooling, you usually have an android-tools package for your distro. This way, you don’t have to install Android Studio provided by Google.

The configuration settings that you use to export your app goes into the export_presets.cfg file. Once you put the details for your release key in, you should avoid storing this file in a public git, as it contains sensitive data. But even before then, it contains paths that are local to your machine, so I would recommend not storing it in a public git anyway, as it makes merging with others painful.

Finally, when building your apk file, a funny detail is that the switch to control if it is a debug or release build is found in the actual Save As… dialog, and not in the export settings. This was initially confusing to me, as I was looking in the wrong place.

The next step is Google Play. Here one creates all the accounts and listings as explained in the article linked to in the beginning of this blog. What is a bit unclear is that some settings are only available once an initial apk has been uploaded (e.g. Content rating).

Another of these dependencies that confused me is that even the closed alpha testing requires the app to have been published at least once. This means that you have to publish version 1.0 first, then you can use the alpha channel to push out updates quickly to your testers. As it takes up to a week (or longer…) to get the initial publishing through the system, this is a bit frustrating, as you really have to wait around for a few days before you can continue.

When you create an update, you need to remember to step the version code of the apk. This has to be done manually when configuring the export in Godot.

It is also worth mentioning that I did not opt-in to let google manage and protect my signing key. This means that I get warnings for not supporting bundles each time I try to publish, but these warnings can be ignored.

Next steps for me is to to publish to f-droid, and to provide some translations to be able to target more markets (right now the app is in Swedish, so I limited distribution to Sweden).

foss-north 2020 is on

The foss-north event due a few days ago got cancelled due to health issues, but I’m happy to announce that I’m back and that the planning for foss-north 2020 already is on.

The event will be run as last year, meaning one community day, two conference days and one training day. The community day will be on March 29, conference march 30-31 and training on April 1.

Last year we attracted some 100+ people for the community day and 250+ people during the conference (260 tickets sold). My personal goal for 2020 is 400 visitors (we can do it!) and 200 people during the community day. Also, let’s find a bigger place for the social event ;-)

I just sent out the first sponsorship request to our old sponsors and am happy to see that we already have one sponsor lined up. I have a feeling that this will be a great year.

MX records…

As you might know, I’m a fan of federated services. I tried to promote this during foss-north with conf.tube and mastodon on the list (I’m @e8johan@mastodon.technology). I also got my own nextcloud instance up after much procrastination.

Now I decided to start shifting away from gmail. And I’ve been a gmail user since uni’. That is 15+ years, probably closer to 20.

I’ve also been a fond user of the send-as-another-email setup, basically living of mail forwards from various domains and using gmail as the all mighty source and destination for all mails (which enables great confusion when you pick the wrong identity). Well – no more of this (once my alternative setup is in place).

I’ve chosen to use fripost‘s services. The allow all that I want – custom domains, aliases, and so on, while doing this in a privacy based setup. The organization is an association rather than a normal company. This means that most of the work is done on voluntary basis. But, man, they are a helpful, friendly and skilled bunch. Right now we’re discussing SPF and DKIM setup, while I’m uncomfortably am fumbling around with DNS records. It will be great once I’m done.

And if I don’t reply to mail – I’m on vacation for a week, while moving to a new mail provides, so do resend that mail if I missed it ;-)

NextCloud on Pi Adventures

I spent yesterday *finally* setting up a NextCloud instance of my own. It’s been on my todo since I installed fiber at home and got a decent Internet connection.

I started out with Rasbian Lite and combined it with the NextCloudPi install script from ownyourbits. I then used certbot to install certificates from let’s encrypt before migrating the data directory using these instructions.

After that it was happy account creation time, before realizing that I could not upload files larger than ~10kB. Very annoying.

After having duckduck-ed and browser issues and articles for hours, I finally found that that the /etc/php/7.3/fpm/php.ini file contained a reference to the data directory.

sys_temp_dir = /new/path/to/data/tmp

This one-liner cost me about four hours to find, so hopefully this post saves someone else that time.

3D using Godot

It is time for another installment of Godot (previous entries: introduction, 2D). This time, I have dived into the world of 3D. The goal is to recreate parts of an old time favorite: Kosmonaut. Something I remember playing a lot on my dad’s 286 with amazing EGA graphics.

The state of the game when writing can be seen in the short screen capture below. This is more of a tech demo status than a full game at the moment, but I hope you will still find it interesting. You can also get the complete source code.

The project is split into two major parts: the Player and the World. Each of these contain scripts that I will refer to below. But first I want to talk about how to create 3D scenes.

Of course every scene can be created manually from individual elements. However, in 2D games it is common to use tiles to create large worlds from common elements. Godot’s analog in the 3D world is the GridMap.

A grid map is more or less a 3D tile map. Inside each tile (or cell, or whatever you call them in 3D) you can place an item. The way you create these items in Godot is to place each 3D element in a scene and then convert it to a mesh library. Then you can draw your 3D scene much like you can draw a 2D scene from tiles.

Once we have a world with a track (the grid map), we add a player to the scene (the yellow blob in the image above – I need to learn Blender to create a proper ship). The player scene contains the ship – and the camera. This means that the camera follows the player automatically – very convenient.

The player script is responsible for this ship’s movements based on user input. Inputs can either be pressed for a long time, used for sideways movement, or just tapped (i.e. the release is ignored), used for jumping. Each of the inputs are mapped to a keyboard key (or other input device) in the Project Settings dialog, under the Input Map tab. This feels a bit awkward to me and makes me lose the feeling of flow – but I don’t know how to do it better.

Getting gravity, jumping and bouncing to work was fun. It reminded me of coding games on my Atari ST. The character controller code is really basic, but can become super complex if one does not think through the order of the things you do. I ended up exporting some tunables so that they can be adjusted in the editor, just to figure out how high to jump and how fast to run the ship.

Figuring out crashes was easier than expected. Through the KinematicCollision objects retrieved using get_slide_collision, the normal of the surface collided with can be retrieved. From there on, it is easy to determine if the ship is sliding along a wall, or just hit it head on. The latter is deadly and the crash signal is emitted.

The crash signal leads to the world script. Here we handle the second death scenario – falling. This is a handled by the world, rather than the player, as the world knows what the lowest possible y value is.

The world also refers to two invisible scene elements used to mark the starting position ($StartPosition) and goal position ($GoalPosition). The first is used when resetting the player, while the latter is used to determine when the goal has been reached (duh).

When starting a run – or restarting for the millionth time, and when completing a track, a short sequence is shown. These sequences are realized using a CanvasLayer, Sprites and an AnimationPlayer. The canvas layer allows us to add 2D contents on top of (and behind) a 3D (or 2D) scene. Each such layer is broken into a scene of its own that encapsulates one sequence. Each scene have a small script interface with a play function and a finished signal.

When showing a sequence from the main world script, the script is started and then the calling function yields until the finished signal is emitted, as exemplified here. Very convenient!

One more word about the sequences: the animation player is a really convenient way to control all properties of a scene using key frames. It can even be used to call functions. I really like this.

On a side note, I found my first Godot docs bug when writing this post. The pull request is right here ;-)