Compare commits
3 commits
5d31cb4027
...
b06499d7a2
Author | SHA1 | Date | |
---|---|---|---|
b06499d7a2 | |||
9ee8582390 | |||
3b6e441d48 |
|
@ -4,8 +4,9 @@ base_url = "https://lynxize.dev"
|
|||
compile_sass = false
|
||||
build_search_index = false
|
||||
|
||||
generate_feeds = false # need to configure it to be at /blog/atom.xml which takes Work(tM)
|
||||
generate_feeds = false # set to true in the blog _index
|
||||
|
||||
author="lynxize"
|
||||
|
||||
[markdown]
|
||||
highlight_code = true
|
||||
|
|
|
@ -22,7 +22,7 @@ You can find the source for this site [here](https://git.lynxize.dev/lynxize/web
|
|||
You can find me in the following places:
|
||||
- Discord - `@lynxize`
|
||||
- Bluesky - [`@lynxize.dev`](https://bsky.app/profile/lynxize.dev)
|
||||
- GitHub - [`@lynxize`](https://github.com/lynxize)
|
||||
- GitHub - [`lynxize`](https://github.com/lynxize)
|
||||
|
||||
You can also reach me [through email](mailto:lynxize@gmail.com), though response times will definitely be slower.
|
||||
|
||||
|
|
|
@ -3,4 +3,8 @@ title = "Various Ramblings"
|
|||
sort_by = "date"
|
||||
template = "blog.html"
|
||||
page_template = "post.html"
|
||||
|
||||
generate_feeds = true
|
||||
+++
|
||||
|
||||
Some random blog posts/ramblings/text walls of mine.
|
277
content/blog/six-months.md
Normal file
|
@ -0,0 +1,277 @@
|
|||
+++
|
||||
title = "Game Progress Log - Six Months"
|
||||
date = 2025-04-18
|
||||
+++
|
||||
|
||||
{% important() %}
|
||||
This is more of a personal progress log than a blog post.
|
||||
I wrote it more for my future self than anyone else, though you're obviously welcome to read it if you want.
|
||||
{% end %}
|
||||
|
||||
|
||||
## Background
|
||||
Despite what I sometimes like to pretend, I'm not really a game dev.
|
||||
I've created and deleted my fair share of Godot and Unity projects, I've messed around with [libGDX](https://libgdx.com/), I've completed three game jams (with varying degrees of success)
|
||||
but I've never actually made anything I'd consider *finished*.
|
||||
I'm great at starting projects but terrible at completing them.
|
||||
|
||||
A little over a year ago, I tried following the [learnopengl](https://learnopengl.com/) tutorials, and had a lot of fun doing so.
|
||||
I got as far as a pig in a spotlight before bad design decisions and my inexperience with C++ caused the project to collapse under its own weight.
|
||||
|
||||
*Maybe in retrospect trying to learn graphics programming and C++ at the same time was not the best idea*...
|
||||
|
||||
{{ image(src="/assets/6months/pig.png", alt="Minecraft pig model drawn in front of a space-themed skybox", caption="piiiiiiiggggg") }}
|
||||
|
||||
Fast-forward to 8 or so months ago, and I finally thought up a game idea I thought was worth persuing.
|
||||
Something I could stay motivated to work on in the longer-term, and hopefully stick with long enough to complete.
|
||||
|
||||
I really want to love [Godot](https://godotengine.org/).
|
||||
It's my go-to choice for game jams, but once a project hits a certain size I can't figure out how to structure it.
|
||||
And I guess I just sort of got bored, or something.
|
||||
I made a little prototype, ran into some weird Godot limitation I no longer remember, and thought "hmm, what if I did this myself."
|
||||
|
||||
## Stuff
|
||||
So, for the last six months I've been working on a little game framework thingy in my free time.
|
||||
|
||||
[SDL3](https://libsdl.org)+[Kotlin](https://kotlinlang.org) is a bit of a cursed combination,
|
||||
but Kotlin is my current favorite language and I wasn't going to repeat the mistake of using a language I'm not comfortable with.
|
||||
|
||||
When I started, [LWJGL](https://github.com/LWJGL/lwjgl3) didn't have bindings for SDL (though [it does now](https://github.com/LWJGL/lwjgl3/pull/1033)) so it wasn't an option.
|
||||
[jextract](https://github.com/openjdk/jextract) works well enough for my purposes, since I was going to wrap most things in Kotlin anyway.
|
||||
|
||||
The first triangle was fairly straightforward.
|
||||
|
||||
{{ image(src="/assets/6months/triangle.png", alt="A window displaying a rainbow triangle", caption="hello triangle") }}
|
||||
|
||||
And I guess it just spiraled out of control from there. Instead of making a game I've been making a game framework.
|
||||
|
||||
I find the SDL GPU API (~~wow that's a lot of caps~~) to be a lot easier to reason about than OpenGL was.
|
||||
Trying to learn OpenGL was difficult because everything was State Soup and some totally unrelated code somewhere else
|
||||
would interfere with whatever I was trying to do, because I wasn't being careful enough.
|
||||
|
||||
At least with SDL I have some idea what's actually going on.
|
||||
|
||||
{% note() %}
|
||||
The lack of tutorials for SDL GPU was a little bit frustrating.
|
||||
Being extremely new, there's not much to go off other than [some examples](https://github.com/TheSpydog/SDL_gpu_examples/blob/main/Examples/ComputeSpriteBatch.c#L305)
|
||||
and the (actually fairly decent) [documentation](https://wiki.libsdl.org/SDL3/CategoryGPU).
|
||||
|
||||
Also, [RenderDoc](https://renderdoc.org/) my beloved...
|
||||
{% end %}
|
||||
|
||||
So let's see, after 6 months what have I got...
|
||||
|
||||
### Sprite Batching
|
||||
Most everything is based around a compute-shader based sprite batcher.
|
||||
It was loosely inspired by [this example](https://github.com/TheSpydog/SDL_gpu_examples/blob/main/Examples/ComputeSpriteBatch.c#L305).
|
||||
I don't have a great way to benchmark performance, but it handles tens of thousands of sprites with no problem on my laptop,
|
||||
so it's more than fast enough.
|
||||
|
||||
It does have the annoying limitation that all sprites must come from the same atlas texture, and it won't automatically batch sprites from a bunch of different ones.
|
||||
I should probably change that at some point.
|
||||
|
||||
### Box2D
|
||||
I didn't really want to write my own physics.
|
||||
Thanks to [Box2D](https://box2d.org/) 3.0+ being a C library, it was pretty easy to generate bindings for it.
|
||||
|
||||
Unfortunately there's now a `conversions.kt` file that looks like
|
||||
```kotlin
|
||||
internal fun AABB.b2AABB(arena: Arena): MemorySegment {
|
||||
val a = b2AABB.allocate(arena)
|
||||
b2AABB.lowerBound(a, this.min.b2Vec2(arena))
|
||||
b2AABB.upperBound(a, this.max.b2Vec2(arena))
|
||||
return a
|
||||
}
|
||||
```
|
||||
just to convert to and from Box2D's types, but eh, it's fine.
|
||||
I wrapped the callbacks with my own event system and it seems to be working well.
|
||||
|
||||
### Lighting Experiments
|
||||
I am *very* new to graphics programming, all things considered, and trying to implement [radiance cascades](https://radiance-cascades.com/) was probably ill-advised.
|
||||
|
||||
I did get some cool screenshots before I realized my game wouldn't even benefit from this kind of lighting in the first place.
|
||||
I probably could have figured it out if I'd spent a little more time, but I was getting bored.
|
||||
|
||||
{{ image(src="/assets/6months/idk.png", alt="Very broken scene", caption="yeah I don't even know lmao") }}
|
||||
|
||||
{{ image(src="/assets/6months/brokenrc.png", alt="Very broken scene", caption="significantly closer") }}
|
||||
|
||||
{% note() %}
|
||||
It wasn't helped by the fact that my test scene was almost entirely text and thin debug lines left over from messing with Box2D.
|
||||
Even a correct RC implementation would probably struggle with that.
|
||||
{% end %}
|
||||
|
||||
I might revisit this later. We'll see.
|
||||
|
||||
### 3D Experiments
|
||||
After so much 2D stuff I was getting a bit bored.
|
||||
My game is 2D, and there's no way I'll be writing a competent 3D engine, but I wanted to mess around a little.
|
||||
If I could draw the pig with OpenGL, maybe I could do something similar with what I'd built.
|
||||
|
||||
It went... about as well as could be expected.
|
||||
|
||||
{{ image(src="/assets/6months/brokenfox.png", alt="A fox with extremely broken textures", caption="biblically accurate fox or something idk") }}
|
||||
|
||||
I did eventually unbreak the fox and get a cubemap skybox mostly working.
|
||||
|
||||
It was pretty fun overall, even if not *useful*.
|
||||
I learned about [gamma correction](https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/)
|
||||
and some [neat tricks](https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/) for fullscreen render passes, so it wasn't a complete waste of time.
|
||||
|
||||
|
||||
### Audio
|
||||
I initially tried plugging an opus decoder more or less directly into an `SDL_AudioStream`, but it turns out that was a bad idea.
|
||||
So for now, I'm using [miniaudio](https://miniaud.io/).
|
||||
|
||||
{{ image(src="/assets/6months/audio.png", alt="debug ui for audio, with volume, pitch, and pan options", caption="little sound ui thing I made with Dear ImGui") }}
|
||||
|
||||
It supports basically everything I want to do anyway, like audio streaming, looping, pitch and pan modification, and more.
|
||||
|
||||
Getting it to compile was bit of a headache because it's not designed to be built as a shared library, but I don't exactly have any other option to use it from Kotlin.
|
||||
CMake makes me go insane...
|
||||
|
||||
{% note() %}
|
||||
I've been using stuff from [the FTL soundtrack](https://benprunty.bandcamp.com/album/ftl) and [ESCISM](https://radicaldreamland.bandcamp.com/album/escism-esc-original-soundtrack)
|
||||
as test tracks, which are therefore forever burned into my head. There are worse problems to have.
|
||||
{% end %}
|
||||
|
||||
### User Interface
|
||||
I know basically nothing about UI, and trying to research how other people handle it proved kind of useless.
|
||||
|
||||
"Just draw a bunch of textured rectangles! It's easy!"
|
||||
Yeah, okay, but where and what and why and aaaaaaaaa I don't even know.
|
||||
I was almost tempted to try to use [Dear ImGui](https://github.com/ocornut/imgui) for game UI, but the lack of theming made that impractical.
|
||||
|
||||
I figured drawing [9-slices](https://en.wikipedia.org/wiki/9-slice_scaling) would be a good place to start, using the sprite batch code I'd written earlier.
|
||||
|
||||
{{ image(src="/assets/6months/brokenui.png", alt="Extremely broken 9-slice drawing", caption="Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") }}
|
||||
|
||||
I decided to try to decouple the layout and the functionality a little, keeping the logic in Kotlin and the layout in [HOCON](https://en.wikipedia.org/wiki/JSON#HOCON).
|
||||
|
||||
Why HOCON? I don't know. The syntax is nice and [Hoplite](https://github.com/sksamuel/hoplite) provides nice error messages when I mess something up.
|
||||
|
||||
It looks like this:
|
||||
```js
|
||||
{
|
||||
// some stuff (theme declarations, etc.) omitted for brevity
|
||||
rootElement = {
|
||||
type: PaddingContainer
|
||||
padding: {
|
||||
left = 30f
|
||||
right = 30f
|
||||
top = 20f
|
||||
bottom = 20f
|
||||
}
|
||||
child = {
|
||||
type: HorizontalListContainer
|
||||
children = [
|
||||
{
|
||||
type: SizeConstraintContainer
|
||||
max_width = 100f,
|
||||
max_height = 100f,
|
||||
child = {
|
||||
type: NinePatchContainer
|
||||
id: "test-button-1"
|
||||
child = {
|
||||
type: Label
|
||||
font_size = 48f
|
||||
text = "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: SizeConstraintContainer
|
||||
max_width = 100f,
|
||||
max_height = 100f,
|
||||
child = {
|
||||
type: NinePatchContainer
|
||||
id: "test-button-2"
|
||||
child = {
|
||||
type: Label
|
||||
font_size = 48f
|
||||
text = "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are lots of other container types like `AlignmentContainer`, `ClippingContainer` and I'll probably need to add a few more,
|
||||
like `ScrollContainer`.
|
||||
|
||||
The Kotlin side looks like this, where the `ButtonBehavior` handles mouse presses and the hovered/pressed/released state.
|
||||
```kotlin
|
||||
val gui = Gui(Game.colorTarget, Core.gameDir.resolve("assets/test_ui.conf")).apply {
|
||||
addBehavior(getElementById("test-button-1"), ButtonBehavior().also {
|
||||
it.onMousePress += {
|
||||
println("Button 1!")
|
||||
}
|
||||
})
|
||||
|
||||
addBehavior(getElementById("test-button-2"), ButtonBehavior().also {
|
||||
it.onMousePress += {
|
||||
println("Button 2!")
|
||||
}
|
||||
})
|
||||
show()
|
||||
}
|
||||
```
|
||||
|
||||
I don't think this will scale particularly well, but my game is fairly UI-light so it should be Fineeee™ for now at least.
|
||||
It's significantly better than just spamming `Batch.draw()` a bunch.
|
||||
|
||||
I don't know how I'm going to handle more complex UI elements, like scroll bars and tab groups. HOCON makes it easy to include
|
||||
other files with `include required(file("/path/to/thing.conf"))` so maybe I could try to make some templates for things like that.
|
||||
|
||||
One of the hardest parts was dealing with `Batch`'s aforementioned everything-must-be-from-the-same-texture limitation.
|
||||
For now, I'm just generating a separate texture atlas for each UI at runtime, which doesn't feel great.
|
||||
|
||||
Text is handled through [SDL_ttf](https://github.com/libsdl-org/SDL_ttf)'s GPU text engine, which does most of the hard work with FreeType and HarfBuzz for me.
|
||||
All I have to do is keep track of different font styles.
|
||||
I tried using FreeType directly, and just about went insane on the spot.
|
||||
Text rendering [is not a rabbit hole I want to go down](https://faultlore.com/blah/text-hates-you/), and this is probably good enough
|
||||
for everything I'll want to do.
|
||||
|
||||
### Shader Hot-Reloading
|
||||
There's not much to say about it, other than that it works!
|
||||
It took too long to get the file watching working properly because Java's `WatchService` is a little weird.
|
||||
|
||||
In the future I want to be able to hot-reload textures, though that's a little harder because the texture atlases would have to be rebuilt.
|
||||
|
||||
### Misc
|
||||
There are some other things that I worked on that aren't really worth their own sections, like:
|
||||
- An overcomplicated asset management system
|
||||
- Remappable keybind handling
|
||||
- Most of a [glm](https://github.com/g-truc/glm)-esque math library from scratch
|
||||
|
||||
## The Future
|
||||
This is now my biggest project ever in terms of LoC, which is ...concerning? ...fun? I don't know. Let's go with [fun](https://dwarffortresswiki.org/Fun&redirect=no).
|
||||
|
||||
I'm sure any professional engine devs are... what's the equivalent of "rolling in their graves" for people who are still alive?
|
||||
Whatever. That. They're probably doing that.
|
||||
I don't really know what I'm doing, and I guarantee there are a bunch of horrible design decisions that will come back to bite me later.
|
||||
To be honest though, I don't really care. I'm having fun and learning a lot, which is what I set out to do.
|
||||
|
||||
Once I get a little further along, I want to make the core framework open-source.
|
||||
Not because I think anyone should use it, (please no, spare yourself) but because I wouldn't have gotten nearly this far without all the example code on the internet,
|
||||
and if my project can be of any help as a reference for someone else, I'd like that.
|
||||
|
||||
I've experimented with adding the [Fleks](https://github.com/Quillraven/Fleks) ecs (not to be confused with [flecs](https://github.com/SanderMertens/flecs)) and I've been very happy with the results so far.
|
||||
It seems like a good way to structure the game itself, though I'm not quite sure how to cleanly tie Box2D's physics in.
|
||||
|
||||
Here's some things I might work on soon:™
|
||||
- Shader caching? (probably not necessary, but might be fun to do)
|
||||
- Getting it running on Windows (90% done already, shouldn't be too hard)
|
||||
- Basic [i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization) maybe
|
||||
- Despaghettify the UI code
|
||||
- Figure out a name for this mess (I'm terrible at naming things)
|
||||
- **Start working on the actual game!**
|
||||
|
||||
That last one is the main thing. It's about time I stop messing around and start actually making my game.
|
||||
If I want to make the core framework better, I have to try using it, and see what walls I run into.
|
||||
I'm sure there will be plenty.
|
||||
|
||||
Anyway, that's it for now, see you in another six months!
|
15
content/blog/website-v3.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
+++
|
||||
title = "Another Redesign"
|
||||
date = 2025-04-17
|
||||
+++
|
||||
|
||||
I feel like I just did this [a few months ago](/blog/website-v2).
|
||||
|
||||
I didn't change as much this time, mostly just the CSS.
|
||||
Apparently I've become slightly obsessed with the color purple, so... yeah... the whole site is purple now.
|
||||
|
||||
Other changes:
|
||||
- Added the [random stuff page](/stuff).
|
||||
- Added some 88x31s to the home page, because why not?
|
||||
- Fixed the code block font and some other small things.
|
||||
- The [RSS (well, atom) feed](/blog/atom.xml) should finally work now.
|
BIN
static/assets/6months/audio.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
static/assets/6months/brokenfox.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
static/assets/6months/brokenrc.png
Normal file
After Width: | Height: | Size: 434 KiB |
BIN
static/assets/6months/brokenui.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/assets/6months/idk.png
Normal file
After Width: | Height: | Size: 684 KiB |
BIN
static/assets/6months/pig.png
Normal file
After Width: | Height: | Size: 241 KiB |
BIN
static/assets/6months/triangle.png
Normal file
After Width: | Height: | Size: 170 KiB |
BIN
static/assets/88x31/anythingbut.gif
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
static/assets/88x31/arch.png
Normal file
After Width: | Height: | Size: 535 B |
BIN
static/assets/88x31/catview.png
Normal file
After Width: | Height: | Size: 279 B |
9
static/assets/88x31/credits.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
yeah to be honest I have no idea where most of these come from
|
||||
I grabbed a few from aggregator pages like:
|
||||
https://cyber.dabamos.de/88x31/index.html
|
||||
https://www.88x31.nl/index.html
|
||||
https://capstasher.neocities.org/88x31collection-page1
|
||||
etc.
|
||||
|
||||
If you really care about proper attribution for every single 88x31, go find a better hobby/hyperfixation please.
|
||||
HOWEVER if you made one of them and want credit (or for me to remove it) just let me know!
|
BIN
static/assets/88x31/cssdif.gif
Normal file
After Width: | Height: | Size: 495 B |
BIN
static/assets/88x31/firefox.gif
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/assets/88x31/gnu-linux.gif
Normal file
After Width: | Height: | Size: 550 B |
BIN
static/assets/88x31/ieburnbtn.gif
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
static/assets/88x31/java.gif
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
static/assets/88x31/javascript-zero.gif
Normal file
After Width: | Height: | Size: 507 B |
BIN
static/assets/88x31/jellyfin.gif
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
static/assets/88x31/msoffice97.gif
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
static/assets/88x31/nocookie.gif
Normal file
After Width: | Height: | Size: 581 B |
BIN
static/assets/88x31/right2repair.gif
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
static/assets/88x31/sdl.gif
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
static/assets/88x31/squishstare.gif
Normal file
After Width: | Height: | Size: 403 B |
BIN
static/assets/88x31/steam.gif
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
static/assets/88x31/thunderbird.gif
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
static/assets/88x31/ublock.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
static/assets/88x31/webvirus.gif
Normal file
After Width: | Height: | Size: 998 B |
BIN
static/assets/88x31/wikipedia.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
|
@ -8,7 +8,8 @@ Not AI though, just me! :3
|
|||
|
||||
:root {
|
||||
--color-accent-1: #af8cff;
|
||||
--color-accent-2: #77aef2;
|
||||
--color-accent-2: #74cded;
|
||||
--color-links: #77aef2;
|
||||
|
||||
--color-note: var(--color-accent-1);
|
||||
--color-warning: #ed9a5f;
|
||||
|
@ -77,7 +78,7 @@ header {
|
|||
}
|
||||
|
||||
a:hover {
|
||||
|
||||
color: hsl(from var(--color) h s 30%);
|
||||
}
|
||||
|
||||
a {
|
||||
|
@ -120,12 +121,22 @@ footer {
|
|||
color: var(--color-accent-2)
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
code {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
/* Color only inline code blocks */
|
||||
code:not([class^=language-]) {
|
||||
color: var(--color-accent-2);
|
||||
}
|
||||
|
||||
a:link, a:visited {
|
||||
color: var(--color-links);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: hsl(from var(--color-accent-2) h s 85%);
|
||||
color: hsl(from var(--color-links) h s calc(l + 10));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,6 +161,13 @@ footer {
|
|||
background-color: hsl(from var(--color-important) h 35% 15%);
|
||||
}
|
||||
|
||||
#post-list {
|
||||
color: var(--color-accent-1);
|
||||
}
|
||||
|
||||
hr {
|
||||
color: var(--color-accent-1);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left-width: 4px;
|
||||
|
@ -172,7 +190,10 @@ figure {
|
|||
figcaption {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 5px auto;
|
||||
margin: 5px auto 20px;
|
||||
color: var(--color-accent-2);
|
||||
font-size: smaller;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
49
templates/atom.xml
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ lang }}">
|
||||
<title>{{ config.author }}</title>
|
||||
{%- if config.description %}
|
||||
<subtitle>{{ config.description }}</subtitle>
|
||||
{%- endif %}
|
||||
<link rel="self" type="application/atom+xml" href="{{ feed_url | safe }}"/>
|
||||
<link rel="alternate" type="text/html" href="
|
||||
{%- if section -%}
|
||||
{{ section.permalink | escape_xml | safe }}
|
||||
{%- else -%}
|
||||
{{ config.base_url | escape_xml | safe }}
|
||||
{%- endif -%}
|
||||
"/>
|
||||
<generator uri="https://www.getzola.org/">Zola</generator>
|
||||
<updated>{{ last_updated | date(format="%+") }}</updated>
|
||||
<id>{{ feed_url | safe }}</id>
|
||||
{%- for page in pages %}
|
||||
<entry xml:lang="{{ page.lang }}">
|
||||
<title>{{ page.title }}</title>
|
||||
<published>{{ page.date | date(format="%+") }}</published>
|
||||
<updated>{{ page.updated | default(value=page.date) | date(format="%+") }}</updated>
|
||||
{% for author in page.authors %}
|
||||
<author>
|
||||
<name>
|
||||
{{ author }}
|
||||
</name>
|
||||
</author>
|
||||
{% else %}
|
||||
<author>
|
||||
<name>
|
||||
{%- if config.author -%}
|
||||
{{ config.author }}
|
||||
{%- else -%}
|
||||
Unknown
|
||||
{%- endif -%}
|
||||
</name>
|
||||
</author>
|
||||
{% endfor %}
|
||||
<link rel="alternate" type="text/html" href="{{ page.permalink | safe }}"/>
|
||||
<id>{{ page.permalink | safe }}</id>
|
||||
{% if page.summary %}
|
||||
<summary type="html">{{ page.summary }}</summary>
|
||||
{% else %}
|
||||
<content type="html" xml:base="{{ page.permalink | escape_xml | safe }}">{{ page.content }}</content>
|
||||
{% endif %}
|
||||
</entry>
|
||||
{%- endfor %}
|
||||
</feed>
|
|
@ -20,6 +20,7 @@
|
|||
<a href="/blog">blog</a>
|
||||
<a href="/stuff">stuff</a>
|
||||
</nav>
|
||||
<link rel="alternate" type="application/atom+xml" title="RSS" href="/blog/atom.xml">
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
<h1 class="title">
|
||||
{{ section.title }}
|
||||
</h1>
|
||||
<ul>
|
||||
{{ section.content | safe }}
|
||||
<ul id="post-list">
|
||||
{% for page in section.pages %}
|
||||
<li>{{ page.date }} <a href="{{ page.permalink | safe }}">{{ page.title }}</a></li>
|
||||
<li>{{ page.date }} - <a href="{{ page.permalink | safe }}">{{ page.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock content %}
|
|
@ -3,15 +3,44 @@
|
|||
{% block content %}
|
||||
|
||||
<br>
|
||||
Hey! You found my little personal page!
|
||||
|
||||
I'm a professional waster of time, purveyor of useless activities, and chronic avoider of productivity.
|
||||
Hey!
|
||||
<br>
|
||||
You found my little personal page!
|
||||
<br>
|
||||
<br>
|
||||
I'm an expert waster of time, enjoyer of useless activities, and chronic avoider of productivity.
|
||||
<!-- br brr brrrrr (bad) -->
|
||||
<br>
|
||||
<br>
|
||||
I also sometimes write bad code for fun and play games.
|
||||
<br>
|
||||
<br>
|
||||
<a href="/about">More about me</a>.
|
||||
|
||||
<br>
|
||||
<br>
|
||||
Since I don't know what else to put here and have to fill the space somehow, here's an 88x31 dumping ground, because why not?
|
||||
<br>
|
||||
<hr>
|
||||
<div>
|
||||
<img src="/assets/88x31/catview.png">
|
||||
<img src="/assets/88x31/gnu-linux.gif">
|
||||
<img src="/assets/88x31/ieburnbtn.gif">
|
||||
<img src="/assets/88x31/javascript-zero.gif">
|
||||
<img src="/assets/88x31/cssdif.gif">
|
||||
<a href="https://catsta.red"><img src="/assets/88x31/squishstare.gif"></a>
|
||||
<img src="/assets/88x31/msoffice97.gif">
|
||||
<a href="https://www.thunderbird.net/"><img src="/assets/88x31/thunderbird.gif"></a>
|
||||
<a href="https://archlinux.org/"><img src="/assets/88x31/arch.png"></a>
|
||||
<a href="https://jellyfin.org/"><img src="/assets/88x31/jellyfin.gif"></a>
|
||||
<img src="/assets/88x31/right2repair.gif">
|
||||
<a href="https://wikipedia.org"><img src="/assets/88x31/wikipedia.png"></a>
|
||||
<a href="https://www.libsdl.org/"><img src="/assets/88x31/sdl.gif"></a>
|
||||
<a href="https://librewolf.net/"><img src="/assets/88x31/anythingbut.gif"></a>
|
||||
<img src="/assets/88x31/nocookie.gif">
|
||||
<a href="https://www.youtube.com/watch?v=cErgMJSgpv0"><img src="/assets/88x31/webvirus.gif"></a>
|
||||
<a href="https://librewolf.net/"><img src="/assets/88x31/firefox.gif"></a>
|
||||
<a href="https://adoptium.net/"><img src="/assets/88x31/java.gif"></a>
|
||||
<a href="https://store.steampowered.com/"><img src="/assets/88x31/steam.gif"></a>
|
||||
<a href="https://ublockorigin.com"><img src="/assets/88x31/ublock.png"></a>
|
||||
</div>
|
||||
<p style="font-size: x-small">(If one of these is yours and you want credit, let me know. I just found them Wherever™)</p>
|
||||
<hr>
|
||||
{% endblock content %}
|