Compare commits

..

18 commits

Author SHA1 Message Date
Benjamin Palko
1b4b4c9982 explicitly define args 2026-08-12 08:05:20 -04:00
Benjamin Palko
462cd5483a check for undefined
Some checks failed
PR Gate / Checks (pull_request) Failing after 39s
2026-08-11 20:46:35 -04:00
Benjamin Palko
37d44b6216 fix env error
Some checks failed
PR Gate / Checks (pull_request) Failing after 36s
2026-08-11 17:45:36 -04:00
Benjamin Palko
40838e3f1e ignore pnpm-store
Some checks failed
PR Gate / Checks (pull_request) Failing after 37s
2026-08-11 17:43:38 -04:00
Benjamin Palko
cac710880e ignore workflows and opencode
Some checks failed
PR Gate / Checks (pull_request) Failing after 45s
2026-08-11 17:40:09 -04:00
Benjamin Palko
b64e830acd update typescript 2026-08-11 17:39:21 -04:00
Benjamin Palko
4f8e6ba55f update remaining packages
Some checks failed
PR Gate / Checks (pull_request) Failing after 46s
2026-08-11 17:31:39 -04:00
Benjamin Palko
0e0bff902b remove humanspeak 2026-08-11 17:25:01 -04:00
Benjamin Palko
ae83ed48fd lol
Some checks failed
PR Gate / Checks (pull_request) Failing after 48s
2026-08-11 17:21:25 -04:00
Benjamin Palko
58f89f8915 update svelte packages 2026-08-11 17:19:56 -04:00
Benjamin Palko
060f413336 update eslint and prettier 2026-08-11 17:12:52 -04:00
Benjamin Palko
73fdec95ef freeze lockfile
Some checks failed
PR Gate / Checks (pull_request) Failing after 46s
2026-08-11 17:08:23 -04:00
Benjamin Palko
a61d95cba3 fix eslint errors
Some checks failed
PR Gate / Checks (pull_request) Failing after 34s
2026-08-11 16:49:31 -04:00
Benjamin Palko
885f3f6a74 eslint ignore .opencode
Some checks failed
PR Gate / Checks (pull_request) Failing after 38s
2026-08-11 16:34:12 -04:00
Benjamin Palko
a6d4064af8 format project 2026-08-11 16:25:07 -04:00
Benjamin Palko
7651afaa0b fix prettier config ordering 2026-08-11 16:25:02 -04:00
Benjamin Palko
897b10d229 fix action version
Some checks failed
PR Gate / Checks (pull_request) Failing after 45s
2026-08-11 16:17:00 -04:00
Benjamin Palko
00006a013d set up new workflow and migrate to .forgejo dir
Some checks failed
PR Gate / Checks (pull_request) Failing after 17s
2026-08-11 15:57:25 -04:00
4 changed files with 145 additions and 2 deletions

View file

@ -21,7 +21,7 @@ jobs:
- name: Build - name: Build
run: pnpm build run: pnpm build
- name: Deploy to Netlify - name: Deploy to Netlify
run: pnpm dlx --package=netlify-cli@27 netlify deploy --prod --dir=build --auth "$NETLIFY_AUTH_TOKEN" --site "$NETLIFY_SITE_ID" run: pnx netlify-cli deploy --prod --dir=build --auth $NETLIFY_AUTH_TOKEN --site $NETLIFY_SITE_ID
env: env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

View file

@ -0,0 +1,83 @@
---
layout: blog
title: Godot .NET with SpacetimeDB
description: First post.
image:
url: https://spacetimedb.com/meta-tags.png
alt: SpacetimeDB
date: '2026-1-22'
categories:
- development
published: false
---
I've been on and off again experimenting with Godot since the great Unity [controversy of 2023.](https://www.geekwire.com/2023/heres-why-so-many-video-game-developers-are-suddenly-abandoning-the-unity-engine/) At the time Godot came up pretty quickly as the open-source alternative, I'll spare you the history lesson we are here to talk SpacetimeDB! If you found this article I assume you already know what SpacetimeDB is.
# Setting up our workspace
Before we get into any programming we are going to do some setup on our project workspace to help things along, we will be thankful for this later! I'm going to be painfully explicit in the details here so bare with me.
## Create a project directory
We are going to sidestep creating the root project directory with Godot, this will become apparent as to why later but for now just trust me! 😉
```bash
mkdir massive
```
## Init Git
```bash
git init
```
## Set tool version with mise
We are going to use [mise-en-place](https://mise.jdx.dev/) to handle our tool versions at the project level, this is a great tool that I now use by default for any new project Im working on. It allows us to keep our tool versions independent of our global settings.
```bash
mise use dotnet@8 bun@latest
```
> This will generate a `mise.toml` file in our project root.
The first tool is obvious, we are writing in C# so of course we need dotnet! Using bun however, let me explain.
## Create a new Godot project
## Create docker-compose
```yaml
services:
spacetime:
image: clockworklabs/spacetime
ports:
- 3000:3000
command: start
```
## Create package.json
```json
{
"name": "massive",
"scripts": {
"database:up": "docker compose up -d",
"database:down": "docker compose down",
"database:publish": "spacetime publish --project-path server massive",
"database:generate": "spacetime generate --lang csharp --out-dir client/module_bindings --project-path server"
},
"devDependencies": {
"@types/bun": "latest"
}
}
```
## .editorconfig
```editorconfig
root = true
[*]
charset = utf-8
```

View file

@ -0,0 +1,60 @@
---
title: The Art of Simple Design
description: Functional Decomposition as a Method of handling Contextual Shifts during project development
image:
url: https://images.unsplash.com/photo-1766811474703-6e86727d7f95?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D
alt: This is an image
date: '2026-1-22'
categories:
- development
published: false
---
Project degradation as a result of contextual shifts during development is a common occurrence, contextual shifts are a natural part of the project development process, and we should always try to account for them in our design and as we develop. Some design frameworks like IDesign seek to solve this through functional decomposition, by reducing a project to a set of functional interactions, i.e a data access calls, business logic, orchestration, etc... This is certainly the correct path, but in the process of trying to develop a perfect solution, often falls into the pit of overdesign with strict naming conventions and complicated architecture. This actively becomes a hindrance to development cadence, the problem we were seeking to fix.
A strong design methodology should not be a strict instruction manual, but an informative pamphlet. It should impart a new perspective on the same problems we have seen a million times, and give new tools to use.
```typescript
interface User {
id: string;
name: string;
email: string;
hashed_password: string;
}
interface IUserAccessor {
findUser(user_id: string): Promise<User>;
createUser(user: User): Promise<User>;
updateUser(user: User): Promise<User>;
deleteUser(user_id: string): Promise<boolean>;
}
```
```typescript
import { Client } from 'pg';
class PostgresUserAccessor implements IUserAccessor {
private readonly Client _client;
constructor PostgresUserAccessor() {
_client = new Client();
}
async findUser(id: string): Promise<User> {
await _client.connect()
const res = await client.query("SELECT * FROM users WHERE users.id = '$1::text'", [id]);
await _client.end()
return res.rows[0];
}
```
Over the years, between the projects I have worked on, I started to notice that teams tended to gravitate towards one side of a spectrum.
On one side you have the people who don't follow design patterns, this is the wild west and anything goes, maybe they don't know what patterns to use or even care that they exist? Their architecture is based on vibes, or what has come before, it tends to be disorganized and inconsistent.
On the other side of the spectrum are the people who are design pattern evangelists, they have either seen these projects and understand the importance of design, or are from a theoretical/academic background. They know their pattern(s) well, but perhaps are too vigorous in their application, this can result in an over-designed mess. What this looks like
They try so hard to strictly adhere to a chosen design pattern, but either out of misunderstanding or overcommitment, their code becomes rigid and unnatural. Think of it like this, Bridges are a great structure for traversing difficult terrain, but they have their uses. If I was trying to travel upstream on a winding river, I would not build a bridge straight up the river, when completed it may be the fastest option but it would certainly not be cheap or sensible, a boat would be a better option. Now if the context changes and I am trying to traverse from one side of this river to the other? A boat still works, but now the bridge is making a lot more sense! My point is, if all you know is bridge design then everything starts to look like a bridge problem, or... something something hammer and nails.
Perhaps this leads into another topic about overspecialization and the benefits of generalization in a specialized world. The greatest tools you can have on your belt are new perspectives!

View file

@ -17,7 +17,7 @@ export async function sendContactMessage(name: string, email: string, message: s
form.append('content', content); form.append('content', content);
if (!env.DISCORD_CONTACT_WEBHOOK) { if (!env.DISCORD_CONTACT_WEBHOOK) {
throw new Error('Undefined discord webhook'); return;
} }
const url = new URL(env.DISCORD_CONTACT_WEBHOOK); const url = new URL(env.DISCORD_CONTACT_WEBHOOK);