Showing posts with label dev diary. Show all posts
Showing posts with label dev diary. Show all posts

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.

Wednesday, 14 May 2025

[Dev Diary] The Tool Jam 5 - Creating a Random Lore Generator + Fun with Markov Chains

It's about time I took part in a game jam but this one really intrigued me. I think it's because I tend to work on the developer tools these days rather than the game itself; I find it more interesting. Therefore, this game jam caught my eye.

I've always been fascinated with random generators. The kind from the early internet days like Seventh Sanctum. I've long wondered how these worked and I've created some simple generators using the basic idea over on my playground using HTML, CSS and *shudder* JavaScript. I thought this would be the perfect jam though to do some research and really dig into how random generators used to be made convincingly and do it using my favourite C++ and SFML combo.

Warning, this is a long post.

Research - Ask ChatGPT
First off, I had a great conversation with ChatGPT about how those sorts of generators were made and what kind of algorithms they used. It started off explaining 3 ways to implement my game jam idea:

Grammar-based using rules and templates
Basically recursive string placement and you supply a whole load of word types.
The [adjective] [noun] of [proper-noun or abstract-concept]

Mad-libs approach
A more basic version of the grammar based approach, where different types of sentences are supplied.
Long ago, in the time of the #adjective# #noun#, the #faction# waged war against the #enemy#

Layered Abstraction
Basically structured nonsense. Here, the word types are already built up from other approaches to create something that sounds more AI generated.
[Proper Noun] was last wielded by the [Faction], a cult that believes [Purpose].

I found this really interesting, especially as the word types like [adjective] and [Purpose] could easily equate to an enum. I could create a list of enum word types, store everything in text documents and then "build" sentences from these word types. Add in some logic using rules and templates, like adjectives must always be before a noun, and I could quickly create something quite random.

Markov Chains
I then asked if all this data was really just stored in text files and it said yes, but ChatGPT always says yes. But in its explanation it started talking about Markov Chains. This is the kind of computer science mumbo jumbo I was hoping to get from GPT. I went off and researched Markov Chains and it turns out they are basically a way to generate sequences of stuff. You seed them, and the next item in the sequence is based off the item before it but they don't have full context over the entire sequence. Kind of like ChatGPT itself. 

Markov Chains are statistical mimicry. They have no concept of grammar templates or meaning. In essence you could say they are the spiritual ancestor of LLM's. 

Armed with this knowledge, I then started wondering if you could give Markov Chains more context. ChatGPT informed me that my best bet would be to implement Conditional Markov Chains mixed with Probabilistic Grammar and Weights. This involves different Markov models like religiousMarkov or plantMarkov mixed with assigned weighted probabilities. So if a weapon name is "Cursed", you're more likely to get a backstory involving betrayal or a wielder with a tragic fate over a backstory where the goddess bestowed it due to kindness.

V1 - Basic C++ Lore Generator
Armed with some fun research, I then went off and made a basic console version of what I wanted. To start off I made a simple enum of word types, created a map of word types to strings. Then 'built' sentences using those word types and created a random sentence by filling in the word type with one of those strings:


All good stuff. 

V2 - Basic C++ Lore Generator
I expanded slightly on this version and moved over to using text files so I could easily get GPT to generate a load of words or phrases for me that I could add to the files. I added a way to load those in to be used instead of hardcoding it in main.


V3 - Creating a Basic Markov Chain Model
This is where shit got fun. With the help of ChatGPT, I got a very simple Markov generator going that takes in a text file of words and then "trains" itself on that data set. Then, in the place where it gets a random word from the "word pool" of that specific type, it would request a word from the generator instead. These words were actually plausible and looked 'right'.

You can see here my full list of names I created and the name the generator created. I also cleaned up the code at this point and moved everything out into seperate classes as it was getting messy in main and I hate having global variables and static classes just hanging around.

At this point, it kind of felt like I had created baby's first LLM and I was very happy. It then occurred to me that I could then chain the markov chains together to create the initial lore template itself, essentially creating a fully generative 'lore engine' so to speak.

I put this to ChatGPT and it started talking about word tokens instead of using individual characters and it was like a lightbulb went off in my head. ChatGPT itself works on tokens instead of characters (you've probably seen this from the infamous 'how many r's are there in strawberry'). I would now be recreating this, albeit in a very basic and crude manner.


V4 - Markov Based Word Chain Generator

First, I turned my initial Markov generator class into a pure virtual class, and created MarkovWordGenerator which inherited from it. The Markov Word Chain generator still needs an order and train/generate functions but they need to be slightly different. This would then allow me to have Word generators and Sentence Generators.

This did work...somewhat. The markov model was too accurate given my limited data set I was feeding it. This meant that it always returned the exact sentence as found in the training text file. Giving it an order of 1, gave the model less context but the sentences produced lacked context and so the sentences were jumbled and didn't make sense (in English anyway).

I also wanted more control over the types of sentences created. So I ended up making a text file that had sentence templates for item lore.

I then "trained" a markov model on a large text file that ChatGPT produced for me of item lore sentences. Then created functions that allow the user to just call "generateItemLore()", and it goes off, chooses a random item lore template, then replaces the bracketed sections with something from a word pool or in the case of {{sentence}}, replaces it with a markov-generated sentence.

I then added a way to have the user input a name for the item or generate one randomly:
Creating a random Lore Generator using pure C++ and Markov Chains

Even with a larger "data set", I still have to set the model to the lowest setting (1). The sentences make more sense than previously but can still seem 'off'. It'll do though.


V5 - Creating the UI

Now with a simple item lore generator pretty much created, I wanted to move away from the console for a bit. I kept them as separate projects so I could continue working in the console one to prove out ideas then move it over to the UI version.

So I created a window, added a nice background image and some background music, then I got to creating the text boxes and remembered that SFML and text is not great. This is a program that is mainly reliant on entering text and displaying text. So I switched out SFML for FLTK. FLTK is a fantastic little library that is way more suited for this kind of task than SFML. The only issue is that I have my own wrapper around the library and I haven't turned that into a library yet so I had to pull every single file across.

Honestly, the thought of having to create a scrolling text box class in SFML just had me noping out within 5 seconds. FLTK was made for this kind of program.

The weekend then happened. Also it was sunny, which is rare for england, so I forgot about it until an hour before the jam closed. I considered not submitting but for once I was seeing a jam through. And I managed to submit with 11 minutes left to go:


Overall Thoughts
This was a lot of fun. Especially as I've come to understand how LLMs were initially created. There's is so much power in having a "locally trained" generator though. I'd be interested in making this do other things like generate documentation on code bases. But for the moment, I'd like to add a proper UI using a library and then expand it to creating lore for places and people. Also, allow more modding capabilities.


Monday, 24 July 2023

Dev Diary // FLTK & Tetris Part 2

A little while ago I had fun making Tetris in FLTK; a library not meant for games.

It worked perfectly except for the bad flickering that I thought was down to the fact that FLTK just wasn't designed to handle games.

Then today I was working (as usual), and I saw a some code in Unreal Engine called double buffer and a light bulb went off in my head. When using something like Direct X, you usually set up a swap chain, and a buffer and a second buffer and all that jazz because the whole point is to draw your next frame to an unseen buffer, then you swap the unseen buffer with the one currently being displayed; ad infinitum. 

I wondered if this was the actual issue and the flickering was being caused by screen tearing. Turns out, it was. I had a look at the FLTK documentation and they have a solution for this!

Fl_Double_Window is a type of Fl_Window, so seeing as how my Window wrapper is a wrapper around Fl_Window, I just inherited from Fl_Double_Window instead and voila! No more flickering; it just works™.

FLTK and Tetris using C++ - Using FL Double Window to prevent screen tearing

This made me very happy. It's very smooth now and it's actually got me excited for my planned Game Engine: Blink. What can I create now? I could do anything.

Tuesday, 18 April 2023

Dev Diary // Using ChatGPT to make an Idle Clicker Game

There is an idle clicker game called Cookie Clicker. It's amazing, you click a giant cookie, to make more cookies, to buy buildings and upgrades that will make cookies. There is a grandma apocalypse, a dragon called krumblor and ascensions. Kittens can give you milk multipliers which boosts your cookies per second. The entire goal is to make as many cookies as possible per second. It is utterly addictive and completely free:

Cookie Clicker was first released back in 2013 and I started playing around 2015. Soon after release, the creator made a website: Idle Game Maker, which turned the cookie clicker code into an engine and allowed users to make their own idle game. It's really intuitive and easy to use; and you can host your game for free using their website.

Whilst messing around with that engine recently; I realised a lot is hidden away from the user. Being an engine programmer, I wanted to know more about how clicker games actually function but I have next to no knowledge of web development; enter ChatGPT.


The above video is me sitting down with Chat and trying to get it to create the bare bones of an idle clicker with as little coding from me as possible and I'm amazed at the results. I filmed for 50 minutes and by the end of that I had a clicker game with 2 buildings and a lucky button that appears randomly. I edited about 3 lines of code in total but used ChatGPT to generate everything for me. Even asking it to move CSS elements to different places.

I don't think I would continue trying to get it to create the entire game as that would get a bit tedious; but now I've got the bare bones, I've got a solid starting point to tinker with. I would probably start making it look prettier first before adding anything else.

HTML, CSS and Javascript are completely outside my zone of knowledge but having looked through the generated code; the html and JS is actually pretty readable and easy to add to. The CSS on the other hand will require some more thought.

You can find all the code generated in this session here:

Tuesday, 14 March 2023

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

A colleague introduced me to the YouTube channel javidx9 the other day with the video:

I sat down after a gym session one dreary monday night and the 36 minute video took me about 90 minutes but javid had delivered and there was Tetris in the console window in about 300 lines of code. I also really enjoyed the little maths trick he employed to rotate the tetromino pieces. I found the video to be a bit rushed in places and some things cut out so I had to refer to the github repo quite a bit. Some things also went unexplained and me from a few years ago would be quite confused but on the whole; a solid tutorial.

Tetris was on my list of games to clone as it's a classic, easy-ish to implement and rife for tinkering. And tinkered with that initial small program I have.

Console Window
Here is the repo for my "all-in-main" version that I wrote whilst following along with the video. It's not exactly as his code but close enough:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

++Console Window
I then set about taking this apart and creating a more generic Tetris that could eventually be run using any library. This one still runs in the console window but the input options, rendering, tetromino mechanics have been abstracted to work regardless of what library you're using....in theory.

FLTK
This is a small lightweight API  that I was introduced to whilst working my way through Principles & Practice. I actually really like it due to it's simplicity and Windows 95 looking graphics. This was the first test to see how portable I'd made my code in the previous exercise.

I started off modifying the wrapper code given in the book Programming: Principles & Practice by Bjarne Stroustrup. I've been meaning to do this for a while; it's not a perfect wrapper but it makes iteration in FLTK a bit faster.

Here's the repo:

With that done, I then found a free Tetris block png off the internet:

I used GIMP to change the hue of it to create 6 other colours.
Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

I then created a simple window with a quit button.

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

Now I needed to find a way to display the Tetris Board on the window. At this point I already had all of the code needed from the console versions so I created a grey block and wherever '#' is drawn, I told it to draw a grey block instead.

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

Next was to draw the current piece. This required some tweaking but after some trial and error I managed to get it working without having to expressly tell the individual blocks to draw to make up the shapes (it used the text created in the console versions).

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)


I then started copying over all the update logic to move and rotate the pieces. I was extremely surprised that this "just worked". FLTK does have it's own Keyboard event handling system however, the default windows one worked just fine with it so I stuck to that instead of changing it.

To create the "game loop", I used FLTK's timing system and registered a "tick" function with it. The tick function updates the Tetris board then redraws it. The tick function also handles updating the game tick counter to regulate tetromino speeds and locking them in place:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)
Please ignore the flickering; FLTK and my screen recorder don't get along.

The only thing left after all this was to print out the score:

Dev Diary // Adventures with Tetris (C++ Console Window & FLTK)

And with that I got bored and got the itch to do something else. I will come back to this though as I'd like to do it in SFML next, add sounds and such. I was happy I managed to get a "game" of sorts working in FLTK though as that library is not built for games....and it really shows. It was fun creating helper classes though. I'd like to know why it's flickering so much once the screen gets really full. I think it'd be a good task to delve into Visual Studios performance profiling and debugging options.

EDIT 25/07/2023
I fixed the screen flickering: