Activity

robkoo

Shipped this project!

Hours: 12.9
Cookies: 🍪 190
Multiplier: 12.27 cookies/hr

Introduction

This is the first stable release of crobgol, which is a high performance terminal based Conway’s Game of Life simulator written entirely in C23. In this project I tried to implement optimization techniques to make it fast and memory efficient. Below you can find a list of features. For more info, check out the repository:)

Features

  • Full CGoL simulation with customizable grid size and FPS
  • Entirely Custom CLI argument parser with short/long options and value taking
  • Dual rendering modes: Unicode and ASCII
  • Optimized bitmap grid using uint64_t* instead of the old char array
  • built-in benchmark mode to compare old vs new grid implementation
robkoo

And to finish up the initial release, I worked thoroughly on the README to make it pretty and contain lots of info. That includes a demo GIF, shields, badges and such (see attachment).

I also created the releases and set up everything to be as smooth as possible for you guys:) I hope you enjoy my neat little optimized game.


PS: Please ignore that my font/system does not support U+2605 (its meant to show this: ★)

Attachment
0
robkoo

Shipped this project!

Hours: 15.01
Cookies: 🍪 496
Multiplier: 27.52 cookies/hr

For more info about the changes, feel free to read the devlogs that I have posted since the last ship:) Here I have written a simple overview of the changes done.


Since the last ship, I have added a very beautiful shader that renders the Mandelbulb 3D fractal. I also added some utilities, such as a memory leak checker script, make targets, in-app scene switching and frame rate indepedence. I also implemented a bunch of bugfixes, regarding memory, logic issues and such.

A huge feature, that could possibly keep pushing the shaders forward, is my custom GLSL preprocessor. For now it supports the @include directive, which, as you can guess, includes a shader file. It handles recursive includes, so you can include a file with had something included.

robkoo

This devlog essentially covers some small updates that finished up pre-release v0.2 (and v0.2.1 but that was a tiny bugfix).


README changes

I spent a lot of time researching online about README quirks and such, and I believe I made a very pretty README that I can be proud of. It features an animated title, lots of shields, new entries, a table of contents and a gif right there on the top of the README. (See attachment).

In-app scene switching

Instead of having to change the source code directly to check out the different scenes yourself, you can now simply press ‘,’ or ‘.’ to switch between different scenes right in the app.

v0.2.1 Windows bugfix

The v0.2 pre-release didn’t compile on Windows due to a few issues:

  • <windows.h> lib declaring/defining really GENERIC symbols, such as ERROR, CreateWindow() and such. I had to #undef the ERROR macro and rename my window functions to be able to include this lib.
  • using r as a file open mode rather than rb on Windows causes CRLF (\r\n) to be converted automatically into \n, which then causes my program to crash as the file size wasn’t matching.
Attachment
0
robkoo

Shipped this project!

Hours: 15.29
Cookies: 🍪 318
Multiplier: 20.82 cookies/hr

Overview

This is the first pre-release of the CLI tool called syedm, which is my lightweight dotfile manager. It’s a symlink-based dotfile manager, which, in my case, means it symlinks your dotfiles from your repo to the appropriate directories on your system. It is written entirely from scratch in C(23) with NO external dependencies. Below you can find explanations of each feature and what it does.


Features

Custom CLI argument parser

As you would imagine, a CLI tool needs a CLI argument parser. I built mine completely from scratch, and currently it supports:

  • short flags (e.g. -n)
  • long flags (e.g. --dry-run)
  • combining short flags (e.g. -ni)
  • value flags (e.g. --install .)
    There is a built in help flag, which displays all the options, whether they take a value and a short description (see image).

Installing dotfiles

Installing dotfiles is straightforward. First, your dotfiles repo must match the structure outlined in README.md (here). Then, if you are in the root of your dotfiles repo, simply run syedm -i . and that will install your dotfiles from your current directory to the directories based on the mapping. You can change these defaults by passing the appropriate flags with the appropriate paths.
By default, syedm WON’T overwrite files that already exist on the location(s) it tries to install your dotfiles to.

Dry-run (preview of changes)

A really helpful feature that I’m pleased is part of my project is the option -n, --dry-run. It shows what WOULD happen if you were to, for example, install your dotfiles. This is really helpful as you can preview what the tool would do. For example, running syedm -ni . will preview what the tool would do while installing. It also works on a couple of other flags.

Force

If you wanna overwrite files that exist at locations syedm wants to install to, simply pass the -f, --force flag while installing.

Status

If you wanna check the status of your dotfiles, you can run syedm -s . and that will print the status. Some status options include MISSING (not installed) or IS_DIR (destination is a directory). For a full list of the output, please consult the appropriate entry in README.md, that can be found here.

Logging

The project uses a custom logger I built, which logs into stdout with great detail. Logs include the source file and line of the log, colored severity (DEBUG, WARN, etc.) and the actual info. This is a neat feature that ensures errors can be easily traces and debugged.

Internals

If you are curious, I have implemented, for this project, a kind of OOP in C. I use opaque pointers in structs to hide away the “private” members, ensuring you can’t directly access/modify the members. You can only get/set these via dedicated getters/setters. I have also made the structs use the singleton pattern by holding the instance of the struct in a static thread-local variable, which makes it so you can have a very nice clean syntax, such as logger->SetColor(..) without having to pass the struct in the function. The structs contain function pointers, ensuring you can use familiar OOP-like syntax (e.g. cli->CliParse(...). I believe this really sets my project apart as this is a fairly advanced C concept.


Conclusion

I personally use this tool to manage my own dotfiles, as I had built it specifically to fit my use cases. It is quite primitive, and I do plan to expand it, but right now it does all it needs. If you have feedback about anything, including new features, improvements, bugs, PLEASE let me know and I’ll make sure to fix them. Thanks for reading this!

robkoo

Finished up the pre-release of this tool, by polishing the README, CHANGELOG and adding a package target, which lets me compile and make an archive for the releases page.

Attachment
0
robkoo

Overview

In this rather short devlog, I simply improved the README to include details about the optimizations I had made and I also added Unicode support (and made the --ascii flag actually do something)


Commit 5e98a9c620

Nothing much to say here besides the fact I improved the README. Besides the aforementioned optimization section (that can be found here), I added a section where you can see a neat table that displays info about each flag available in this tool. You can find it here.


Commit 01a60aa3ed

In this commit I have added Unicode rendering support, which uses the U+2588 (█) character to indicate an alive cell. You can disable this by providing -a, --ascii while running the executable, which will use the # character to display an alive cell. I also slightly improved the game printing by adding a generation counter. You can see this in action by watching the provided video.

0
robkoo

Overview

This rather big devlog is entirely dedicated to optimizing the previous implementation as per the optimization sidequest. To sum it up, I implemented a more optimized data structure to hold the grid and a more optimized way of counting neighbors and computing the next generation in the game. Below you can find a more detailed explanation of the commits that contain this work.


Commit 04af1c83d5

Optimized data structure & functions

The biggest change here is the aforementioned optimized data structure, which is the bitmap. Instead of storing each cell as a char (8 bits per cell), each cell gets a bit inside a bitmap (1 bit per cell), which drastically decreases the memory usage of this program by 8 times.

For this to work, I had to implement functions to work with the bitmap instead of the char array. They’re named exactly the same as the older functions, just with Bitmap prefixed to clearly indicate the use case.

Benchmark

Another notable change in this commit is the addition of a benchmark, which compares the old and new implementations of the function that computes the next generation. You can run a benchmark by passing an option --bench <number> where <number> is the desired amount of iterations to test. Optionally, you can also pass the width and height of the grid that will be benchmarked.

The actual benchmark is not primitive either - it first warms up the caches by running a few iterations before actually timing the functions. Both the functions get the same starting grid to ensure fairness while comparing. The timing uses CLOCK_MONOTONIC, which is NOT affected by system time changes and it can only move forward.

Optimization results

As mentioned before, the memory usage is 8x lower now, due to storing one cell in one bit rather than one cell in 8 bits. The new function to compute the next generation is also much faster, and from my testing can vary between 3x-4x speedup (see image 1). These are by no means small gains, and you would see the difference especially if you’re trying to simulate huge grids. More details can be found in the Optimizations section of the README here.


Commit 0691bc561b

Overview

This is a bugfix/slight improvements commit. I focused on memory leaks, which I initially missed. I also fixed inconsistent naming of the new functions. I have also gone through and improved checks in some functions that were missing to ensure that no incorrect behavior will go on unnoticed.

One small improvement I have made that I find quite noticable is the fact that if you forget to include a value where you’re supposed to have one, the program won’t silently continue and just skip that argument, but rather terminate after printing the help message (see image 2).

Attachment
Attachment
0
robkoo

Shipped this project!

Hours: 21.11
Cookies: 🍪 414
Multiplier: 19.61 cookies/hr

Intro

Comparing this ship to the original Alpha v0.1 one, there are quite a few huge changes in the game. I will go through each version since the first ship one by one to familiarize you with how the game evolved since.

Fun fact

Since Alpha v0.1, 56 files have been changed, 5543 lines were added and 1121 removed. Substantial progress has been made.

(Checked via git diff v0.1..v0.1.3 --stat)


Alpha v0.1.1

This version brought a HUGE UI overhaul. Alpha v0.1 featured (mostly) basic white-on-black UI, while in this update, visual chrome was added to each scene, giving them some depth. There is also a neat animation in the main menu. The tournament info scene for play-offs had also been revamped, now featuring a bracket style UI, instead of the old, simple text. Honorable mention goes to: being able to have 3 save slots instead of 1 :)

Internally, I added files for storing standardized UI elements and UI values (ui::tokens, ui::prefabs). Biggest example of this is the scene chrome, which is standardized across all scenes from this. Button interaction APIs were also massively expanded.

There’s a ton of changes to go over, mostly tiny compared to the UI overhaul, so I won’t go into too much detail over here. Feel free to read the CHANGELOG entry here for more info.


Alpha v0.1.2

This update focused on usability. Biggest changes include the addition of persistent helper bars to the roster selection scene and training scene. It also included changing resolution, so you could finally enjoy the game at a higher resolution, if you wish to do so.

The simulation was also touched on a tad. Now, the selected shooter on ice is selected via weighted random sampling (based on shooting stat), rather than picking a player with the highest shooting stat (currently on the ice).

If you need more detailed changes, you can find the CHANGELOG’s entry here.


Alpha v0.1.3

And last, but definitely not the least - Alpha v0.1.3. A brand new UI component was added - the Modal. Now, modals can pop up if you try to do a destructive action, such as reset tournament data, as to confirm your action. They are also used for info, which can be seen on first entry to Game Main Menu.

Internally, modals required a rewrite of how the Scene class handles components. Previously, it just iterated over its internal arrays of components and components groups and simply rendered them. This wouldn’t have worked with the new modal, so I added support for nested component trees. Now there’s a neat method to serialize the UI components into a single array, which is then easily able to be iterated over, and the method ensures correct order for rendering modals, modals’ components and the rest of the scene.

Another quite notable change is the addition of a player statistics scene. Ever since the early days of this project, players had a ton of statistics tracked, such as goals, time on ice, penalty minutes and so on, but no way to showcase them. The scene features a neat paginated table, ordered from the player with the most points, to the least.

Last big change of this update was the addition of a line swap scene. This required me to extract the line rendering code from roster selection, so I could reuse it in this scene. You can edit your lines via swapping compatible positions (e.g. C<->C, LD<->LD).

If you wish to read more, check out this version’s entry here.


Outro

If you made it all the way here, thanks for reading this message! The game has come a long way since the original release, and I hope you will enjoy it:) The most challenging part of this ship was definitely all the UI stuff, as I’m not that well versed with UI. I’m proud of how the game has improved, including simulation, UI, more scenes to explore and such, and I’d definitely like to keep working on it. Let me know in your votings’ reviews what I could improve, I would greatly appreciate the feedback.

robkoo

I finished up work on the Alpha v0.1.3 update and recorded a demo video for anyone to look at. It showcases (nearly) all of the functionality of the game. What isn’t obvious at a first glance is the save system, but if you look closely, once I click on “Preview & simulate”, you can see match-up number 2 waiting for me, therefore confirming saving and loading data works. I hope you all can enjoy my game, and I apologize for not writing enough devlogs. That one huge 65hr one was me frantically coding this as a school project.

0
robkoo

Summary

Quite a few changes to go over, but to summarize it, I made a CLI argument parser with the option of passing either a short flag (such as -a) or a longer version one (such as --ascii). Based on what you pass you can control some game settings (and more to come!)


Commit c754f6e2e1

This commit contains the implementation of the parser, which I have done completely from scratch. As mentioned in the summary, you can define flags to have values (numeric or generic), short and a long name. The option parser prints to the console if anything went wrong, e.g. you passed a non-numeric value to an option which expects a numeric value.

The actual parsing is done in a very simple way:

  1. Iterate over all the provided arguments starting from index 1 (index 0 is the name of the ran executable)
  2. Check for dashes in argument. This step also provides the count of dashes (0, 1 or 2)
  3. Parse the value of the argument.
  4. Validate whether the argument is defined in an array of structures.
  5. Parse the argument value if the argument requires one
  6. Save argument into a struct and repeat
    If, at any point, either of the steps fail, the current iteration is simply skipped.

[!WARNING]
For anyone checking out this specific commit, be aware of a stray exit(0); that I forgot to remove while I was testing at src/main.c:17


Commit e4b0bb07d6

This is the commit that connected the existing game to the CLI parser. I declared some default values, which are as follows:

What Default value Explanation Width 80 In cells Height 24 In cells FPS 15 In FPS, duh ASCII false True - render using ASCII, false - render using Unicode

If you do not provide an argument with a value, defaults are used. In the provided video you can see the functionality of these flags.

[!WARNING]
Passing a huge FPS value will probably disable the option of killing the app via <C-c> (Control+C)!

Same thing as the previous commit - I forgot to remove a stray exit(0); (at src/main.c:19)

This commit also includes a very useful change: You can now see a neat helpful menu by running the --help flag (see image 1).


Commit b9a9616448

This is just a bugfix commit. I fixed incorrect assignment of parsed values into the app settings, incorrect parsing of short and long options, removed some useless code, and finally, removed the exit(0); call which was blocking the app from being ran.

Attachment
0
robkoo

And now, the commit (48b6f59cab) with the actual Conway’s Game of Life. This was really easy to implement, as the game contains very simple rules. For a cell, with 8 neighbors, the rules are as follows:

  • If the cell is alive, and it has fewer than 2 neighbors, it dies, as if by underpopulation;
  • If the cell is alive, and has 2 or 3 neighbors, it lives on;
  • If the cell is alive, and it has more than 3 neighbors, it dies, as if by overpopulation;
  • If a cell is dead, and has exactly 3 neighbors, it gets revived, as if my reproduction.
    So, by implementing these simple rules, we get the output you see in the attachment video. That runs an infinite loop that always prints the next generation. Don’t worry, this isn’t the end of the project yet, I have a few things planned to make this unique from other implementations of Conway’s Game of Life. Stay tuned! :)
0
robkoo

First commit of this project; and it’s a simple one. All I did, in the first commit (36435c4e53), was prepare the project’s Makefile, README.md, LICENSE.md, directory structure and a simple main.c.
The next commit (27f29b7902) I implemented very basic functions to work with a grid, which hosts all the cells where the game will happen.


In the image you can see, on the top, the grid after filling it via GridRandomize() with 0.224 density. After that, I cleared it and set the cell at x: 22 and y: 4 to 1. This simply showcases the functionality of these functions.

Attachment
0
robkoo

This devlog I made another beautiful shader. This time it is the Mandelbulb, which is a 3D infinite fractal. It serves as an analogue to the famous Mandelbrot fractal, as they showcase similar patterns at various scales. The colouring of the fractal uses Orbit trap, which gets the color based on how close an iterative function, used to create the fractal, approaches some shape. I think mine might be a bit wrong, but the colours are really cool nonetheless, so I just kept it this way on this nice pink (even though I aimed for magma-like colours lol).


I also changed a bit of the internals of the shaders, as, to get the Orbit trap data out of my shader functions, I had to make a structure for it. I made sure not to influence the previous two shaders, though, so they should behave exactly the same.


Of course, with a new shader come new DEMO entries. Check out the demos here :)


In the provided attachments you can see the fractal from various positions.

Attachment
Attachment
Attachment
Attachment
0
robkoo

I followed up on the previous devlog by restructuring the shader directory. Now it’s divided into folders (see attachment 1) where each of them contain/do a specific function. I had to re-write a bunch of the code to fit this new scheme, and I also had to add recursive include support in my custom preprocessor. Attachment 2 shows the updated shader for the Menger Sponge, where you can see the custom includes. I also did some minor bugfixes and such across the codebase. Next devlog should finally be more shader stuff:)

Attachment
Attachment
0
robkoo

I have some neat plans for future shaders, but I recognized that they would use the same functions like some other shaders. That’s why I decided to write a custom GLSL preprocessor. In this devlog I added support for the include directive, which, as the name suggests, lets you include other GLSL files. It simply replaces the directive call with source code that you wanted included. I ran into quite a bit of trouble with memory corruption and such, and that’s why it took quite a while to get this working.


What I really like is that I made it nice and extensible, so when I need a new directive, I just add a few variables and a function to handle the directive and it all should work like a charm:) Expect some pretty shader stuff next devlog, though.


In the image, on the left, you can see the source code of the shader after my custom preprocessor ran. On the right you can see the contents of test.glsl, which used the include directive, and below that the contents of functions.glsl, which is the file that was included.

Attachment
0
robkoo

When I was testing my app, I found out that there may be memory leaks within my code. I then ran valgrind (a cli tool that displays memory leaks amongst other things) and found quite a range of issues. I fixed all of them, and I also wrote a script (checkMemoryLeaks.sh) that compiles the project, runs valgrind on it, saves the output of valgrind to a file, parses the file to find issues with the project files and neatly outputs the lines in the valgrind log occured. I used that output to validate that the program shouldn’t contain any more memory leaks caused by me. The script outputs some detailed info thats coloured for clarity.

The image shows the output of my script after valgrind has finished running. The remaining memory leaks are not my fault; I checked each one of them in the valgrind log file and found that the stack trace leads to functions out of my reach.

Attachment
0
robkoo

Shipped this project!

Hours: 15.55
Cookies: 🍪 337
Multiplier: 21.65 cookies/hr

The first pre-release of this shader project. It’s built from scratch using C(23) and GLSL, which I’m proud of. I tried to minimize external dependencies, so, for example, I’m only using core stuff such as GLFW. Other stuff, such as the math behind matrices or vectors, was implemented by me.

Currently there are two ray marching shaders in this project; a Menger Sponge one, and a sphere one. The Menger Sponge one allows you to render a Menger Sponge of any desired stage (if your GPU can handle it, that is). The sphere ray marching shader allows you to render a uniquely coloured sphere with diffused lighting, whose scene contains a light source to see the diffused lighting in action. Both of the scenes have a 3D first person camera available, which you can move by using the keys WASD and moving your mouse.

If you can’t/don’t wanna run the project, you can check out the demos (link) to see how the project looks.

robkoo

To finish up the first pre-release of the project, that being version v0.1, I created a file named DEMO.md (link). It contains various images and clips that showcase the shaders in this project. I also finally filled up the changelog (link) with thorough descriptions of each version of the project (you can check out the commit history to see the tags with version that associate it with commits). I also renamed the project from raymarch to raych, as I thought the original name was too vague. I updated the Makefile to be able to package an archive with the binary within. I also added Windows support, via the UCRT64 shell.

Attachment
Attachment
0
robkoo

As I mentioned in my previous devlog, I wanted to add a 3d camera; which I did in this one. I had to implement a bunch of vector and matrix mathematical functions to be able to have a 3d camera. I am far too tired to set up video recording on my system, so I provided a photo of the Menger sponge from an angle that I could get only by moving my camera.

Attachment
0
robkoo

Finally some fun, shader stuff, eh? I, first, created a very simple camera system, which allows you to move on the X and Z axis. It’s a very simple implementation, without any transformation or rotation matrices. That is the plan in the future. You bind the camera movement to a shader struct inside the main while loop, which then lets you change the shader’s camera position, and in the shape render function, it gets passed as a uniform to the fragment shader. After getting that done, I worked on implementing an infinite (in theory) 3d fractal named Menger sponge, which I was able to do after learning up on shader concepts and math from some very helpful online resources. I was able to create a function inside the fragment shader that lets me render a Menger sponge of desired stage (see images, where the stage is 5). In the future I’d really like to make the Menger sponge infinite, so you would just fly in Menger sponges forever.

Attachment
Attachment
0
robkoo

And for the cherry on top of the up-’n-coming v0.0.1 (pre)release, some actual ray marching shaders. I draw a quad covering the whole viewport and then apply shading in the fragment shader to draw a deformed sphere with simple diffused lighting and curious colors. I spiced it up a bit by passing time to the shader so it glows periodically (based on sin()). In the future I reckon its entirely possible to make the camera movable and light not hardcoded.

PS: For the curious, v0.0.1 update will be out when I add windows compatibility.

Attachment
0
robkoo

Another OpenGL thing that I implemented this devlog is some basic shape rendering. I added nice functions for rendering a triangle and rectangle to the screen. It’s kinda inefficient but I tried to focus on first having something work and then improving it later if necessary. Data is passed to the functions via a structure that contains the position info and the shape’s color.

Attachment
0
robkoo

First of the things required for rendering are shaders, and this devlog/commit I added a simple shader abstraction layer. The file, for now, it exposes a simple CreateShader(..) function which takes in paths to vertex and fragment shaders, and returns a structure which, as of right now, contains just the program ID. I also fixed the odd bug, which was simply caused by not initializing (malloc-ing) some internal variables. It all should work correctly now.

Attachment
0
robkoo

Another core thing to tackle before the fun shader stuff. I added a dedicated logger, which is just a few functions to neatly display logs, and two macros to wrap them for convenience. Curiously, I have encountered a peculiar bug which I can’t seem to find the root of. the LOG(...) macro segfaults if I use it in the main render loop, but nowhere else. In this case, the LOG_RAW(...) macro doesn’t. Also sometimes internal char* buffers for color and label fail (see the screenshot) and I simply have no idea why, as always happens with one specific LOG and no other ones.

Attachment
0
robkoo

In the first hour (and some minutes) of this project I simply set up my repository, which includes, but is not limited to, the directory structure, Makefile, README contents, the GPLv3 license and wrote some window abstraction code. That means, at this point in time, I can open a window. The project currently only runs on GNU/Linux, but in the future, I plan to support Windows operating systems as well.

Attachment
0
robkoo

[!NOTE]
For more info about the changes, please consult the changelog for this update.


Generally, this is a small update whose contents were based on the feedback of my dear girlfriend. It took a while as I tried to not repeat myself, thus I refactored/extracted the line rendering from rosterSelectionScene so I could use it in the lineSwappingScene. I also came across a nasty bug that wiped my forwards from the save, so I tried to mitigate it by changing how the SaveHandler saves players.


Alpha v0.1.3-dev.3

Added

  • Lineup editing via LineSwapScene and shared lineup helpers
  • INFO log level in Logger
  • Shared startup resolution handling in WindowHandler

Changed

  • GameMainMenuScene expanded with CHANGE LINEUP and HELP / HOW TO PLAY menu items
  • MatchPreviewScene and MatchResultScene received UI/layout refresh
  • RosterSelectionScene heavily refactored around shared lineup builders

Fixed

  • Save-load roster integrity
Attachment
Attachment
Attachment
Attachment
Attachment
0
robkoo

For thorough info about the changes, please refer to the version’s changelog entry that can be found right below the version label.


This devlog focuses on the last two commits to the alpha branch. These commits contain additions and changes that will then make up the Alpha v0.1.3 update when it’s ready. I came up with this versioning, for the alpha branch commits (Alpha v0.1.3»-dev.x«) just now, so that’s why there’s two commits in this one devlog. From now on, it will be a single commit per devlog.


Alpha v0.1.3-dev.2

changelog entry

Added

  • a player performance scene which, as of right now, shows your team’s skaters’ career stats (not limited to the current tournament)

Fixed

  • a bug where your game wouldn’t be saved if you clicked BACK TO MAIN MENU in either the winner screen or loser screen

Alpha v0.1.3-dev.1

changelog entry

Added

  • a Modal UI component, which inherits from Rectangle

Changed

  • scene rendering and bounds checking now support component trees (e.g., Modal with internal Rectangle components)
  • scene rendering and bounds checking now flatten all renderable components into an ordered std::vector, then traverse it for rendering/hit checks
Attachment
Attachment
0
robkoo

This devlog only contains the most important of this update. For all the technical details, please refer to the changelog


Overall, this update was meant to improve stability (by fixing some nasty bugs) and increase usability (by adding the helper text).


Alpha v0.1.2

Added

  • resolution switching in Settings (cycling through 4:3 presets)
  • tutorial/helper text for:
    • roster selection
    • training

Changed

  • standardized back button across scenes

Fixed

  • roster clear/load edge cases that could leave stale assignments
  • simulation safety around invalid team lookup and coach dereference paths
  • shooter selection and shot consistency issues in match simulation
  • player runtime/energy edge-case handling
Attachment
Attachment
0
robkoo

Alpha v0.1.1

[!NOTE]
(The full changelog can be found here)


This update is mostly a polish + stability update - same core game loop, but better UI, better save handling, and fewer edge-case crashes/weird states.
Fun fact: because of my UI framework, the actual UI didn’t take that long to implement. I had to come up with the shared UI layer, and the initial UI, but then it was smooth as butter.


Added

  • credits scene with repo link + new credits navigation from main menu/settings
  • save system expanded to 3 slots
  • slot-aware stats persistence (slot1/slot2/slot3) via GameState save token helpers
  • shared UI layer (ui::tokens + ui::prefabs) and richer component interaction states

Changed

  • broad visual/UI improvement across almost all scenes (layout, hierarchy, button patterns, consistency)
  • startup/shutdown flow now respects selected save slot for both saves and stats
  • playoff tab reworked from text list into a visual bracket with connectors and score boxes
  • saves/settings scenes now rebuild on enter to prevent stale state

Fixed

  • playoff progression bugs around direct QF byes / reseeding collisions
  • invalid “next game” detection caused by placeholder matchups
  • scene-transition safety during clicks (deferred callback execution)
  • save safety: empty roster no longer overwrites existing save files
Attachment
0
robkoo

Shipped this project!

Hours: 67.18
Cookies: 🍪 907
Multiplier: 13.5 cookies/hr

I built this game in C++ as a kind of challenge; I am a hardcore C developer and I had to create a C++ game as a school project. I decided to try and make a proper game to understand C++ and I think I did pretty good, but I’m sure there’s tons of C++ paradigms and features I missed out on. I also practiced OpenGL a bit.

robkoo

I updated the makefile, prepared release archives and finished up the release of alpha v0.1

Attachment
0
robkoo

Very early alpha release of the game. Features saving your progress, saving players’ and teams’ statistics (separately from the save file), deterministic game results (if you input the same seed, you get the same result), custom rendering pipeline for text and UI. Game is cross-platform. Your goal, as the coach of the Czech national hockey team, is to win the Olympics. The hockey game rules are following the IIHF rule book, and the Olympics’ groups are based on 2026 Milano-Cortina Winter Olympic games. The full changelog can be found in the repository’s docs/ folder. (Alpha branch)

Attachment
0
robkoo

Very early full release of syedm. Features installing, removing and checking status of symlinks. You can preview changes by passing -n; --dry-run flag which will only print what it would do, instead of making the changes. Project includes a simple CLI argument parser, which distinguishes between short (-n) and long (--dry-run) flags. It also supports grouping flags together (-ni).

Attachment
0