Logging for Recformer

One of my regrets is not actively writing about Recformer1 as I implemented it. I realized this while writing my last blog post, and this post is me trying to rectify that mistake. So, in this post I am going to discuss logging for Recformer. Why Does Recformer Need Logging? Great question! Recformer is part of the work I’m doing for my dissertation. The work I have done up and to this point has shown that the method I created for dynamic difficulty adjustment via procedural level assembly works when tested with agents, but I have not shown that it has any effect when player’s (i.e., actual human beings) interact with it. To address this, I am running several studies with real player’s to see how the system works. And while I will be asking the user to fill out a survey to learn more about the player’s experience, I also want quantitative data (e.g, levels completed, time played, etc.), and this is why Recformer needs logging. ...

March 27, 2025 · 10 min

A* for Recformer

Recformer is a simple platformer. To beat a level, the player has to collect every coin in the level. Recformer is implemented in Typescript. I built it for the web because I am planning to run a player study with it, and it is a lot easier for people to open up a webpage than to install an executable. Another reason I made it is because I wanted to, and because of that, I want the game to be good; at the very least, I want Recformer to be decent. An image I have had in my mind for a while now is a main menu where you can watch an agent that plays the game. This blog post is going to show you how I accomplished exactly that. ...

March 20, 2025 · 14 min

Graph Simplfication for a Faster A*

A* is an algorithm that is so well covered that I won’t be wasting my time to add to the noise in this blog post, but if you are unfamiliar with A*, I recommend reading an introduction from Red Blob Games and then coming back here.1 Alright, assuming you are familiar with A*, the question you may be having is: “How can we make A* faster?” There are, in fact, a lot of ways. If you don’t care about finding an optimal path, you can use an inadmissable heuristic.2 If you wish to reduce resources required, you can cache common path requests. If you have a problem where the path is constantly being recalculated, then you can migrate to D*. If you want every search possible to be less costly to compute while still being optimal, you have to do something different. Specifically, you need to reduce the search space.3 ...

March 1, 2025 · 7 min

Visualizing Hilbert Curves With Raylib

In my most recent post, I showed how to implement Conway’s Game of Life in C++ and visualize it with raylib. This post is of the same kind, except we are going to visualize Hilbert Curves with raylib. However, this post will only have an example of the final result and the code.1 I am of the opinion that that the two sources below are of a high enough quality that I don’t have anything more to add. ...

December 3, 2024 · 3 min

Visualizing Conway's Game of Life with Raylib

Introduction Conway’s Game of Life was created by John Horton Conway. The idea is simple: you have a grid of cells that can either be alive or dead. In every iteration, a new grid is made from the current grid by following a set of rules based on a cell’s neighbors. Since this is a grid, there are 8 possible neighbors when diagonals are included. The rules are the following: Any live cell with less than two neighbors dies. Any live cell with two or three neighbors stays alive. Any live cell with more than three neighbors dies. Any dead cell with three live neighbors becomes a live cell. The rules are simple, but the results can be mesmerizing. However, there are more reasons to care about Conway’s Game of Life than the fact that it is nice to look at. For example, it has been shown that a turing machine can be simulated with it. It is also proof of how seemingly incredibly complex phenomena can appear from straightforward rules. ...

November 26, 2024 · 7 min

Previewing Files with Tkinter

Introduction This is related to an earlier post which was on panning and scaling a node graph visualized with Tkinter. In this post, the goal is to implement a level preview function where when the user hovers over a node they can see the associated file in a rectangle that appears. When they stop hovering over the node, the preview should go away. Additionally, there is a section on writing an update_node function that simplified the codebase. ...

November 25, 2024 · 3 min

Panning and Zooming for a Node Graph Editor with Tkinter

Motivation As part of the work for my dissertation, I am building a tool that allows users to edit a Markov Decision Process (MDP). This relates to my paper, Level Assembly as a Markov Decision Process. This work is different because I am representing the MDP as a graph. Every node in the graph is a state, and a state is a level segment. Every edge represents an action. Levels are formed by connecting states together. I also have some metadata in the edges, which are links between level segments. ...

November 24, 2024 · 8 min

Updating My Site to Hugo

It’s been over two years since I last made a post, and a lot has happened. One of the most minor of these is the change to my website: I’m now using Hugo to build the whole thing. Before Hugo, I was using a home-brewed tool I built in Python. It worked with HTML, but there were re-writable portions marked by {{ FILE_LOCATION }}. The tool would go to that file location and replace the line with whatever it found in that file. I also had a blog post system with a meta file with information like the title and the data of the blog post, and more features. However, it was a pain to work with. ...

November 23, 2024 · 3 min

Q-Learning and SARSA

In this post I’m going to be covering two active reinforcement learning methods: q-learning and SARSA. Both methods do not depend on an MDP. Meaning, we are not guaranteed the presence of P. Instead, we learn which actions can be taken in a state during playthroughs. This is represented by a q-table, which is a table of states and actions that yield a q-value, which represents expected utility when taking an action in a given state. We can say that the expected utility of a state is the best action associated with that state. See the equation below. ...

February 22, 2022 · 4 min

Temporal Difference Learning

This post is on temporal difference learning (TDL). TDL does not rely on a a Markov Decision Process (MDP). Instead, it traditionally uses a table where each state has a row and column so that the table represents the utility of all possible transitions. TDL uses observations to learn which transitions are valid. \[ \begin{align} U^{\pi}(s) \leftarrow U^{\pi} + \alpha (R(s) + \gamma U^{\pi}(s') - U^{\pi}(s)) \end{align} \]This is a very similar to the Bellman equation that we’ve seen in the past posts, but we aren’t using neighbors because temporal difference learning does not assume a model. Instead, an agent plays through the game, and returns a set of states that were taken along the path. So, the utility of a state s is determined by itself plus the reward of that state plus the utility of the state next in the path minus its own utility all multiplied by a learning rate alpha, which is typically a small number between 0 and 1. ...

February 1, 2022 · 3 min