summaryrefslogtreecommitdiff
path: root/old_stuff/src/content/blogs
diff options
context:
space:
mode:
authorKyren223 <contact@kyren.codes>2026-10-06 20:46:31 +0300
committerKyren223 <contact@kyren.codes>2026-10-06 20:46:31 +0300
commitba1be9573ef20d6424ae987257a1c727c47d4b53 (patch)
treee59ef56f19142215070d0516a9b3a110d15557b6 /old_stuff/src/content/blogs
parentea056b6e080669ba4b6f16c2757b4e2e88ea0553 (diff)
Initial setup for website rewrite
Diffstat (limited to 'old_stuff/src/content/blogs')
-rw-r--r--old_stuff/src/content/blogs/_degoogle-your-life.mdx31
-rw-r--r--old_stuff/src/content/blogs/_my-webdev-experience.md8
-rw-r--r--old_stuff/src/content/blogs/_test.md37
-rw-r--r--old_stuff/src/content/blogs/discord-sucks-so-i-made-my-own.mdx186
-rw-r--r--old_stuff/src/content/blogs/how-computer-memory-actually-works.md198
-rw-r--r--old_stuff/src/content/blogs/hytale-modding-my-honest-concerns.md158
-rw-r--r--old_stuff/src/content/blogs/making-a-game-in-3-days.mdx78
-rw-r--r--old_stuff/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx284
-rw-r--r--old_stuff/src/content/blogs/rust-is-great.md101
-rw-r--r--old_stuff/src/content/blogs/the-search-for-the-perfect-ssh-key.mdx117
10 files changed, 1198 insertions, 0 deletions
diff --git a/old_stuff/src/content/blogs/_degoogle-your-life.mdx b/old_stuff/src/content/blogs/_degoogle-your-life.mdx
new file mode 100644
index 0000000..d6fa8e1
--- /dev/null
+++ b/old_stuff/src/content/blogs/_degoogle-your-life.mdx
@@ -0,0 +1,31 @@
+---
+title: "How to de-google your life"
+description: How I de-googled my life and why you should do it too
+date: 2222-11-11
+---
+
+## What I already de-googled
+- Proton (mail, drive, calendar maybe?)
+- KeepassXC
+- Gitea
+- Linux
+- Firefox (zen)
+- DuckDuckGo
+- Google photos, Google Drive backup etc
+
+
+## New stuff
+- SMS "Messages" app
+- Kopia (write a password management/backup/other setup blog?)
+- F-droid
+- Use a custom android OS?
+- Control over notifications?
+- Fossify (Contacts/Phone/Messages)
+- CoMaps instead of Google maps
+- Aurora instead of Google play
+- NetGuard
+- Self host notes app? maybe just use git for sync + a markdown editor on mobile?
+- Disable "My files" "Usage access"
+- Disable "Phone Manager"
+- Weather app
+- Nova launcher
diff --git a/old_stuff/src/content/blogs/_my-webdev-experience.md b/old_stuff/src/content/blogs/_my-webdev-experience.md
new file mode 100644
index 0000000..6949572
--- /dev/null
+++ b/old_stuff/src/content/blogs/_my-webdev-experience.md
@@ -0,0 +1,8 @@
+---
+title: My webdev experience
+description: I made a website, here are my thoughts on web development
+date: 2024-12-13
+---
+
+Lorem ipsum dolor sit
+
diff --git a/old_stuff/src/content/blogs/_test.md b/old_stuff/src/content/blogs/_test.md
new file mode 100644
index 0000000..344a479
--- /dev/null
+++ b/old_stuff/src/content/blogs/_test.md
@@ -0,0 +1,37 @@
+---
+title: Test
+description: This is a test blog to... well.. test things!
+date: 1970-01-01
+---
+
+## Secondary
+
+Testing some content with multiline thing
+let's see what happens if this wraps
+This should be super close
+
+This should be far
+
+- Some bullets
+- Adka kda kd ak
+- d kakd akd ka k
+
+## Smaller header
+
+How about code blocks
+
+```go
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("Hello, World!")
+}
+```
+
+Hmm
+
+> Does this blockquote work
+
+This is `highlighting` I think is what it's called
diff --git a/old_stuff/src/content/blogs/discord-sucks-so-i-made-my-own.mdx b/old_stuff/src/content/blogs/discord-sucks-so-i-made-my-own.mdx
new file mode 100644
index 0000000..bfd4057
--- /dev/null
+++ b/old_stuff/src/content/blogs/discord-sucks-so-i-made-my-own.mdx
@@ -0,0 +1,186 @@
+---
+title: "Discord sucks! ...so I made my own"
+description: How I built Eko - THE discord alternative for terminal nerds
+date: 2025-08-08
+---
+
+## Discord sucks
+
+I have been disatisfied with discord for a few years by now, the main reasons that most people will
+agree with me, are it's slow, sluggish, bloated, and that it gets worse over time.
+
+- Reduced upload size from 50mb to 10mb
+- Ugly UI revamps
+- Literally ships with an entire browser (chromium due to electron)
+
+But there are a few more personal reasons for me.
+
+Ignoring the fact that I am in 100 servers and literally can't join any more,
+as someone who spends most of his day in the terminal, writing code with NVIM (btw),
+I really missed vim motions in discord, they are great and I'd probably talk about them in the future.
+
+## Searching for alternatives
+
+Vim motions are so ubiquitous they are practically everywhere, not just coding editors like Zed and
+vsc\*de but also note taking apps like Obsidian, and heck, even google docs have an extension for them.
+
+Surely an app as popular as Discord will have them right? well after some searching I found
+[Cordless](https://github.com/Bios-Marcel/cordless), a discord client in the terminal, great!
+
+Reading the readme, I immediately got dissapointed, the project has been shutdown.
+The reason was due to a high risk of Discord banning users for ToS violation, so I couldn't even make my own client!
+
+## The idea
+
+So I thought to myself, if Discord doesn't let me make a client, I'll write my own Discord, complete
+with a backend, frontend and most importantly, vim motions!
+
+Great, now that I have the idea, what languages do I use for the backend and the frontend?
+
+I heard that golang is a really good language for the backend, due to it's concurrency model making
+it easy to handle a ton of connections simultaneously.
+
+And what about the frontend? I'd need to find some library to help me make a TUI (terminal UI),
+After some searching, I found [bubbletea](https://github.com/charmbracelet/bubbletea) from [charm](https://github.com/charmbracelet),
+a golang library for creating TUIs, perfect.
+
+This has the added benefit of the backend and frontend being able to share types as they are
+written in the same language.
+
+## The implementation
+
+### The frontend
+
+Bubbletea uses the Elm architecture to create a UI, it is made out of 3 components:
+
+- The model - the state of the UI, it can contain UI elements, buttons, styles, and even other models
+- The view - a function that takes a model and returns the UI, in the case of a TUI, it just returns a string
+- The update - a function that takes the model and a message, and computes a new model based on that message
+
+The way it works, is a new message comes, for example a user resized the window, this message
+gets propagated to the model via the update method, which produces a new model, then
+the view method takes the new model and renders the new state to the UI.
+
+The concept itself is really great, although Bubbletea, partly due to golang had to make a few
+tradeoffs which made me like it less.
+
+First, golang doesn't have the concept of "const", so the view must take a copy of the model,
+FOR EVERY RE-RENDER, this is extremely inefficient, especially that most models can take thousands
+of bytes if not more, and that the copy is being pased on the stack.
+
+This doesn't only happen on view, this also happens in the update function, every update, the model
+also gets copied and passed on the stack, then the function modifies the stack version and returns
+a new version of it that is then also, gets copied on the stack.
+
+This is due to the Elm architecture originating from Elm, a functional programming language, in
+such languages mutating is discouraged, and everything gets copied.
+
+### The backend
+
+The server itself is fairly boring, it has a loop that accepts new TCP/TLS connections, and it
+spawns a new goroutine ("Green thread") to handle the client requests.
+
+So instead, let's talk about how IDs are handled!
+
+My first idea was to use a UUID (universally unique identifier), but it takes 128 bits, that seems
+way too much, 32 bits already allow for 4 billion permutations, but just in case (see IPv4 lol),
+64 bits should be plenty, that's 18 quintillion!
+
+For the format, is it fine to just randomly generate them? 18 quintillion is alot, but the chance
+of collissions is not as low as I'd like it to be, I wonder what Discord uses for their IDs...
+
+#### Snowflake IDs
+
+Discord uses snowflake IDs, originally invented by Twitter, they are 64-bit with a special format
+that guranteed uniqueness across multiple machines and data centers, here's how they work:
+
+```
+ 0 1 2 3 4 5 6
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|s| Milliseconds since Epoch | Node ID | Mac ID | Incremented |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+```
+
+- s - The sign bit when storing the ID as an int64, unused (always 0)
+- Milliseconds since Epoch - The number of milliseconds since some date, in Twitter's case this is 2010, for Discord it's 2015, and for Eko it's 2025
+- Node ID - A unique identifier for the data center or cluster, in case of Eko this is always just 1 as I run eko on a single VPS server
+- Mac ID - The specific machine ID within a cluster, in Eko this is combined with the NodeID into a single 10-bit field, with a value of 1
+- Incremented - If 2 IDs are generated in the same millisecond, this is incremented, up to 4095 times,
+allowing a single machine to generate 4 million IDs per second (1000 * 4096)
+
+The snowflake ID also has the nice benefits of embedding a timestamp in it, this allows to save
+even more space by not needing to store a separate unix timestamp for creation dates, the creation
+date of a user is when their ID was first generated.
+
+If you are interested in knowing when your discord account was created, there are [websites](https://snowsta.mp/)
+that allow you to check this.
+
+Because everything in Eko uses snowflake IDs (users, networks, frequencies, messages) this trivially
+allows us to view the timestamp, the client just shifts 22 bits to get the milliseconds, adds the
+hardcoded Epoch, formats the unix timestamp, and now you got timestamps of messages.
+
+### The protocol
+
+Ok, so we have the backend, we have the frontend, but how will they communicate over the network?
+
+The first thought that came to mind, was to use whatever Discord uses, which is HTTPS and websockets,
+but this felt wrong, using such a bloated protocol just for sending a few text messages.
+
+I decided it'd be better to design my own protocol from scratch, that'd be efficient and small.
+After a while of planning, I came up with this packet format:
+
+```
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Version |En.| Type | Payload Length |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| Payload... Payload Length bytes ... |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+```
+
+- Version (8 bits) - the most important thing when designing a protocol is to have a version field,
+ so that when you inevitably introduce breaking changes, the server and client will notice a mismatch
+ and know how to deal with it
+- Encoding (2 bits) - Indicates the format of the payload, more on that later
+- Type (6 bits) - The type of the payload, what kind of message it is
+- Payload Length (16 bits) - How long is the payload, 16 bits gives us a maximum payload size of 65,536 bytes
+- Payload (0-65k bytes) - The actual body of the message, formatted per the encoding
+
+I was thinking about how to encode the payload in an efficient format, JSON was just too verbose
+for this, after taking a look at protobufs, cap'n proto and MsgPack, I chose MsgPack, mostly
+because of it's ease of use while being almost as fast as the other 2.
+
+But I still wanted to support JSON, so I introduced a 2-bit encoding into my packet,
+the idea is the packet sender specifies 0 for JSON, 1 for MsgPack, and the other 2 are reserved.
+That way the server and client can communicate with MsgPack, but if a developer writes their own
+client that uses JSON, the server can handle that just as fine.
+
+Another thing to mention is how the type thing is used as a "tagged union", it specifies the
+structure of the payload, unlike a tagged union though, it doesn't need to store the size of the
+largest packet, that's what the payload length field is for.
+
+## The release
+
+After months of work, I am happy to present...
+
+[Eko](https://github.com/kyren223/eko) - a terminal-native discord alternative for terminal enthusiasts!
+
+<img
+ src="/eko-screenshot.png"
+ alt="Description"
+ style={{ width: "1000px", paddingBottom: "20px" }}
+/>
+
+For more information head over to the [README](https://github.com/kyren223/eko), or install it now with
+
+```
+curl -sS https://eko.kyren.codes/install.sh | sh
+```
+
+Hope to see you there!
+
+As always if you have questions or want to chat, feel free to contact me on discord at Kyren223 or email me at `contact at kyren.codes`.
+
+You can also add me on Eko, here's my ID: `2102554263552`
diff --git a/old_stuff/src/content/blogs/how-computer-memory-actually-works.md b/old_stuff/src/content/blogs/how-computer-memory-actually-works.md
new file mode 100644
index 0000000..42a4acc
--- /dev/null
+++ b/old_stuff/src/content/blogs/how-computer-memory-actually-works.md
@@ -0,0 +1,198 @@
+---
+title: How computer memory ACTUALLY works
+description: Virtual address space, paging, the stack and the heap.
+date: 2025-09-25
+---
+
+## How memory is usually taught
+
+Most universities, schools and online courses usually separate memory into 2 places:
+
+- The stack, where all your local variables live.
+- The heap, the magical place where you go get memory if you don't know the size ahead of time.
+
+This is a bit inaccurate, the CPU doesn't really differentiate between the stack and the heap[^1],
+For the CPU, it's all just a bunch of memory.
+
+## Virtual Memory
+
+In the past, programs would use physical addresses to refer to a specific place in the computer's RAM.
+nowadays this is no longer the case, because of several issues:
+
+- Insecure - malicious programs can read or write into another program's memory which may contain passwords or other secrets.
+- Bug prone - a program may accidentally read or write into arbitrary places, causing the entire system to crash
+ or misbehave, rather than just the program itself.
+- RAM-limited - the maximum memory limit is how much RAM the computer has, saving and
+ restoring memory from disk is not possible.
+
+The way modern CPUs and operating systems solve this problem is by assigning every process (program)
+it's own "virtual address space" and then map virtual addresses into physical addresses.
+
+- Fixes security - each process has it's own address space, and can't access the other address spaces.
+- Fixes bugs - the process is self-contained, crashing doesn't effect other processes.
+- Fixes memory limits - the operating system can intervene and swap memory in and out of disk
+ to emulate more RAM (at the cost of lower speeds).
+
+So how does this work?
+
+On 64-bit operating systems, pointers (addresses) are stored as 64-bit numbers, this allows for
+2^64 addreses, which is excessive, in reality, CPUs only use 48 of those bits[^2] to store the address,
+this means the virtual address space is 256TB in size.
+
+```
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+| ignored | 48-bit virtual address |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+```
+
+Of course, most computers don't have 256TB of physical memory[^2], for example, I only have 64GB.
+
+The reason this works is **virtual memory may not have physical memory backing it**, and keeping
+track of virtual memory is essentially free[^3].
+You are not storing 256TB of data, you only need to keep track of ranges of virtual addresses and
+their mapping to the physical addresses that back them up.
+
+For performance reasons, the mappings don't store ranges of individual bytes of memory, but rather
+chunks, usually 4k bytes, this is known as a "page".
+
+The operating system sets up a "page table" for each process which maps virtual pages in the process
+virtual address space into physical pages in the computer's RAM.
+
+This is enabled by hardware support. CPUs understand what a "page table" is, and have a special
+register that points to a page table, the operating system then makes sure to set that register
+to the correct page table for the currently running process.
+
+Each entry in the page table has some additional metadata such as:
+
+- Read access bit - whether the process is allowed to read from the page.
+- Write access bit - whether the process is allowed to write to the page.
+- Execute access bit - whether the process can execute code that is inside the page.
+
+We will see why that's useful soon.
+
+## Using Virtual Memory
+
+Operating systems provide through syscalls 4 main operations for dealing with virtual memory:
+
+### Reserve
+
+You ask the operating system to reserve a certain amount of virtual address (must be a multiply of
+the page size), and it gives you back a pointer to the first address.
+
+Reserving only guarantees that if you ask again, it won't give you that same range of addresses,
+but it does not yet ask for physical memory so this operation is essentially free.
+
+Trying to access reserved pages will result in a page fault causing the operating system to
+terminate the proggram with a segmentation fault (segfault).
+
+### Commit
+
+Similar to reserve, but now you are asking the operating system to back up the virtual pages you asked for with physical pages.
+You are allowed to commit pages that you have previously reserved.
+
+The operating system may not back the pages yet with physical pages, but mark the page as "no access",
+as in read, write and execute bits all set to 0.
+
+Trying to access the pages, triggers a page fault, waking up the OS, which checks if the page was commited,
+and if it was, instead of crashing the program, it'd back up the virtual page with a physical page
+(potentially swapping a page from disk), and then resuming the program.
+
+From the program's perspective, everything looks normal except the performance hit due
+to the added delay, which can be measured.
+
+### De-commit
+
+De-commit releases the physical memory backing the page up, and changes the virtual page to being reserved.
+
+### Release
+
+Release releases physical memory of the page AND un-reserves it from the virtual address space.
+
+## What is the stack VS the heap then?
+
+So, if the operating system only deals with pages and virtual memory, then why do people
+differentiate memory into "the stack" and "the heap"?
+
+### The stack
+
+The stack is a region where functions[^4] store their local variables, but it's just
+memory, the compiler specifies the wanted stack size in the executable format (usually 1MB on windows and 8MB on linux),
+and the OS reserves it in the virtual address space when it creates the process.
+
+The heap on the other hand, is a higher-level interface that operating systems usually provide.
+it's a way to allow many big or small allocations, to be as efficient as possible.
+To achieve this, it uses techniques like freelists to chunk many pages into fine-grained allocations.
+
+### Allocators
+
+Things like `malloc` and `free` are examples of heap allocators.
+
+In almost all cases, you don't need such a generic allocator like malloc, and instead, other allocators
+such as arenas and pools cover most use cases.
+
+Arenas are stack allocators, they have a base pointer and a size, and they can push new elements,
+pop the last element, or release the entire thing at once (by resetting to 0).
+
+Use cases for arenas include in games or apps, a frame-arena that you reset at the start of a frame,
+or in web servers a per-request arena that resets when a response is served.
+
+A pool is an arena that stores fixed-size elements, this restriction enables the ability to reuse
+elements that have been freed anywhere, not just the top of the stack like a normal arena.
+
+Use cases for pools are for example in games, a pool for enemies, defeating an enmey and then
+spawning a new one, reuses the space left by the defeated enemy.
+
+For more information on memory management techniques, see [my curated list of resources for managing memory](https://git.kyren.codes/Kyren223/resources#how-to-actually-manage-memory-its-easy).
+
+## A cool trick that virtual memory enables
+
+### Growing a Dynamic array / Vector / List without resizing
+
+The way most languages implement dynamic arrays (like C++, Rust, Go) force a limitation on the programmer:
+pointers are not stable.
+
+This means that if you take a reference to an element in the dynamic array, and then add an element to it,
+the reference may no longer be valid.
+
+This is due to the case where you add an element, if there is not enough space in the array,
+it may need to resize it, by creating a new (larger) array, copying all the elements, and then
+returning the new larger array, so of course retaining a reference to the elements isn't valid.
+
+This annoying restriction can be lifted entirely by using the knowledge we learned about how
+the virtual address space works.
+
+Because the address space is so large (256TB), we can reserve an excessively large chunk, say 64GB
+of it, but only commit a single page, then whenever we need to grow, we just commit more pages.
+
+Of course, 64GB is quite large and takes a decent chunk out of those 256TB, but the point was to
+show it's possible. In practice, you will most likely have some upper bound for how much you are
+expecting to be the maximum, for example in my own codebase, I usually only reserve 64MB.
+
+This works because from the perspective of your program, addresses are contiguous due to using
+virtual memory. The physical pages in RAM that back the virtual memory are basically always
+scattered and fragmented anyways.
+
+## End
+
+As always if you have questions or want to chat, feel free to contact me on discord at Kyren223 or email me at `contact at kyren.codes`.
+
+And if this kind of stuff interests you, I recommend checking out [my curated list of resources](https://git.kyren.codes/Kyren223/resources)
+for further reading about these topics.
+
+[^1]:
+ CPUs have 2 registers usually called sp (stack pointer) and bp (base pointer) for
+ storing the lower and upper bounds of the currently active stack.
+ They are used in instructions like push and pop.
+
+[^2]: Some super computers exceeded the 256TB limit, so certain CPUs support 52-bit or 56-bit addresses
+
+[^3]:
+ Misses in the translation lookaside buffer (a cache on the CPU for translating between virtual and physical memory)
+ can sometimes become a performance bottleneck (Thanks Martins Mozeiko for pointing this out!).
+ This is due to the need of storing an entry for every 4kb page, this can be mitigated by using
+ "large pages", which are usually 2MB in size, substantially reducing the amount of needed page entries.
+
+[^4]:
+ Procedures is the more correct term, function implies "pure function" with no side effects (like in math),
+ while procedures may or may not have side effects.
diff --git a/old_stuff/src/content/blogs/hytale-modding-my-honest-concerns.md b/old_stuff/src/content/blogs/hytale-modding-my-honest-concerns.md
new file mode 100644
index 0000000..2ae3fd2
--- /dev/null
+++ b/old_stuff/src/content/blogs/hytale-modding-my-honest-concerns.md
@@ -0,0 +1,158 @@
+---
+title: Hytale Modding - My honest concerns
+description: Hytale finally released, promising modding, but iz it true?
+date: 2026-02-02
+---
+
+## Hytale
+
+For those who don't know, [Hytale](https://hytale.com) is a video game created by Hypixel Studios (the people behind Minecraft's largest server: Hypixel), which has been in development for over 7 years, and has finally been released in public beta on January 13th 2026.
+
+Minecraft was a big part of childhood, and was what pushed me into becoming a programmer, I started by making Minecraft mods and plugins using Java.
+So you can imagine how excited I was for this new game to release, especially because of the promises around great modding support.
+
+Unfortunately, now that the game has released, and we can see how the game and it's modding support works, I have came to realize a few major problems with the way it's been designed, and unless these problems are addressed and fixed, I am unable to imagine a thriving modding community at the level Minecraft has.
+
+## The good
+
+First, to not be all that negative, I have to give credit to Hypixel Studios for the things they did get right when designing the game and the way modding works.
+
+### The Entity Component System
+
+An Entity Component System (ECS) is a somewhat old concept that has only recently became popular in the game development world, it's a way to architecture the game by composing entities out of various components, and then running systems to update components efficiently.
+This is opposed to the more common approach (that Minecraft uses) which is Object-oriented programming (OOP) which creates hierarchies of entities, leading to less modularity and horrible performance.
+
+Although Hytale's ECS is written in Java, which prevents most performance optimizations, it's still way better than OOP, both in terms of performance and in terms of developer experience.
+
+### Official modding
+
+Unlike Minecraft which has multiple 3rd-party providers for modding (Forge, Fabric, Spigot, and more), Hytale has a single official API.
+
+This leads to 2 main benefits: users don't have to choose which provider to use (limiting them to only mods written for that provider) and developers don't have to port their mods to multiple providers to be more widely available.
+
+## The bad
+
+ I do hope Hytale succeeds, and it is a beta after all so things aren't perfect, but my concern is their next plans for modding seem to focus on less relevant things rather than solving the major issues.
+
+### No client modding
+
+Hytale modding is completely server-side, similar to Minecraft plugins or server-side mods.
+
+This means that a mod's code is run solely on the server and not on the client's computer, while assets such as textures, models, sounds and configs are sent to the client to be used.
+
+I think the logic behind this is to allow Hytale to release the original unobfuscated server source code (which Minecraft only recently done), but disallowing in their ToS any client-side modifications and reverse engineering, to still keep half of their game "private".
+
+### Only one version
+
+Hytale forces the client to always use the latest version, unlike Minecraft which allows going back to older versions.
+
+Their logic is that server owners and modders only need to take into consideration the latest version of the client, which saves time.
+
+## The ugly
+
+At first glance, these decisions seem good and beneficial, but upon further consideration, they are actually detrimental to a thriving modding community.
+
+### High latency lag
+
+The largest issue with everything being on the server, is every time the client wants to do something, it must do a roundtrip by sending a request to the server and awaiting for a response, this is what ping is, how long it takes for a roundtrip.
+
+My average ping on Minecraft is 200-300ms, that's 1/4 of a second or equivalent to 4fps, imagine how annoying it'd be to have to wait that long between pressing a button to move, to actually moving on the screen, it'd be unplayable.
+
+Luckily there is a solution for this -- prediction (of movement), the client AND the server both calculate the location, then, the client moves there on the screen immediately, without waiting for the server.
+Then once the server responds, the client checks if the results are too much out of sync, in which case it uses the server position.
+
+Fortunately both Minecraft and Hytale implement this (if you ever got "lag backed", this is why).
+
+But unlike Minecraft which does it for movement, blocks, chests, and more, Hytale does it to a more limited set of hardcoded things like movement, but not blocks and UIs.
+
+Usually this wouldn't be an issue, mod creators can fix this by creating their own mod that runs on both the client and server, where the client version does the prediction, making it feel instant, unfortunately this is impossible with Hytale, this means that mods like Refined Storage will have a 1/4 of a second delay each time you try to put/take a block from the inventory, very annoying.
+
+Another limitation of no client side modding support is the inability of adding things like custom key bindings, this can be added by Hytale, but again, with a delay due to server roundtrip latency.
+
+### Per-clieant customizations
+
+Minecraft has plenty of client-side mods which allow customizing the client in a way that doesn't effect the server, this is most often used for visual effects using resource packs, shaders or additional HUD elements.
+
+This is unfortunately impossible in Hytale beyond the few hardcoded settings that exist, due to mods being server side only, it means that at best servers can control a single global texture pack for all players that play it, but there is no individual personalized resource packs, and shaders are completely impossible.
+
+Even community-made client-side mods by reverse engineering the client can't exist because Hytale explicitly prohibited it in their ToS and made it illegal to do.
+
+### Version chasing
+
+In practice, rather than helping players and modders save time, targeting only one client version causes a huge problem.
+
+Players can't play servers that don't support the latest version of the client, If there is a breaking change to the client-server protocol, which will almost certainly happen every large version update, then players won't be able to play.
+
+In practice this means that Hytale not only forces clients to not play older versions, they also force server owners to always run and update to the latest server version, which forces modders to update their mods to the latest version.
+
+This is a huge problem for a bunch of reasons:
+
+Minecraft mods/modpacks usually target every other major version, this gives mods more time to improve their mods before immediately having to work on porting to the new versions.
+
+Mods that were abandoned and not updated to newer versions will not be playable, which is a huge issue considering the most played Minecraft modpacks (SkyFactory, GregTech, FTB) use older Minecraft versions, and have not been updated to the latest one.
+
+Having access to older versions means that if Hytale ever makes a change the community dislikes, they can still go back and play older versions they enjoy more, similar to how some Minecraft players still play 1.8 because they prefer that PvP style.
+
+### Lack of Big mods & modpacks
+
+All the previous issues will likely lead to this problem, there won't be many competent developers willing to invest massive amounts of time to make high quality mods for the community.
+
+And I don't blame them, why would you spend so much time if you have to constantly update your mods to newer versions instead of improving them, have your mods feel laggy due to high latency and have players forget them if you ever stop updating them to the latest version, and all of that, for free.
+You may as well take that effort and put it into Minecraft modding.
+
+There will certainly be attempts to replicate mods like RS/AE2, Create, Mekanism,
+Botania and others, but they will be made by less experienced beginners and will probably be inefficient and worse than their Minecraft equivalents.
+
+### No content for players
+
+Hytale is still in beta, and doesn't have much content yet, it only took me a few days (20-30 hours of playtime) to explore about 75% of the content (on my first and casual playthrough).
+
+Usually this isn't a problem, except that Hytale's Community are mostly Minecraft players, the same people who expect endless content for a $20 game.
+
+There is a reason I was able to play Minecraft almost daily for an entire decade without getting bored, and that reason is mods.
+
+The base game eventually gets boring, there are only so many things you can do, and Hytale knows it, which is why they advertise their "Great modding capabilities" so much, they are counting on modders creating content for them for players to play.
+
+If there are no competent modders to create popular high quality mods, then there is no content, if there is no content, players will eventually get bored and move on to other games, no players, means the game will die.
+
+I really hope this doesn't happen, but at the current state of things, I can't see how it won't happen.
+
+## Solutions
+
+Let's end this on a more positive note -- what can Hytale do to fix these issues and convince modders it's worth their time?
+
+### Multiple versions
+
+Let's start with the easy problem - only one version, the fix is extremely simple, just add a dropdown in the launcher to select previous client versions.
+Of course, I don't expect Hytale to support all these versions, by neither does Minecraft, just have them available to download, and even add a "Unsupported" text next to them.
+An even nicer option would be to allow separate game profiles which contain both versions, world and settings, but this can be left as a responsibility for 3rd-party launchers (like Modrinth, and Prism in Minecraft).
+
+### Client-side modding
+
+For the other problem of client side modding, it's a bit more complicated and technical but still doable.
+
+Hytale seems to have 2 main requirements that prevented it from doing client-side modding like Minecraft: security and copyright/IP.
+
+Minecraft client mods are inherently insecure, they have access to the client's computer, allowing malicious mods like rats, ransomware and otherwise to effect your system.
+
+So how do we allow code execution, without opening ourselves to security, while also not exposing any details about the client code to avoid copyright/IP issues?
+
+It's simple! Just copy what websites do!
+Websites also run code on a User's computer, and yet if you go to a malicious website, they can't hack you, the solution is by running a sandboxed programming language and then only allowing it to access an API, which decides what it is or isn't allowed to do.
+In the web world, this is done using JavaScript and web APIs.
+
+JavaScript is terribly designed, so Hytale can use something else like Lua, then Hytale needs to write a comprehensive API allowing lua code to access all game related values on the client (player position, entities, chunks UIs, assets, etc).
+
+This solves the security issues, lua is sandboxed and thus any malicious code can't do anything harmful, and because they only expose things via an API, Hytale doesn't have to share the client's source code.
+
+Then, to fix both server-side latency and client-side customization: Lua scripts can be sent to the client the same way assets like textures are currently sent, this allows server-side mods to write their own client-side predictions avoiding latency, or alternatively, players can install scripts locally to only modify their client without effecting the server.
+
+And when Hytale was owned by Riot games (before Hytale was purchased back by it's original founder Simon), they were planning on using Lua for what seemed like a very similar system to what I was proposing.
+
+But unfortunately instead of working on that, Hytale seem to want to focus on a very complex visual scripting system for client side modding, which not only will take significantly longer to implement than what I proposed, it'd also be significantly limited and most programmers are more productive and prefer writing code in text rather than a visual scripting system.
+
+## Conclusions
+
+Hytale seems like a very promising game that can finally give a new fresh take on the Minecraft genre, but in its current state it has major flaws in terms of modding ability, but I believe it can be resolved by implementing my suggested solutions.
+
+And as always, if you wish to talk to me about this topic, programming or anything else, you can contact me on discord at Kyren223 or email `contact @ kyren dot codes`.
diff --git a/old_stuff/src/content/blogs/making-a-game-in-3-days.mdx b/old_stuff/src/content/blogs/making-a-game-in-3-days.mdx
new file mode 100644
index 0000000..47b0949
--- /dev/null
+++ b/old_stuff/src/content/blogs/making-a-game-in-3-days.mdx
@@ -0,0 +1,78 @@
+---
+title: "Making a game in 3 days"
+description: How we built a game in zig for the boot.dev hackathon
+date: 2025-07-28
+---
+
+This blog post is about my experience participating in the boot.dev 2025 hackathon.
+
+## The team
+
+- Kyren223 (me) - discord kyren223
+- GottZ - website https://contact.gottz.de/
+- Nuclear Pasta - discord jacob_v_thaumiel
+
+## The idea
+
+Initially we wanted to make a programming language REPL, but a REPL is not very
+visual, and we also realized that maybe making an entire language in 3 days
+isn't very realistic, so instead we decided to go for an even more difficult
+idea, making an entire game, in 3 days...
+
+## CPU vs AI
+
+We knew we wanted to make something coding-related, we thought about including
+a programming language in the game, and that led us to an idea about CPU instructions.
+This idea evolved into a tower defense game, where the CPUs are towers defending
+against pesky bugs like null pointer dereferences and infinite loops.
+
+For the language, we chose Zig, for the following reasons:
+
+- Me and nuc are already familiar with it (and really like it)
+- Total control over memory (manual memory management)
+- Blazingly fast
+- Great interopability with C (for GottZ)
+- Simple and C-like
+- Modern (optionals, tagged unions, functions on structs, etc)
+
+For the game library, we decided to go with [raylib-zig](https://github.com/Not-Nik/raylib-zig),
+the [raylib](https://github.com/raysan5/raylib) bindings for Zig.
+
+We did so because raylib is an extremely simple to use bare bones library
+to handle things usch as player input and graphics.
+
+## Difficulties
+
+To avoid git conflicts on a fresh project, we decided to use [Zed](https://zed.dev/)'s collaborative features
+to write code as if it was a google doc.
+
+This worked for a while but the Zig LSP didn't work well and it was really hard
+to test when only 1 person can build the project.
+
+Because of this on the 2nd day once we had more "surface area" we decided to
+go back into commit-push and pull workflow so each of us can use our favorite
+editor and run the project locally.
+
+By the end of the 2nd day the project was mostly complete, we spent the rest of
+the day adding polish like fancy game over and victory screens, statistics,
+making the readme, fixing bugs etc.
+
+## Finally
+
+After 3 days of hard non-stop coding, we actually got a working game.
+It consists of 3 levels and even with very basic mechanics it's already fun!
+
+> Nuclear Pasta
+> I feel like I'm playing Bloons
+
+So what are you waiting for? go give the game a try!
+
+[https://github.com/The-Memory-Managers/cpu-vs-ai](https://github.com/The-Memory-Managers/cpu-vs-ai)
+
+Don't forget to star the repo!
+
+Not in the mood to play? watch a demo playthrough [here](https://youtu.be/_clLDGNlef0).
+
+This is just a prototype, we plan on (eventually TM) making a full game out of it, so stay tuned!
+
+As always if you have questions or want to chat, feel free to contact me on discord at Kyren223 or email me at `contact at kyren.codes`.
diff --git a/old_stuff/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx b/old_stuff/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx
new file mode 100644
index 0000000..7b8c235
--- /dev/null
+++ b/old_stuff/src/content/blogs/nixos-the-perfect-distro-for-a-production-server.mdx
@@ -0,0 +1,284 @@
+---
+title: "NixOS: The perfect distro for a production server"
+description: My experience using NixOS to manage my production VPS
+date: 2025-01-01
+---
+
+NixOS is a linux distribution praised for it's functional-style declarative
+configuration that allows you to manage the entire system through the Nix
+programming language, making your sytem reproducible and more reliable.
+
+This is in contrast to other linux distros that use a more imperative approach
+of managing the system by running commands to install packages, create
+users, etc.
+
+## NixOS as a daily-driver operating system
+
+About half a year ago I started using Windows subsystem for linux which enabled
+me to run a linux distro in the terminal, 6 weeks ago I finally decided to make
+the jump and switch from windows to a full linux desktop experience.
+
+I wanted a linux distro with a large set of latest-version packages but still
+stable without risk of getting my system broken (sorry Arch).
+
+I was considering going with Tumbleweed, a rolling release distro
+by openSUSE which I was already familiar with because I was using it in WSL.
+
+But then I remembered Nix, this weird thing that is an operating system,
+programming language, and a package manager.
+
+Nixpkgs is the the package repository with the most fresh packages (even more than AUR),
+and it has a really cool benefit of being able to install all my packages
+through a config file, similar to NVIM with lazy.nvim or rust with cargo.
+
+Initially I was considering using something like Debian with nixpkgs as I heard
+that was possible, but some people warned me that it's a bad idea to not use
+the native package manager, so I ended up **going with NixOS as my first linux
+distro on desktop**.
+
+I followed a [great video about installing NixOS](https://www.youtube.com/watch?v=a67Sv4Mbxmc) by Vimjoyer
+and was able to get it up and running.
+Although I experienced some issues in the first few days, that was expected
+and I was able to solve all of them.
+
+One trap to be aware of is the nix community is sometimes too enthusiastic and
+will try to convince you to do things "the nix way" like rewriting your
+perfectly fine existing configs in nix or moving from stow to home manager.
+
+In my opinion, I don't want to waste so much time configuring everything,
+I am OK with only configuring system settings and packages while having things
+like other dotfiles or scripts be handled the "normal linux way".
+
+## NixOS as a production server distro
+
+A few days ago I got my first VPS, a RS 1000 from netcup (use code
+`36nc17355743780` for a $5 discount),
+my goal with it was to host my website along with some other self-hosted apps
+including my own server for a terminal-based social media I am working on
+(which I will make a blog post about in the future).
+
+Infrastructure as code (IaC) is the practice of managing servers through
+configuration files rather than manual instructions (such as running commands),
+this has several benefits such as being able to use version control and ensuring
+a more reproducible server that can be easily deployed and updated using these
+files.
+
+This is where NixOS comes in and really shines, all these "nix ways" of
+configuring stuff as a desktop OS seems overkill and time consuming but for a
+server that's exactly the point, to be able to reproduce the entire system
+from only a bunch of nix files.
+
+## Configuring a server with NixOS
+
+After struggling to install NixOS, I discovered [NixOS Anywhere](https://github.com/nix-community/nixos-anywhere)
+which made it very easy to install remotely through SSH.
+
+First thing was setting up proper SSH authentication and security.
+
+Nix makes it really simple to do, just add these 2 lines to enable ssh
+but disable the insecure password authentication
+
+```nix
+services.openssh.enable = true;
+services.openssh.settings.PasswordAuthentication = false;
+```
+
+And to add a public key to connect with to the root user
+
+```nix
+users.users.root.openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren"
+];
+```
+
+If you would like to know how I generated a key that ends with `/Kyren` read
+my first blog post - [The search for the perfect ssh key](http://localhost:4321/blogs/the-search-for-the-perfect-ssh-key)
+
+### Managing secrets with sops-nix
+
+Next, before we can get into configuring a webserver, we need a good way
+to store secrets for things like SSL certifications, [sops-nix](https://github.com/Mic92/sops-nix) is a nix module
+that integrates the [sops CLI tool](https://github.com/getsops/sops) into nix.
+
+Rather than having to set up 20 different secrets for each thing, it allows
+us only setup 1 secret that is stored on the server and on the admin's
+system, then, any additional secret can be defined in a file that gets
+encrypted automatically by sops which can safely be committed into version control.
+
+At runtime sops will write all these files to a directory which can then be
+accessed by anything that needs access to that secret, sops also makes it easy
+to let specific users or groups access to a specific secret.
+
+### Setting up automatic updates
+
+We have added sops-nix, but how can we get it into the server?
+
+The simple approach would be to ssh as root into the server, git clone the
+repository with the config and then run
+
+```sh
+nixos-rebuild switch --flake .#default
+```
+
+_assuming you are inside the git directory where your `flake.nix` is and your
+`nixosConfigurations` is called `default`_
+
+While that certainly works, a better approach would be to listen for changes
+to the git repository and automatically pull and rebuild the system.
+
+```nix
+system.autoUpgrade = {
+ enable = true;
+ flake = "github:kyren223/server#default";
+ dates = "minutely"; # Poll interval
+ flags = [
+ "--no-write-lock-file" # Prevent flake.lock from upgrading
+ "--option" "tarball-ttl" "0" # Required for polling below 1h
+ ];
+};
+```
+
+This will automatically run every minute to fetch the github repository
+and rebuild the system.
+
+But wait, what if the repository is private? that's where sops-nix comes in!
+
+```nix
+sops.secrets.github-access-token = { };
+nix.extraOptions = "!include /run/secrets/github-access-token";
+```
+
+The first line defines a new `github-access-token` secret, and the second line
+makes sure nix is aware of it so it can use it when trying to fetch the repo.
+
+Of course, make sure to define the secret in your `secrets.yml` file,
+The key would be `gituhb-access-token` and the value would be a github PAT
+token.
+It's recommended to only give the token read-only access to the repo's contents.
+
+## Serving a static website
+
+Now that we have a way to manage our secrets, and continious deployment of our
+nix configuration, we can finally start working on a website.
+
+The plan is to host multiple websites in the future so I'll be using [Nginx](https://nginx.org/en/)
+as a reverse proxy.
+
+```nix
+services.nginx.enable = true;
+services.nginx.virtualHosts."kyren.codes" = {
+ useACMEHost = "kyren.codes";
+ forceSSL = true;
+ locations."/" = {
+ index = "index.html";
+ root = "/srv/website";
+ };
+};
+```
+
+This enables nginx, which installs it on our system then defines a new virtual
+host with the domain `kyren.codes`, later if we were to host other sites, the
+virtualHost can be something like `git.kyren.codes`.
+
+The `locations."/"` sets the base url of our website to `/srv/website` which is
+where I have my website's static files, and nginx will serve `index.html` as
+the default page when you go to that domain, later I will explain how to setup
+continious deployment to automatically update this directory on push to master.
+
+The `useACMEHost` and `forceSSL` makes sure the server uses https, you'd need
+to get a SSL certificate from [Let's Encrypt](https://letsencrypt.org/), once
+again, Nix makes it really simple to do
+
+```nix
+# Define the token using nix, make sure the "acme" user can access it
+sops.secrets.cloudflare-dns-api-token = { mode = "0440"; owner = "acme"; };
+
+security.acme.acceptTerms = true;
+security.acme.defaults.email = "acme@kyren.codes"; # Your email
+
+security.acme.certs."kyren.codes" = {
+ domain = "kyren.codes";
+ extraDomainNames = [ "*.kyren.codes" ];
+ dnsProvider = "cloudflare";
+ environmentFile = "${pkgs.writeText "cf-creds" ''
+ CF_DNS_API_TOKEN_FILE=${config.sops.secrets.cloudflare-dns-api-token.path}
+ ''}";
+ webroot = null;
+};
+
+# Allow nginx to access acme certs
+users.users.nginx.extraGroups = [ "acme" ];
+```
+
+This defines a `kyren.codes` entry (which is what `useACMEHost` references)
+I am using cloudflare as my DNS provider, but you can get a full list of
+supported DNS providers at [this link](https://go-acme.github.io/lego/dns/), and
+of course make sure to change the environment variables to match your provider.
+
+Now if we commit and push these changes and wait about a minute for the server
+to pull the changes, we should have a working static site at `kyren.codes`.
+
+### Setting up continious deployment for the website
+
+The way we are going to do this on the server is create a new linux user and
+add to it a public ssh key that will be used for deployments.
+
+It's recommended that the user is restricted as much as possible so in the case
+of a hacker getting access to the key, they won't be able to get into other
+services that are running on the server.
+
+We can create a user declaratively like this
+
+```nix
+users.users.website = {
+ isNormalUser = true;
+ group = "users";
+ openssh.authorizedKeys.keys = [
+ # Allow an admin to manually SSH
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren"
+
+ # The deployment public key
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ1B/i/AQLYt6mrz0P/oUJItpvWXp7z0xHNzmcPdtwWd"
+ ];
+};
+
+# Make sure the /srv/website always exists
+# Give read and write permissions to the website user
+# Give read permissions to the nginx group (so nginx can serve it)
+systemd.tmpfiles.rules = [
+ "d /srv/website 0750 website nginx"
+];
+```
+
+Now all you need to do is have a github action (or similar) that builds your
+website then copies the build output into the server by SSH-ing into it.
+You can take a look at [my github action](https://github.com/Kyren223/website/blob/master/.github/workflows/deploy.yml)
+for my website to see an example of how you can do it.
+
+## Conclusions
+
+NixOS helps system admins and developers achieve infrastructure as code by
+allowing them to declare the entire machine's configuration using the powerful
+Nix programming language.
+
+This makes the state of production machines more consistent and reliable while
+making it easy to reproduce across hundreds of machines.
+
+Compared with the traditional approach of a debian or ubuntu server, where
+system admins would have to painfully manage the state of all machines ensuring
+all the dependencies, firewalls, OS settings, etc are configured properly.
+
+Because of the difficulty, OCI containers such as docker became popular, but
+they come with a cost, mainly performane due to virtualization. NixOS makes it
+easy to configure programs to run on bare-metal making it a better, more
+performant alternative to docker.
+
+**Thanks for reading! wishing you a year full of code, growth and new oppurtunities!**
+
+If you'd like to learn more about NixOS, here are some resources I found useful:
+
+- [NixOS in production](https://github.com/Gabriella439/nixos-in-production)
+- [Vimjoyer's Youtube Channel](https://www.youtube.com/@vimjoyer/videos)
+
+Have questions or just want to chat? feel free to contact me on discord at
+Kyren223 or email me at `contact at kyren.codes`.
diff --git a/old_stuff/src/content/blogs/rust-is-great.md b/old_stuff/src/content/blogs/rust-is-great.md
new file mode 100644
index 0000000..6916867
--- /dev/null
+++ b/old_stuff/src/content/blogs/rust-is-great.md
@@ -0,0 +1,101 @@
+---
+title: "Rust is great... except for the language"
+description: ""
+date: 2026-08-27
+---
+
+For those who know me it might be weird seeing me say "Rust is great", after all, I have been
+openly bashing and criticize the language for quite a while now.
+
+While my opinion on Rust hasn't changed, I came to a realization that made me appreciate Rust
+for what it has taught me -- which I hope to share in this blog.
+
+## What is Rust?
+
+> Rust is a blazingly fast and memory-efficient language: with no runtime or garbage collector,
+> Rust's rich type system and ownership model guarantees memory-safety and thread-safety,
+> enabling you to eliminate many classes of bugs at compile-time.
+
+Well... at least that's how the Rust website describes the language, in reality this is mostly
+propaganda, it's inaccurate and misleading at best.
+
+A more fair definition might look like:
+
+Rust is a language that restricts the way you are allowed to program, enabling it to make certain
+guarantees that allows detecting memory and data corruption at compile time.
+Rust doesn't have a garbage collector, making it usually faster than garbage-collected languages.
+
+So, both of these definitions seem to focus on Rust being able to guarantees that usually only
+garbage collected languages can make, so how does it do that?
+
+Rust accomplishes that via it's most unique feature: the Ownership Model.
+
+## What is Ownership?
+
+There are 3 rules to ownership:
+
+- Each value in Rust has an owner
+- There can only be one owner at a time
+- When the owner goes out of scope, the value will be dropped (freed/deallocated)
+
+Assigning a value to a variable, passing it as an argument to a function[^1] or returning it will
+result in what's called a "move", where the existing variable gives up it's ownership and passes
+it to a new owner.
+
+This mostly applies to types that allocate a resource that needs freeing, which in Rust means any
+type that implements the `Drop` trait.
+Types that don't implement `Drop` such as integers and other primitives are "trivially copyable"
+meaning the value just gets copied instead of "moving" ownership.
+
+Just these rules already make a few nice guarantees:
+
+- Values are only dropped exactly once, preventing double frees
+- Values can't be used after being dropped, preventing use-after-free (UAF)
+- Values will be automatically dropped, preventing SOME memory leaks.
+
+One issue with this, is that if you pass a few values to a function temporarily, you must return
+all of them back, otherwise the caller can no longer use them.
+
+This is fixed by another concept called "borrowing" -- as the the name suggests, instead of giving
+up ownership, it allows to "borrow" a _reference_ to a value temporarily, and later return the
+reference back to owner.
+
+There are 2 types of references, a read-only (immutable) reference, and a read-write (mutable)
+reference. By restricting the programmer to only ever have a single mutable reference OR any
+number of immutable references Rust is able to guarantee a bit more:
+
+- Data races can't happen as a value will never be written to while also being read/written by
+ something else
+- References are always valid (no dangling references)
+
+There is one more concept worth mentioning, but first, I'd like to take this opportunity to shine
+a light on one of my biggest issues with the language -- the restrictiveness of it.
+
+While these rules do give us guarantees, they make our lives incredibly tedious, we constantly
+have to keep track of what's mutable, and what isn't, and what references do we have to what,
+and if we get any of that wrong, we have to stop what we are doing, read a long error message, fix
+the bug, and then go back and try to remember what we actually wanted to do - and then again,
+every few minutes, it destroys productivity.
+
+And it doesn't even need to be a complex example, even this simple code doesn't compile:
+```rust
+let my_list = vec![1, 2, 3, 4];
+let first: &i32 = my_list[0];
+my_list.push(5); // error: can't take mutable reference because immutable reference exists (first)
+let last: &i32 = my_list[my_list.len-1];
+println!("{first} and {second}");
+```
+
+This is a very simple code example that doesn't violate any of the guarantees[^2] Rust makes, yet
+Rust does not compile this code. This is because not every valid program would be verifiable by
+Rust, there will always be correct programs that Rust will deny.
+
+## Lifetimes
+
+
+
+
+
+
+
+
diff --git a/old_stuff/src/content/blogs/the-search-for-the-perfect-ssh-key.mdx b/old_stuff/src/content/blogs/the-search-for-the-perfect-ssh-key.mdx
new file mode 100644
index 0000000..09cc13c
--- /dev/null
+++ b/old_stuff/src/content/blogs/the-search-for-the-perfect-ssh-key.mdx
@@ -0,0 +1,117 @@
+---
+title: The search for the perfect SSH key
+description: How you can embed your name in an SSH key
+date: 2024-11-15
+---
+
+SSH keys are a widely used tool among developers,
+they are the equivalent of a username and password in the development world.
+They allow you to prove your identity and they are the gateway
+into accessing servers remotely in a secure manner.
+
+## The SSH public key format
+
+When generating an ssh key, you get 2 files, one with no extension that stores the private key
+and another that ends with a `.pub`.
+The public key is what you share publicly on your profile or add to a remote server to login through SSH.
+
+Here's how a typical SSH public key looks
+
+```
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBSSj+yfJLWEb+Df4r4603TOFAUBREYS43qQB+c9i9UW
+```
+
+It consists of 2 parts, the algorithm, in this case it's
+`ssh-ed25519`, but it can be other ones too such as `ssh-rsa`.
+The second part is a base64 encoded custom binary format.
+
+Let's break it down
+
+- the length of the algorithm string, for ed25519 it's always 11 (4 bytes long)
+- the algorithm type, for ed25519 it's always `ssh-ed25519` in binary (11 bytes long)
+- the length of the key, 32 bytes for ed25519 (4 bytes long)
+- the raw bytes for the ed25519 key (32 bytes long)
+
+## Embedding a word in base64
+
+Base64 is a widely used format for displaying binary in a compact and human readable way,
+it uses A-Z, a-z, 0-9, '/' and '+' adding up to 64 unique characters.
+
+It's possible to choose specific bytes in a way that when encoding it with base64
+it will form a word.
+
+For example, to encode "Kyren" in base64, we can use the bytes
+`00101011 00101010 01001110` or in hex `2b 2a de`.
+
+So by controlling the 32 bytes at the end of the ssh we are able to get
+a ssh public key containig any keyword we want.
+
+## Brute Force
+
+Unfortunately this approach won't work, we still want to be able to use the key
+so we will need to know the corresponding private key, but it's impossible to reverse engineer
+the private key using the public one, that's why cryptography is so secure.
+
+The solution is simple, just generate a bunch of keys until we get lucky and find the desired keyword.
+So that's what I have done, here's a basic go program that does exactly that.
+
+```go
+package main
+
+import (
+ "bytes"
+ "crypto/ed25519"
+ "encoding/base64"
+ "fmt"
+
+ "golang.org/x/crypto/ssh"
+)
+
+func main() {
+ keyword := []byte("Kyren")
+ for {
+ pubKey, privKey, _ := ed25519.GenerateKey(nil)
+ sshPubKey, _ := ssh.NewPublicKey(pubKey)
+ pub := ssh.MarshalAuthorizedKey(sshPubKey)
+ if bytes.Contains(pub, keyword) {
+ privBase64 := base64.StdEncoding.EncodeToString(privKey)
+ fmt.Printf("Found %s in %s with private key %s\n", string(keyword), string(pub), privBase64)
+ break
+ }
+ }
+}
+```
+
+I have later improved this program by adding multithreading and made it easier to use.
+The final code is available on my GitHub [at this link](https://github.com/Kyren223/ed25519-key-gen).
+
+## Results
+
+After running it for 2 days (about 24 hours in total) on my AMD Ryzen 5 7530U laptop (12 threads),
+here are the results:
+
+```
+Completed Search
+Time Elapsed: 12h9m11.225248108s
+Searched: 6733606724 Found: 737
+```
+
+- Generated and searched 150k SSH keys per second
+- Found a 5-character keyword every 9.1 million keys or about 1 every minute
+- Found a 6 character keyword every 1/64 of every 5-character keyword, or about 1 every hour
+- Found 5-character that are at the end of the SSH key 1/50 of every 5-character keyword
+
+My goal was to find a `/kyren` at the end of the key,
+on average that'd be 1 every 3200 5-character keywords.
+
+At the end after only 1862 keywords I found the key, here it is
+
+```
+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO7P9K9D5RkBk+JCRRS6AtHuTAc6cRpXfRfRMg/Kyren
+```
+
+I hope this inspires you to try and find your own SSH key,
+hopefully your name is not 7 characters long,
+and if it's 8, I hope you have 170 years to spare.
+
+Thanks for reading! this is my first blog post so any feedback will be appreciated!