Sign in

Sam Abbott-Kennedy

@samothyk.bsky.social
88 followers 277 following 84 posts

[onlookers booing]

PostsRepliesMedia
Sam Abbott-Kennedy @samothyk.bsky.social · 05/09/2026
Work on the ternary fantasy emulator continues. I have a wave channel working like a Gameboy, except it natively supports negative values and has a resolution of 3 trits (27 values) Vs the gb's 4 bits (16 values). Still crunchy but more sonorous than a gameboy
010
Sam Abbott-Kennedy @samothyk.bsky.social · 31/08/2026
Finally working on the ternary fantasy console again and I have audio working. Currently got one channel working with 8 trit period, meaning it can accurately represent a full 8 octaves. Manually changing the pitch by writing to the audio registers with the keyboard for now. #fantasyconsole #ternary
020
Sam Abbott-Kennedy @samothyk.bsky.social · 16/08/2026
Ternary assembly (tasm) is now mature enough to make a ROM to move a square around the screen! #ternary #fantasyconsole
010
Sam Abbott-Kennedy @samothyk.bsky.social · 15/08/2026
Work on an assembler for the ternary bytecode (or I guess, trytecode) has begun, it's so much easier to write programs for the ternary emulator now 😅 Which program is easier to read? 😛 #ternary #assembly
An assembly program that reads:
```
.loop:
    inc a
    jr ceq, .loop
    halt
```The assembled program ROM in balanced heptavigesimal, it reads 
```
RS QQ 0P TT
```
000
Sam Abbott-Kennedy @samothyk.bsky.social · 14/08/2026
IO register is now working, and can be queried trit-by-trit to move a sprite across the screen! No VBLANK yet so there's just a delay of 100 cycles between each update 😅 #ternary #fantasyconsole #emulator
000
Sam Abbott-Kennedy @samothyk.bsky.social · 13/08/2026
Still loads of room left but the optable for the ternary CPU is filling out nicely! you can do lots of things with just arithmetic, jumps, loads, and tritwise operations. Heavily influenced by the gameboy optable of course gbdev.io/gb-opcodes/o... #ternary #fantasyconsole #emulator
100
Sam Abbott-Kennedy @samothyk.bsky.social · 13/08/2026
Adding input to my ternary console emulator, what's neat is a single trit can represent a whole axis, -1 for left/down, 0 for released, and +1 for right/up. The other buttons are disappointingly binary, however #ternary #emulator #fantasyconsole
A screenshot of my input code for my fantasy ternary console, reading the io register and writing individual trits depending on input.
010
Sam Abbott-Kennedy @samothyk.bsky.social · 04/08/2026
I've gotten to the point where my ternary CPU is good enough that writing roms for it by hand is getting cumbersome. So logically I need to invent an assembly language for it. I have managed to write the rom for a single sprite moving though 🎉 #fantasyconsole #ternary #odinlang
010
Sam Abbott-Kennedy @samothyk.bsky.social · 03/08/2026
I switched the ternary emulator's tilemap to 3 trits per pixel. Now figuring out how to draw tiles with code is much easier. Also this means they can have a colour depth of 27 colours! All with space for more tiles in VRAM than a Gameboy #fantasyconsole #ternary #emulator
A screenshot of my ternary based emulator showing "HELLO WORLD" in the top center along with the base-27 rom code in the backgroundAnother shot of my ternary emulator showing all 27 colours it can represent
000
Sam Abbott-Kennedy @samothyk.bsky.social · 02/08/2026
Most insane project yet, a ternary CPU based emulator for a console that never existed. I have the CPU and PPU working well enough to transfer tiles to the screen, but working out the ternary encoding of each tile by hand is melting my brain 😅 #fantasyconsole #ternary #odinlang
110
Sam Abbott-Kennedy @samothyk.bsky.social · 23/07/2026
Dabbling in #odinlang once again, I forgot how nice of a language it is. No llm no Google just the docs on one screen and the text editor on the other like god intended
010
Sam Abbott-Kennedy @samothyk.bsky.social · 18/07/2026
Continuing OSR-posting, this is the class I'm happiest with (it's also the most complete class besides the Warrior). The Devout covers the cleric/paladin archetypes with a unique casting mechanic that I should really test. Favour rolls feel a bit jank and maths heavy but I like what they're doing
100
Sam Abbott-Kennedy @samothyk.bsky.social · 17/07/2026
In my everlasting quest to start new projects I'm trying to design a sort of OSR TTRPG. I'm having fun with the spells section, can you guess which games are inspiring me? #OSR #TTRPG
231
Sam Abbott-Kennedy @samothyk.bsky.social · 08/05/2026
The Firered romhack with only gen 5 pokemon is still going. The increased level curve and power creep is really refreshing. Also figured out how to change the overworld pokemon sprites! #pokemon #romhack
010
Sam Abbott-Kennedy @samothyk.bsky.social · 06/04/2026
Working on something completely different, what if the unova dex was the OG 151 #pokemon #romhack #frlg
120
Sam Abbott-Kennedy @samothyk.bsky.social · 20/03/2026
Spent a few days playing with the game of life program, fixed a lot of bugs in the language doing so. I should make more projects like this to stress test the language, any ideas for what else I should try coding? #compiler #programming #raylib
060
Sam Abbott-Kennedy @samothyk.bsky.social · 18/03/2026
Managed to build a cheeky little game of life simulator in my programming language! #programming #compiler #raylib
140
Sam Abbott-Kennedy @samothyk.bsky.social · 17/03/2026
Anonymous structs have blown open a whole new slew of features. Multiple return values and tuples basically for free #compiler #programming
A snippet of my programming language showing anonymous structs, multiple return values, and tuples
```
fn multiple_returns(): struct { u32, u32 } {
    return { 6, 7 }
}

//accept as anonymous struct
fn foo(struct { a: u32, b: u32}) {
    println(a)
    println(b)
}

//accept as tuple
fn bar(tup: struct { u32, u32 }) {
    println(tup.0)
    println(tup.1)
}

fn main(): u32 {
    let x = multiple_returns()
    foo(x)
    bar(x)

    return 0
}
```
031
Sam Abbott-Kennedy @samothyk.bsky.social · 17/03/2026
Been noodling on how my language will handle anonymous structs. They're not done yet but I think they'll be pretty loose, able to coerce between compatible named structs. Plus they'll basically act like tuples once you can create anonymous struct literals, which is nice! #programming #compiler
A snippet of code in my programming language showing coercion between a named struct and an unnamed struct, as well as promotion of an anonymous struct's fields to the containing struct:
```
struct Foo {
    { a: u32, b: u32 }
}

struct Pair { a: u32, b: u32 }

fn foo({a: u32, b: u32}, c: u32) {
    println(a, b, c)
}

fn main(): u32 {
    let pair = Pair { 1, 2 }
    foo(pair, 3) //named struct coerced to anonymous struct

    let f = Foo { pair }

    println(f.a)
    println(f.b)

    return 0
}
```The output:
```
1, 2, 3
1
2
```
010
Sam Abbott-Kennedy @samothyk.bsky.social · 15/03/2026
Gave in and added function receivers, and I think they look pretty swanky. Just means that &self is automagically converted into a parameter `self: &Vec`
A snippet in my language showing method receivers on a struct `CPU`:
```
struct CPU {
    clock: u64 = 0,
    //registers
    AF: u16 = 0x01b0,
    BC: u16 = 0x0013,
    DE: u16 = 0x00D8,
    HL: u16 = 0x014D,
    SP: u16 = 0xfffe, //Stack pointer
    PC: u16 = 0x0100, //Program counter
}

fn CPU.execute(&self, opcode: u8) {
    switch (opcode) {
        0x00 => println("NOP"),
        0x01 => println("Load N16"),
        // etc for the other 0xFD opcodes...
        _ => println("unknown"),
    }
}
```
010
Sam Abbott-Kennedy @samothyk.bsky.social · 15/03/2026
Getting to the point where I can write semi-serious programs in my language. It's a great way to find a bunch of subtle bugs and missing functionality. E.g. here's a ~totally functioning~ gameboy emulator #programming #compiler #raylib
Two files in my language showing a barebones gameboy CPU and raylib draw loop with the gameboy window running, showing a blank screen
170
Sam Abbott-Kennedy @samothyk.bsky.social · 14/03/2026
Had to implement some name mangling when emitting functions to lay the groundwork for interfaces, and I noticed this gave me function overloads for free. Take that, C! #compiler #programming
A program in my language showing function overloads:
```
struct Vec2 { x: u32, y: u32 }
struct Vec3 { x: u32, y: u32, z: u32 }

fn add(a: Vec2, b: Vec2): Vec2 {
    return Vec2 { a.x + b.x, a.y + b.y }
}

fn add(a: Vec3, b: Vec3): Vec3 {
    return Vec3 { a.x + b.x, a.y + b.y, a.z + b.z }
}

fn main(): u32 {
    let v2a = Vec2 { 3, 2 }
    let v2b = Vec2 { 4, 3 }
    let v2c = add(v2a, v2b)
    println(v2c)

    let v3a = Vec3 { 3, 2, 1 }
    let v3b = Vec3 { 2, 1, 1 }
    let v3c: Vec3 = add(v3a, v3b)
    println(v3c)

    return 0
}
```The output of the program:
```
{ 7, 5 }
{ 5, 3, 2 }
```
010
Sam Abbott-Kennedy @samothyk.bsky.social · 12/03/2026
It's all coming together. Now I have unions I can implement the optional type ?T which is just a tagged union. In addition I could implement rust style try-unwrap of optionals basically for free with all the parts I have! Here opt_return only prints x if it's some, else it returns early! #compiler
A snippet of my programming language showing optionals and early returns on optionals:
```
fn maybe(b: bool): ?u32 {
    if (b) return 10
    return none
}

fn opt_return(b: bool): ?u32 {
    let x = maybe(b)
    println(x?) //if x is none, return here, else print the value of x (10)
    println("x was some!")
    return x
}

fn main(): u32 {
    let x = opt_return(true)

    if (x) |value| {
        println(value + 10)
    } else println("x was none")

    let y = opt_return(false)
    if (y) |value| {
        println(value + 10)
    } else println("y was none")

    return 0
}
```The output of the program:
```
10
x was some!
20
y was none
```
030
Sam Abbott-Kennedy @samothyk.bsky.social · 11/03/2026
Now with the fancy struct syntax, implementing tagged unions was relatively easy. Also got rid of all those pesky semicolons messing up the place #compiler
010
Sam Abbott-Kennedy @samothyk.bsky.social · 10/03/2026
Blew apart my struct and function parsing to allow default values and named arguments. Pretty swanky imo #compiler
010
Sam Abbott-Kennedy @samothyk.bsky.social · 09/03/2026
Not sure it's the greatest use of it but the new `with` statement works nicely with raylib 😅 #raylib #compiler
110
Sam Abbott-Kennedy @samothyk.bsky.social · 09/03/2026
Added a defer statement to my language, but I didn't like how the resource acquisition and disposal had to be separated. So I added a with statement that just desugars to defer, and I kinda like it! #compiler
A snippet of my programming language showing the defer statement:
```
fn main() {
    let f = os::open_file("test.txt");
    defer os::close(f);
    
    for _ in 0..15 {
        os::write(f, "Hello once again from osmium!\n");
    }
}
```A snippet from my programming language showing the same code but using a `with` statement:
```
fn main() {
    with let f = os::open_file("test.txt"); { println("closing file!"); os::close(f); } {
        for _ in 0..15 {
            os::write(f, "Hello once again from osmium!\n");
        }
        println("done writing!");
    }
    println("end of main!");
}
```The output of the with statement variant showing the order in which things are run:
```
done writing!
closing file!
end of main!
```
030
Sam Abbott-Kennedy @samothyk.bsky.social · 08/03/2026
Starting on the memory management for my language. Nothing fancy but just a few more guard rails than C. Every pointer has an "origin": Stack, Param, Heap, or Global. Only Heap can be freed, and Stack can't be returned from functions. Maybe this will cause problems but we'll see! #compiler #llvm
A program in my programming language showing pointer allocation and illegal freeing:
```
fn bad(ptr: &u32) {
    free ptr;
}

fn main() {
    let x = new u32;
    free x;

    let i = 10;
    let p = &i;
    free p;
}
```The error messages from compiling the program:
```
Error: Cannot free a pointer with lifetime `Param` at src\main\resources\examples\memory.os:2:5
2 |     free ptr;
  |     ^^^^^^^^^
Error: Cannot free a pointer with lifetime `Stack` at src\main\resources\examples\memory.os:11:5
11 |     free p;
   |     ^^^^^^^
```
110
Sam Abbott-Kennedy @samothyk.bsky.social · 04/03/2026
Osmium Raylib ffi speedrun #compiler #llvm #raylib
020
Sam Abbott-Kennedy @samothyk.bsky.social · 04/03/2026
Decided the next logical step from modules was ffi, surprisingly straightforward to implement! Now I can tuck all that nasty ffi code in a libc.os or something #compiler
A program in my programming language showing FFI:
```
extern fn exit(status: u32);
extern struct FILE();

extern fn fopen(filename: &const char, mode: &const char): &FILE;
extern fn fputs(s: &const char, file: &FILE): u32;
extern fn fclose(file: &FILE);

fn main() {
    let file = fopen("test.txt".data, "w".data);
    if file == null {
        println("Could not open file!");
        exit(1);
    }

    for _ in 0..10 {
        fputs("Hello from osmium!\n".data, file);
    }
    fclose(file);
}
```The output in a new file `test.txt`
```
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
Hello from osmium!
```
110
Sam Abbott-Kennedy @samothyk.bsky.social · 04/03/2026
I managed to implement a somewhat halfway decent module system. I'm not thrilled that the import needs the relative path but it'll do for now. Plus it handles the same file being imported multiple times across the compilation graph 😌 #compiler #llvm
A picture of 3 separate files in my programming language that form a dependency chain. main.os imports io.os and math.os, math.os imports io.os.
main.os:
```
import "math.os";
import "io.os";

fn main() {
    io::print_msg("Hello from main.os!");
    var v = math::Vec(1.0, 2.0);
    println(math::dot(v, v));
    var x = math::pow(2.0, 3);

    println(x);

    math::greet();
}
```
math.os:
```
import "io.os";

struct Vec(x: f32, y: f32) {
    fn dot(v1: Vec, v2: Vec): f32 {
        return v1.x * v2.x + v1.y * v2.y;
    }
}

fn pow(x: f32, p: u32): f32 {
    for _ in 1..p x = x * x;
    return x;
}

fn greet() {
    io::print_msg("Hello from math.os!");
}
```
io.os:
```
fn print_msg(msg: string) {
    println(msg);
}
```The output of the program:
```
Hello from main.os!
5.000000
16.000000
Hello from math.os!
```
120
Sam Abbott-Kennedy @samothyk.bsky.social · 01/03/2026
Added strings to my language, since they're just backed by a slice of u8's all the regular slice operations just worked out of the box Again nothing real languages don't do but it's so satisfying seeing it work! #compiler #llvm
A program in my programming language showing string slicing:
```
fn main() {
    var s: string = "Hello from osmium!";
    println(s);
    println(s[6..=10]);

    var sl = s[8..17];
    println(sl);

    for c in s[0..5] {
        print(c);
        print(' ');
    }
}
```The output of the program:
```
Hello from osmium!
from 
om osmium
H e l l o 
```
040
Sam Abbott-Kennedy @samothyk.bsky.social · 28/02/2026
One huge rewrite later and a brand new backend (LLVM) and I'm extremely happy with my programming language's slices. Nothing fancy that any other real language doesn't do but it's fun seeing my scrappy little compiler go. #compiler
A program in my programming language showing array slicing:
```
fn print_slice(sl: []u32) {
    for i in sl print(i);
}

fn main() {
    var a = [*]u32 { 4, 5, 6, 7 };
    print_slice(&a);

    var sl: []u32 = a[2..=3];
    print_slice(sl);
    print(sl); //prints the raw underlying struct { ptr, len }

    sl[0] = 1; //mutate the original array through the slice, makes sense since []T == &[N]T
    for x in a print(x);
}
```The output of running the program:
```
4
5
6
7
6
7
{ &[0x61dff2e8], 2 }
4
5
1
7
```
110
Sam Abbott-Kennedy @samothyk.bsky.social · 11/02/2026
Taking structs to weird new places (java records) #compiler #development
010
Sam Abbott-Kennedy @samothyk.bsky.social · 10/02/2026
Trying to decide if I want the easier to parse, trendy variable: Type syntax, or the (imo) nicer but harder to parse Type variable syntax. Mainly I'm just trying to bikeshed so I don't have to think about implementing a module system 😔 #compiler
A snippet of my programming language of a recursive descent parser with rust style syntax.A snippet of my programming language of a recursive descent parser with C style syntax.
100
Sam Abbott-Kennedy @samothyk.bsky.social · 06/02/2026
Writing a compiler, so far the language looks pretty cozy but every new feature I add pulls it closer to either zig or rust 😩
A screenshot of code in my language showing a recursive descent parser
020
Sam Abbott-Kennedy @samothyk.bsky.social · 03/08/2025
Brewing again, this time a sort of west coast IPA to use up some Pacific Sunrise hops I got for cheap. A bit lower OG than I wanted but still a respectable 1.054. The Kveik has already munched that down to 1.020 so today is dry hop day apparently 🍻
020
Sam Abbott-Kennedy @samothyk.bsky.social · 25/04/2025
Berry sour is underway, 62/30/8 pils/wheat/oats. About 8 IBU of saaz with a late addition of mosaic and some frozen blackberries I had in my freezer OG was bang on target at 1.042, and pitched 1pk Philly Sour at 23C Once it slows down I'll be adding more frozen berries 🍻 #homebrewing #beer
140
Sam Abbott-Kennedy @samothyk.bsky.social · 23/04/2025
The sun finally came out after days of rain so I had to take some screenshots of my new oblivion remastered character
040
Sam Abbott-Kennedy @samothyk.bsky.social · 12/04/2025
Strawberry wheat beer bubbling away, the saison yeast chewed through the base beer in 3 days so the strawberry puree has now gone in. Lovely colour but hopefully it clears up before bottling 🍻 #homebrew #beer
110
Sam Abbott-Kennedy @samothyk.bsky.social · 05/04/2025
Made what started as a pseudo wheat beer/hitachino clone that sort of became its own thing. Smells great but basically tastes like nothing. I think I should've used more coriander and orange to offset how little hops I used Lesson learnt, next onto a strawberry wheat beer 🍻 #beer #homebrew
000
Sam Abbott-Kennedy @samothyk.bsky.social · 07/03/2025
Making a saison just in time for spring #homebrewing Adjusted some things to account for my terrible efficiency and hit all my numbers 💪
221
Sam Abbott-Kennedy @samothyk.bsky.social · 24/01/2025
Messing about with #raylib and #c3
120
Sam Abbott-Kennedy @samothyk.bsky.social · 23/01/2025
Fuck offfff
010
Sam Abbott-Kennedy @samothyk.bsky.social · 28/10/2024
"don't talk to me or my son ever again" 🍄📷
A mushroom with a much smaller mushroom beside it
11398
Reposted by Sam Abbott-Kennedy
Тsфdiиg @tsoding.bsky.social · 20/10/2024
Some of my old banger from Xitter - The Creator of C++
2602
Sam Abbott-Kennedy @samothyk.bsky.social · 18/10/2024
Some more mushrooms from various walks 🍄📷
0381
Sam Abbott-Kennedy @samothyk.bsky.social · 16/10/2023
A few fairytale lads from my walks 🍄📷 Not quite sure what the big round boy is
1201