2026

Ebiten Infinicave

2026
Thumbnail of Ebiten Infinicave

I wanted to revisit my blob game concept and see if the new GPT6 Astra model could implement it based on an image, since I had problems doing this with AI in the past. It still took about 4 tries before I achieved something remotely resembling the concept. The result is a Go library for Ebitengine that generates an infinite cave with faceted rocks, branching vines and mushrooms, with an interactive viewer to scroll through the world and carve away terrain.

Wormward

2026
Thumbnail of Wormward

I wanted to try out my Ebiten Infinicave library in a game, so I made Wormward, a real-time cave exploration game where you guide a worm through an infinite destructible cave. Use a bazooka, drill, spider silk and a rope gun to carve paths and swing through the terrain.

2025

Razzie Cloud

2025–2026
Thumbnail of Razzie Cloud

A self-hosted platform for my own apps, with shared database provisioning and passkey authentication. Docker Swarm runs the services and Caddy handles HTTPS and routing.

It started in 2020 with a few apps hosted behind Razvhost: UUID server, Geoip server, Mediaserver, Razbox and Razproxy. Later I started learning Kubernetes and moved my apps to Raz-Stack, deployed via Helmfile and Helm, along with Nextcloud. I also wrote k8s-db-operator to provide databases and Redis namespaces to the services, which became the predecessor to database-broker.

Eventually I wanted a simpler setup and simpler user management, so I created razzie-cloud. The two main services are database-broker and access-gateway: the broker provisions separate PostgreSQL databases and Dragonfly/Redis namespaces for each app, while the gateway handles passkey sign-in, device enrollment and user access. Apps request their database connection strings at startup and receive the signed-in user’s identity through Caddy, so they don’t have to implement their own account management.

Files uses both services: an S3 file manager with optional rclone encryption and public read-only share links. The infrastructure repo contains the Swarm stack, deployment tools and NixOS host configuration.

2024

Mock

2024–2025
Thumbnail of Mock

Mock generates a runtime testify mock implementation for any Go interface without having to write any boilerplate (and in my opinion mockery counts as boilerplate too). It was one of a kind when first implemented, and possibly still is. The initial version used the goplus/reflectx package, but due to the linkname related limitations introduced in Go 1.23, I had to delve deep into the Go internals (ABI, GC, reflection) to be able to develop a standalone version. The only dependency is the testify package itself.

2023

0x40 Hues

2023
Thumbnail of 0x40 Hues

I’ve come across Kepstin’s amazing 0x40hues project and caught myself listening to it a lot. After finding community resource packs to try, it quickly became troublesome to configure and run them. This motivated me to fork the project and after a great deal of refactoring, it now supports loading many respacks and on-the-fly configuration.

Botkit

2023–2024
Thumbnail of Botkit

A Telegram bot library designed to handle commands and dialogs. Both of these support replying with sticker, photo, video, audio, album or file (even files not directly uploaded by the bot). Dialogs are composed of one or more queries, which can be single choice, multi choice or file queries. In theory you could run multiple instances to help balance the load, as long as they share the same Redis database.

Broadcaster

2023–2024
Thumbnail of Broadcaster

Broadcast messages from one channel to many, with timeouts, server sent events and much more. Zero external dependencies. Designed for scenarios when it’s unpractical to connect to the same event source using many parallel connections.

Commander

2023–2024
Thumbnail of Commander

Execute Go functions from CLI or from a chatbot. Register any function as a command, then supply a context variable and a string slice as input arguments. If the original function has Context parameter(s), the context variable will be passed, otherwise the arguments from the string slice will be converted using Sscanf. The function’s return values are converted into a []any slice and if any of these values is an error, it will be extracted into a separate error return value.

Json2Go

2023–2024
Thumbnail of Json2Go

A webapp that helps you write Go client libraries for JSON web APIs. One of my experiments required building a database that included data from many third party JSON web APIs. The process of deserializing data into manually crafted Go structs quickly got exhausting, so I had to come up with a solution. Json2Go is by no means perfect (it only looks at the fields of the first item of a JSON array), but it gets the job done. You can input a JSON or a URL that returns a JSON. Field names are automatically converted into camel case, stripped of unsupported characters and correctly annotated with the original name. The resulting generated structure is formatted and uses syntax highlighting.

RazCache

2023–2024
Thumbnail of RazCache

A minimalist abstraction layer above Redis, Badger and a custom in-memory cache. As many of my self-hosted services rely on Redis for caching or data storage, I often had to fire up a local instance for manual testing. This process was too cumbersone for me, so I figured I could come up with a wrapper around Redis supporting the functionaly only I use the most, and during development it should mimic this functionality in-process. Supporting key expirations was a mandatory requirement, so the in-memory cache implements a “janitor” goroutine that cleans up these keys exactly when they expire, one at a time.

2022

k8s-db-operator

2022–2023
Thumbnail of k8s-db-operator

Kubernetes operator to provide access to shared PostgreSQL and Redis. It relies on the DatabaseClaim CRD, but unlike most other operators, this one only deploys Kubernetes secrets containing connection strings. Databases and Redis namespaces are not shared between dbclaims.

RazChess

2022–2023
Thumbnail of RazChess

I’ve had a sudden spark of interest in chess as of late 2022 and decided to build my own web chess app with focus on simplicity and ease of use. Also I didn’t want to waste time convincing friends to register to [insert your favorite chess platform here]. With RazChess you just visit the website, copy the link of the session and pass it to the person you want to play with. As weeks passed I kept adding new features like chess puzzles (mate in two steps), Fischer random (chess960) game, included chess openings encyclopedia, custom games and the ability to download your matches as GIFs. There is also Redis support to restore active games after a restart.

2021

Telegram PizzaBot

2021
Thumbnail of Telegram PizzaBot

Do you love pizza so much that you keep talking about it in your Telegram group chat? Now you can include this bot and with the right permissions it will respond with a pizza sticker or interesting pizza fact to any mentions of pizza.

2020

Beepboop

2020–2022
Thumbnail of Beepboop

A lightweight webapp framework that powers Razbox. Most of the original code was taken from Razlink, but it has heavily evolved since. The core mechanic consists of registering pages (which are mostly a template + handler bundle) and returning view objects from inside the handlers. There are some utilities for session handling, access management and logging too, but this library is not suitable for production use.

Geoip server

2020
Thumbnail of Geoip server

A web service that serves IP address geolocations in JSON format. Instead of relying on a local database it collects data from a (configurable) series of 3rd party providers, converting the results to a commom format. It supports provider fallbacks and caching.

Mediaserver

2020
Thumbnail of Mediaserver

A web service that fetches thumbnails with title from URLs. Originally planned to use it in a chat service to prevent the tracking of users by letting them download images directly.

Razbox

2020–2021
Thumbnail of Razbox

Super simple cloud file storage with almost zero configuration - powered by Beepboop Razbox stores all configuration and metadata in JSON files on the local filesystem and doesn’t rely on a relational database (though it has opt-in support for Redis caching). Each folder can contain a .razbox file (which can be generated by included tools) and the content is ready to be served. Read and write access to these folders can rely on separate passwords, so you can share read access only if you want. Subfolders are also supported and they inherit the read/write passwords, unless a .razbox file is generated for them. Uploaded files can have an arbitrary number of tags that allow filtering. Thumbnails are generated for media files (using ffmpeg for videos!), which are visible in gallery view. Some archive formats are also supported for read-only browsing. Individual files can be shared publicly, this making them readable without any password.

Razproxy

2020
Thumbnail of Razproxy

SOCKS5 tunneled through TLS connection. The project consists of a custom server and client, which enable encrypted traffic between them. The client opens a SOCKS5 port locally which can be used by multiple applications (like web browsers) running in parallel.

Razvhost

2020–2022
Thumbnail of Razvhost

Virtual hosting/reverse proxy with TLS termination and automatic certificate management. It supports proxying, file/directory serving, redirection, accessing SFTP or S3 buckets, hosting PHP projects or even tailing log files. The configuration is loaded from a single file that contains simple hostname -> target rules, where even templates are supported (check readme in repo). Changes to the config files are detected and applied during runtime. It can even watch Docker containers with VIRTUAL_HOST and VIRTUAL_PORT environment variables and direct traffic to them (though it would’ve been better to check labels instead, but it didn’t cross my mind at the time).

S3proxy

2020
Thumbnail of S3proxy

A super simple S3 proxy server that obfuscates file content before transmitting the request to the target. Obfuscation is done via a lookup table which is generated from a user provided key. Only signature v2 authentication is supported.

UUID server

2020
Thumbnail of UUID server

A http server that serves random (version4) UUIDs. It uses my hybrid pseudo- and true random generator library which periodically takes seeds from random.org and uses them to generate pseudo-random UUIDs fast.

2019

RazTracer

2019
Thumbnail of RazTracer

Command line debug information explorer and function call tracer for Linux, based on the Ptrace API. I was in the process of implementing a GUI for the project (borrowing elements from Riddle Solver), but lost interest in continuing the development.

Riddle Solver

2019–2021
Thumbnail of Riddle Solver

Riddle Solver is a terminal app designed to solve Einstein’s 5 house riddle (also called zebra puzzles in general). I think I came across this kind of riddle playing Dishonored 2 first, as a third option to get inside a locked place. It was written by a fictional genius game character named Kirin Jindosh and it’s clearly based on Einstein’s five house riddle. It took me (sadly) at least 30 minutes to solve on paper, but it earned me an achievement. Fast forward 3 years, I had the random idea of implementing this riddle solver, which seemed like a simple way to sharpen my Golang skills. I was wrong. Coming up with the UI design and the solver algorithm caused me some sleepness nights, but I’m really proud of the result.

2015

Personal website

2015–2024
Thumbnail of Personal website
  • 2024 version

    Completely rewritten everything again using Go + PicoCSS + HTMX stack, featuring static site building with Github Actions. It supports light and dark themes (based on user preferences reported by the browser) and uses HTMX boosted page loads and loading spinner. Content is stored in a main content.yaml and individual project yaml files, everything else is in HTML templates.

  • 2019 version

    Everything completely rewritten in Go. Data was still stored in XML files initially, but later all the content (including resume) was moved to a single yaml file, which was periodically updated directly from the repository.

  • 2018 version

    Implemented in C# using NancyFX and a brand new design. It used Github API to list my latest open-source interests and contributions. Project data was stored in XML.

  • 2015 version

    The site made use of user friendly URLs (thanks to Apache web server’s mod_rewrite) and loaded pages dynamically via jQuery’s AJAX API. A server side PHP script automatically parsed the static HTML pages for sections, which could then be accessed individually by the user. It wasn’t very CPU friendly, but made it easy for me to add new content to the page without using a database. Later my Twitter feed was integrated as a news feed, using OAuth and Twitter’s API.

×