Wednesday, 12 August 2026

[Flutter & Dart] I Released an App on the Google Play Store!

So even though I work at a games studio, I don't consider myself to have actually released a 'professional' program yet as I joined Rare in 2019 and Sea of Thieves was released in 2018. Even though my name is in the credits, I don't really count it as I wasn't there for the official launch, nor did I contribute any code to initial codebase.

I did upload a terrible web 'game' to itch a few years ago but I don't count that either.

[Background]
At the tail end of 2025, I was in and out of doctor appointments and had an MRI and a colonoscopy due to high levels of inflammation in my bowels. I was dreading the worse case scenario over the months. My older brother was diagnosed with Crohn's disease when he was 18 (he's now 38), and doctors diagnosed me with it when I was 21 along with Coeliac disease when I started displaying similar symptoms. 

For the past 14 years I have been avoiding gluten like the plague as well as the same foods that trigger my brother (that includes high fibre foods). I have been fortunate that my symptoms have not been as aggressive as my brothers. Statistics say people with Crohn's double their risk of bowel cancer every 10 years.

The results of the MRI and colonoscopy came back with; all clear. No Crohn's and the consultant even said I have 'great looking bowels'. I was extremely confused as Crohn's is incurable. They never actually did any tests when I was 21, doctors at the time just said it was Crohn's because you're 70% more likely to develop it if you have a direct relative with it. Also, Coeliac disease heavily imitates Crohn's...

I was 'demoted' to IBS. Either way, bowel cancer is no joke. My colonoscopy was on the 29th December 2025 and I vowed that one of my new years resolutions would be to eat the NHS recommended 30g of fibre a day as I did not want to have another colonoscopy in the future.

[The App]
Enter MacroTracker9000. The name started off as a joke (and has now been relegated to the debug name of the app), but I wanted a macro tracker that I could control that didn't require an account or network connectivity. I wanted to be able to edit it and add features as I went along. I've tried using the food tracking in the FitBit app and hated it as it's very 'American' focused, as is MyFitnessPal. 

I chose Flutter and Dart as I hate Java. Flutter's state system is really jank and disgusting but at least Dart is syntactically similar to C++. As much as I'm not a fan of the languages, they are super fast to iterate heavy UI apps in and you get cross-platform compilation out of the box.

I've been using Android Studio to make the app as I kind of hate Visual Studio Code and Android Studio is so much better than it used to be. I was using it during my degree to make an android app in Java and it was so clunky and difficult to use. It's not Visual Studio but I'll take it.

[Google Play]
What a nightmare. I originally tried releasing back in March and setting up a play developer account is a task and a half. I then got to uploading to the internal testing track where I saw the apps store front page for the first time and noticed that it was displaying my full legal name and legal address in the "about the developer" section. Google says they do this to prevent fraud if you are acting as a sole trader, even though there's no UK requirement for them to do this but they just do it across the board. I was not happy about this and tried to change my address using a legal document with a different address on it but Google just sent me round 5 different departments collecting support ID's. I eventually ended up with a guy called 'Alvin' who said he was 'liaising with a specialist department' but still heard nothing after 2 months, even though I was chasing Alvin up every week for an update.

I eventually ended up paying £200 to create a limited company, a private email address, get a new sim card for my old phone, paid a business in London to use their address and set up a business banking account with Natwest. The upside to all this is that business Google Play developer accounts don't need to do a 2 week testing period with 12 testers when launching a new app for the first time and I just released it when I was ready.

[Release]
I released it on a Sunday afternoon. Every post I had read said it would take Google anywhere up to 2 weeks to get round to reviewing a new app so I sent it for review thinking I'd hear something in a couple of weeks, it then went live 10 minutes later. It was kind of anti-climactic. 

There's still loads of features I've got on my Trello board and I tend to spend a weekend a month now working on it. I'd really like the ability to create more trackers inside the app like daily push-ups or habit tracking like 30 minutes of writing. With how Flutter's nesting of widgets work, I've already got things like "Daily summary card" and "Calendar View" as separate reusable widgets, so it shouldn't be difficult to create a page where users can select what widgets they want displayed on the page and where and what they should contain. 

Everything in the app exports to a plain JSON file so writing out new custom information is incredibly easy.

Its now also got me thinking about making other apps, mainly a clone of a game I hate called Township. I am somewhat addicted to it but I also loathe it with every fibre of being and curse the developers everytime I lose my super rainbow ball after I've just got it back.

It's times like these I really love being a developer. I can just make the shit I want to use and then not worry about the company pushing updates that changes the thing I loved about the app.

[TrackWell]
You can find it on the Google Play Store here: 

It's free to track food, water and recipes. It does have a 'premium' version that's £3.49 that includes some other things but it's a one-off payment that will include any other premium updates. I tried my best to make this app completely offline with zero permissions requested. Due to the premium billing, it's ended up with a permission on network connectivity (as it needs to connect to the internet to check your play account to see if you've purchased premium) but it silently fails if there's no internet and the app will continue to work just fine.

You don't need an account (you can't even create one anyway) and everything is stored locally on the phone. You back up the data by exporting it to a JSON file. I tend to save mine to OneDrive. Until you export it, it's stored in a binary format that only the app can access. Exporting simply creates a zip folder of JSON files and then hands that over to the OS and lets the OS handle saving it somewhere so the app itself doesn't need a permission on accessing your memory.

My favourite features are the 5 a day tracker and the weekly/monthly overviews for all my macros. If I've overeaten one week, it allows me to course correct over the month and even myself back out. I've also never been below 20g of fibre a day this year. I never realised how difficult it is to hit 30g of fibre and 5 a day and 100g of protein and stay below 20g of saturated fat. It's genuinely changed how I view food and what I decide to eat.

I'm pretty proud that I managed to stick with something and get it officially released. I also own my own company now, so that's cool I guess.

Monday, 8 December 2025

[SFML & C++] 10 - Creating a Release Version // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++17

In this tutorial we're not going to create another app, but rather, I'm going to take you through the process of creating an executable that you would use for release/shipping purposes. This tutorial focuses on creating a release version via Visual Studio, the process may be different for other compilers.

Contents:

Up until now, we've been using the SFML debug libraries and we've been building in debug. In release, the compiler does all kinds of optimisations to the code. However, those optimisations can make the program trickier to debug, which is why we always develop in debug mode. You should never really be shipping a debug build.

Now, there are two ways to build your program; with dynamic linking or static linking. Currently, even in debug mode, we've been using dynamic linking. This means, if I want to run my executable on a different pc that doesn't have SFML installed in the location I specified in the project configuration, you'll get an error about not being able to find DLL files. This is because dynamic linking still requires a whole bunch of files outside of the executable. This is why you'll see "install wizards" for certain programs. The wizard is basically extracting these files to places where the program expects it.

Static linking "fixes" this problem by bundling everything into one executable. This might sound better, however, neither is better than the other. It's up to you to decide which one is more suitable for your app. Here's some more info:

Dynamic Linking
  • Pros
    • Smaller exe size (but DLLs can be large)
    • DLLs can be updated without having to recompile the app (patches etc)
    • Faster compiling/linking times during development
  • Cons
    • DLLs need to be included with exe
    • "DLL Hell" version conflicts - this happens when a user has more than one version of the library on their computer
    • Slightly slower startup time (as the name suggest, it loads dynamically at startup)

Static Linking
  • Pros
    • Single exe file - easier to ship
    • No runtime dependencies to worry about
    • Slightly faster startup time (doesn't have to dynamically load libraries)
    • Users can't accidentally/intentionally delete/move required DLLs
  • Cons
    • Larger exe size
    • Can't update DLLs without shipping a new client
    • Longer linking times during development
    • Each program using the library has its own copy in memory. A easy way to think of this is, imagine you're running 3 games on your PC that all used SFML. If they were built using dynamic linking, they all share the same SFML DLLs as your PC is smart enough to load those DLLs into memory once. With Static, those DLLs are baked into the game so your PC thinks they must be 'special' and need their own version of SFML each. On modern PCs, this isn't really a problem, and most users will only run 1 instance of your app anyway but it's an interesting area of memory management that a lot of people don't tend to think about.

Alright, enough theory and waffling.

Github: N/A

1 - Dynamic Linking

Open up the properties for your chosen app and set the configuration to Release. The first thing to check is the language standard. In debug, I've been using C++17, and when switching to release, it changed it back to 14.


This is important because your program won't compile if you used language features that are available in 17 and not in an earlier version. So make sure you set it back to whatever version you were using.

Next, head to Configuration Properties -> VC++ Directories.

Now, we need to tell the release version to use the release libraries instead of debug. Go to Configuration Properties -> Linker -> Input

In debug, we use the "-d" on the ends of the library names. We can essentially just copy and paste these dependencies in release and remove the "-d" suffix.

Hit apply and ok. Now we can build a release version.

Set the build mode to release and build this project! (Note, if you've been creating all your projects inside of one Visual Studio project like I have, remember to only build this specific project. F7 will build all projects in release so you may end up with errors from other projects.)

There should now be another folder alongside your debug builds:

Inside those folders it looks like this:

As we're building dynamically right now, there is one more thing we need to do. You will also need to do this for debug versions as well (if you want to run the debug exe outside of VS).

Head to wherever SFML is on your pc and locate the bin folder:

You'll notice some extra DLL files in there. These are essential. Without them, you hit an error that looks like this when you try to run the program from it's executable:

All you have to do is copy and paste the relevant DLLs into your release/debug folder, next to the executable:
How To Create A Release Shipping Build Version in SFML - Creating a Release Version

Remember to also bring along any assets you're using. This is why I tend to stick assets in a "bin" folder instead of having them next to the code.

I'm not a fan of the copy/paste method, however it's fine for one off projects. You can write post-build scripts that VS will run to automatically copy them over or create a batch/powershell file that will do it for you.

And that's it! To share your program all you have to do is zip up that Release folder and send it over.

2 - Static Linking

So now we know how to build and release a dynamically linked project. What about static linking?

It's essentially the same process, only we use different libraries and don't need to copy and paste some DLLs afterwards. We do have to define a pre-processor macro though and link dependencies that SFML uses manually. I'm going to do this in a different project.

Set up your SFML project in the normal way, however when adding the additional dependencies, we now use the ones appended with "-s". Don't forget to set the language standard and include/library directories for release. If you want to use static linking in debug, the suffix is "-s-d".

We also need to add some extra libraries that SFML depends on. There is a list on their website of what to include.



Then set the pre-processor definition:

And that's it! In my Release folder now there's just the executable. If I double click and run it, it doesn't require anything else.

If you're wondering what the other file is, that's just symbols. These symbols help you debug your program but you don't need to ship them out with the exe in order for it to work. In fact, you shouldn't ship symbols with your game at all but you should keep them locally so you can debug your game. Each client build has it's own pdb, so v1.2 will have different symbols than v1.3 and if your customer says their game is crashing on 1.2 you can't use the symbols from 1.3.

3 - Removing The Console Window (Optional)

You may have noticed (if you're on windows that is), that the release build still launches with a console window. This can be useful if you still want to do some testing in your release build but you might not want it in your final distribution build. To disable the console window, simply go to the projects properties, ensure the configuration is set to release then modify the subsystem from console to windows:



We also need to change the entry point as well to mainCRTStartup:

Hit apply, ok and rebuild the project. The reason I chose to change the entry point in the project settings is so we don't have to change the function signature of main to something Windows specific like WinMain. This keeps the code cross-platform.

If you launch the app now, it won't have the console window.

And that's really all there is to creating "release" versions of your applications!

Friday, 21 November 2025

[SFML & C++] 9 - Simple UI: Basic Progress Bars // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that includes the basics of a progress bar class. Here's what the finished product will look like:
[SFML & C++] 9 - Simple UI: Basic Progress Bars  // Tutorial


Step 1 - Creating the Progress Bar Class

To start, what's our scenario for this tutorial? I eventually decided on the concept of a "magic bar", pressing space will use all of the magic bar in an 'attack'. Pressing R will refill the magic bar instantly. Pressing S will refill the magic bar over X seconds. When the magic bar is full, the space button can be used again.

This is quite a few mechanics in one, however it features pretty much all of the ground we've covered so far; displaying text, updating text, keyboard input, and timing. Hopefully this project will show you how easy it is to chain mechanics together to create more complex ones.

We'll start off by creating the header file:
There's a few variables here that we won't use just yet. I cheated a bit as well and made the member variables protected so inherited classes can access them without getters/setters. I usually wouldn't do this but it's for conciseness in the tutorial.

Also, this class has virtual functions but it's not abstract. This is an intentional choice because you can have a singular progress bar. In a "proper" project, a class like this would probably inherit from an abstract class like a "Shape". A shape is itself an abstract concept, you can't have a 'shape' by itself, it must have a type. 

As we're going to make this an inheritable class, we should always mark the destructor virtual as well so the correct destructor can be called by the compiler. Not that it matters much in this project but it's a good habit to have.

For the cpp file:


I've set up some defaults here so when we create an instance of it in main, we have something to see. There's nothing in here we haven't seen in earlier tutorials as well.

In main:
We create a font to pass to the constructor of the progress bar, create an instance of it and draw it. It looks something like this:

[SFML & C++] 9 - Simple UI: Basic Progress Bars  // Tutorial

Step 2 - Adding Deplete and Full Refill

So now we have something to work with, lets go ahead and process some events. For this I'm going to create a new class that inherits the progress bar and this will be a specific bar for magic.

The header file:

In here, all we have to do is override the processEvents function which is nice.

The cpp file:


And in main, just replace the instance of our progress bar with a magic bar and call our new process events function.

Now when you run the program you should be able to deplete the magic bar when pressing space and refill it with R. We can also tell this is our new magic bar class because the constructor sets the default colour to red and the base class is green.

We also have some basic checking like, we can't empty the bar further if it's already empty.



Step 3 - Adding Refill Over Time

You might be wondering why we created two rectangles at the start considering a RectangleShape has both a fill and outline. Well, a RectangleShape has no concept of "filling slowly over time" so that's what our mFillRect is for. Basically, the width of mFillRect is determined by mCurrentFillAmount. So for example, if the width of the rectangle is 100 units and the current fill amount is also 100 units, then it appears as "full". If the current fill amount is 50 units, the width is set to 50, giving the appearance of being half empty.

Just like in the first DVD logo tutorial, I'd like this to look smooth, so we'll need to use DeltaTime and an update function that's called each frame.


The deltaTime is used to create an increase amount that's added to the current fill amount each frame based on how long it takes to hit the max fill amount. We then calculate a fill ratio based on the current fill amount as our loading bar is an arbitrary number of units. Perhaps you can get upgrades that make the loading bar bigger? Perhaps it takes a different amount of time to load a level?

We also need to add an event for when the S key is released so it will refill:

And then last, we call the update function in main and pass delta time to it:

And that's it!

[SFML & C++] 9 - Simple UI: Basic Progress Bars  // Tutorial

Note, this is a gif optimised for web so the animation isn't as smooth as when run locally.

Things you should change:
  • The default position of the progress bar is hardcoded in the constructor.
  • A lot of things are hardcoded in the constructor....
  • The base class should probably handle emptying/refilling/timers and have functions that inherited classes can just pass values to that manipulate the effects.
Things you could change:
  • Perhaps space key only uses a certain amount of magic instead of the whole thing?
  • Perhaps there could be a health class? Or a battery left mechanic for a flashlight?
  • Maybe you want a loading bar between levels?
  • Maybe you want a cooldown mechanic between using magic attacks?

Thursday, 3 July 2025

[SFML & C++] 8 - Simple UI: Basic Button Class // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that includes the basics of a button class that handles, hover, pressed and released events. Here's what the finished product will look like:

How To SFML Create Basic Button Class Tutorial using C++ - Basic Beginner


Step 1 - Creating a rectangle button

To start off, we'll stick this in a separate header file instead of doing it in main. So create a new header file. Right click on the header file folder, add -> new item -> choose a .h file.

In the same way, create a matching cpp file.

In the header file we'll create the definition of the class (don't forget the includes for types):

Then we'll create the function implementations in the cpp file:

Now over in main, we'll create an instance of the button (include the button header):


If you run this code, you should see just a white rectangle on the screen. Very exciting.

Step 2 - Add Hover Event

In this next few steps we'll add 3 new functions, on hover, on pressed and on released. Knowing if you're hovering can be useful if you want to change the colour of the button so it's obvious that you're in the collision rect. On pressed is useful for situations where you might want a press and hold mechanic and released is useful for a one-time event, often used for "doing something" when someone clicks a button.

I'm going to start off with hovering. First we need to know if the mouse is within the bounds of the rectangle. I'll add a simple function to the header file to check for that as well as a bool to track to the state and an event function:

Then in the cpp, I'll update the SFButton::update() function and create the onHover():
I also added a new argument parameter to update so we can get the mouse positions relative to our window (the global positions are relative to the desktop screen).

Over in main, we'll now just call the button update function in the update section:


Now when you build, whenever you hover over the button, it should turn green. Then back to white. You might want to store the hover colour as its own variable...

Step 3 - Add On Pressed Event

Now we'll tackle the on pressed. This is very similar to the hover code. Instead of checking in the update function though, we'll need to poll our events to see if the left mouse button has been pressed whilst hovering over the button. In the header let's add another event function and a state:

Then in the cpp we check for button presses and if we're hovering, if so call onPressed():




In main.cpp, we now just have to call the buttons process events function:


Now when you run the program, it should turn green when hovering and red when pressed. But it doesn't turn back to green again, that's because onRelease() hasn't been implemented so it doesn't know what to do.

Let's do that.

Step 4 - Add On Release Function

Let's add another function:

And give it a definition:

Now we just need to handle the button release event:

And that's it. We created a basic button class.





Thursday, 15 May 2025

[SFML & C++] 7 - Animating Sprites // Tutorial

This is part of a series of small projects and tutorials using C++ and SFML

Library version: SFML 3.0.0
C++ Standard: ISO C++20

In this project, we'll make a simple app that loads a texture (image), gives that texture to a sprite and animates it. Here's what the finished product will look like:

How To SFML Animate Sprites Tutorial using C++ - Basic Beginner


Step 1 - Creating a Sprite

What is a sprite? In game development it usually refers to a drawable object that references a texture. They usually have functions that allow you to set the position, rotation, scale and others. They are used primarily for the main "objects" in your games like the main character, enemies, items etc. 

By themselves, sprites have no concept of animation. They load a single image each frame. Therefore to animate them, you need some code that updates the image each frame.

Why doesn't SFML do this for you? Well, animations come in all shapes, sizes and varieties. The speed, duration, loop ability. These are all left down to the programmer to implement as the developers of the libraries cannot be expected to cater to every situation.

Enough talking though. Let's make a sprite and show it on the screen. Sprites load textures. So we'll need a texture first and give a reference of it to the Sprite.

I'll be using the following spritesheet for the purposes of this tutorial:

Please note this is for learning purposes only.

The reason I'm using it is because all the separate frames we need are nicely laid out into little squares so we can easily access them from our texture when we need to update the animation each frame.




Step 2 - Offsetting into a Texture

Now this doesn't work as expected because we're just loading the entire image and displaying that. We only want to display part of the texture. So we'll need to create an offset into it. I've already done some calculations for you and those squares are 48x48 pixels. The start of the walk animation is at x268, y576.



That's better.

Step 3 - Animating the Frames

So to animate this, all we have to do is move the texture rect 48 pixels to the right (+ a 4 pixel gap between frames) to give us the next frame. Then we do the same again, then go backwards to the start. We can simulate this by just using a vector to store the positions.



How To SFML Animate Sprites Tutorial using C++ - Basic Beginner

And done! And that's how you basically animate sprites. We use the delta time to gives us a nice animation speed as well. Animation is a massive part of game development and it would be nice if we could wrap up of our animating code into something reusable.