Friday, May 30, 2025

A City with Mountains on All Sides

The cities have always been my home. Accessible. Loud. Crowded. A little dirty. I worked there, shopped there, wandered late-night corners and coffee shops with bad lighting and good music. And I loved it.

But somewhere in the middle of all that, I learned to love something more. Something quieter.

Chattanooga had that special blend — a city, yes, but one with mountains on every horizon and ridgelines that whispered to you if you were paying attention. You could finish your shift and be at the river’s edge twenty minutes later. You could spend a weekend in a bookstore and the next in a gorge. It made space for both.

There were nooks and secret crannies scattered all over. The kind of places with no signs. No parking lots. Just a slight thinning of the trees — a hint that someone had been there before you, and you were invited to follow.



One of my favorite places to visit was a secret: just two car-sized dirt pull-offs on the side of a mountain ridge. No trail marker. No name. If you knew where to look, you'd find an overgrown path that some stranger had beaten down years ago. It led to a rope tied to a solid oak, hanging over a fifteen-foot drop. Not exactly welcoming — but reliable.

If you trusted the rope and made your way down, a stream waited at the bottom. No trail followed it. But if you hiked far enough — through three miles of fern-bottomed forest — you'd find a waterfall. No name. No sign. No map. Just mist. Just quiet.

I never took pictures. I only shared it once — passed down from a friend who trusted me with it, and whom I trusted in return. It was a sanctuary. And in a way, I think it still is.

That place is out of reach now. Life changes. Jobs move. Roads bend. But a part of me is still there — still standing in the cold stream, still watching the light filter through leaves older than I’ll ever be.

These are some photos from around that time. Not of the secret place — that’s still sacred — but of the quiets that taught me how to pay attention.


There are places that don’t leave you. They just wait — quietly — for you to remember.


 Until next time, stay warm and toasty.

Monday, May 26, 2025

Tin Lover

 


Some poems come out raw.
Some you carry for years before you find the right words.

This one lived in me a long time.

It’s about loving someone through the fog — through heaviness, through ache — and never letting go of the gold that still shines within.

This is Tin Lover.


My love, by wayside, beset by stars,
a space between to steal what’s ours.
Apart, for now, and out of reach,
across a space I’ll never breach -

for wanton promise of things to come
of turning weather and thunder’s thrum -

she’s wrapped in sheets of paper smocks
to weather storms and breaking rocks
to hide from words that cut and bleed
while stitching wounds with garden weeds

and raking dirt across her skin
she hides the gold that gleams within
and inside this gown, this coat of dust
she lets her veins carouse with rust.

Oh here afar across the twain
forced to watch her as she wanes
where lacing sun rays seldom trace
will rarely dance across her face -

within those moments
she may betray
the gold that lives
beneath the grey.

my dear tin lover, she fights this mold
struggles dearly to break its hold,
of stars beset upon her skin
infecting joy to rot within.

Oh how this span does seem our fate
 - It hopes to wither love with hate,
but we shall wait upon those sunlit seconds
to glimpse the gold that ever beckons,

and within those moments,
that space in time,
I’ll see your love,

And you’ll see mine.
 

Sunday, May 18, 2025

Third Spaces, First Loves

There’s something about walking into a coffee shop that feels like stepping sideways out of time.

Maybe it’s the quiet hum of conversation, or the way the scent of freshly ground beans hits you just before the door swings shut. Maybe it’s the chipped mugs behind the bar or the fact that the barista remembers your name — and maybe even your story.

I’ve spent a lot of my life in coffee shops. I worked in them through my teens and early twenties — chain spots, local joints, third-wave dreams. I still stop into one almost every day, even if it’s just for a quick hello and a warm cup. But it’s never really just about the coffee.

Coffee shops were where I grew up — not from a kid into an adult exactly, but from someone going through the motions into someone more aware. Of people. Of ideas. Of myself.

There’s something quietly transformative about being behind the counter — learning to make drinks, yes, but also learning to listen. Learning to ask better questions. I remember those early evenings, the shop glowing softly in warm light as I practiced on the espresso machine. Everything slowed down. I’d sip on my own coffee and dig into the why of the process. The smell of fresh grounds, the hiss of steam — it felt sacred. I can’t reproduce that feeling to this day.

And over time, something subtle and profound happened: the shop became more than a workplace. It became a portal. A place where life cracked open.

I was raised in deeply conservative communities, where the world was small, the rules were clear, and being “different” often meant being feared, or worse, erased. It wasn’t cruelty, exactly — just a kind of handed-down certainty. A worldview that didn’t leave a lot of room for complexity, or curiosity, or deviation from the script.

But in coffee shops, I met people who shattered those scripts.

One of my coworkers, Travis, came in one morning still shaken — his father had screamed hateful things at him that day for being gay, for being different. He bawled before his shift, spent the day trying to keep himself together behind the bar. That moment burned into me. It was so raw, so human. And it revealed something I hadn’t let myself believe before: that the people I was taught to fear were just… people. Hurting, striving, beautiful people.

And then there was Hannah — vibrant, honest, unapologetically herself in every way. She didn’t wear a mask. She didn’t flinch when she talked about hard things. Her self-reflection and groundedness made me feel like I was living behind glass — like maybe I was a little scared to be known. She helped change that.

These weren’t sermons. They were conversations over clinking mugs and shared shifts. And they shaped me more than years of schooling ever did.

I even met my wife through coffee shop conversations. And I’ve made real friendships — people like Taylor, who remembered small details and always made time to ask how I actually was. I’ve had customers I thought I’d only speak to once come back weeks later and re-engage like we’d known each other forever. I’ve even been offered jobs, just sitting and talking at café tables.

Coffee shops hold space like that. They’re not home, and they’re not work, but they’re still ours. These third places are the quiet, public corners of the world where you can belong without needing to perform — where you can show up with a laptop, or a book, or just a heavy heart. And no one asks you to be anything but present.

That kind of space — where you’re allowed to be instead of do — it’s rare. And so, so needed.

Because third spaces don’t just give us rest. They give us the chance to grow. To change. To hear something unexpected, meet someone new, or glimpse a version of ourselves we didn’t know we were allowed to be.

It might sound lofty, but it’s true.


I think often of cafés in 18th-century France — how they became spaces for writers, philosophers, musicians to gather. Not because of some grand plan, but because the coffee shop was the place that welcomed them. Public houses full of voices. I’m no Robespierre (thank God), but I have had those conversations. The ones that reframe your understanding of the world — or of yourself. That spirit still lives on in good cafés today.


Some of the most meaningful conversations I’ve ever had happened over mugs of coffee. Some of the most surprising friendships. Some of the quietest healing.

There’s a kind of magic in that space. And that’s the kind of magic I dream of creating one day.

I still hold onto a silly little poem I wrote once, sitting in a shop during the quiet early hours. It starts like this:


"deep within the murky depths / of caffeine induced epitaphs…

cups clink and orders spoke / an entire world not yet awoke…

grab a seat / grab a cup / take a sip / grab another cup."


One day — maybe when the timing is right — I’d love to open my own place. A space called Whitecap Coffee. A place with chipped mugs and soft light. Where people feel safe, and seen, and maybe even transformed. A place where the coffee is good, but the possibility is better.


Because the world could always use one more coffee shop —

especially the kind that reminds you who you are.


 Until next time,

 Stay warm and toasty.

Thursday, May 8, 2025

How I Accidentally Built a Homelab - Part 1

First it’s “what’s Kubernetes?” and next thing you know, you’re 3D printing magnetically latched airflow panels for a custom rack build with PoE-fed Pis and a GPU-class server tucked into 12U.

 It started, as these things often do, with a question.

 

“What is Kubernetes?”


Innocent enough. I was curious about how containers scaled across systems, how people ran services in their own homes, and what it would take to dip a toe into infrastructure I could learn from hands-on. The answer — or what should have been a Wikipedia article and a weekend project — spiraled into something else entirely.

Today, I’m building a 12U white-out mini rack that hosts:

  •     A Minisforum Ryzen 9-powered NAS with 64GB of RAM
  •     A 6-bay SSD RAID array
  •     A full Ubiquiti network stack
  •     A Kubernetes cluster running across four Pi 5s with NVMe storage

    And an increasingly ridiculous number of 3D-printed panels, mesh filters, and magnetic faceplates I designed in Tinkercad.

It escalated quickly.

Why a Rack?

Another PC tower didn't suit my goals. I didn’t want loose cables running across a desk. I didn’t want a Pi cluster zip-tied to a shelf like a tech goblin. 

I wanted something compact, clean, and modular. Something that would grow with me.

Enter: the RackMate T2, a 12U 10-inch mini rack case that caught my attention while watching through a Jeff Geerling video. Just small enough to be reasonable. Just big enough to be dangerous.  With it, I could bring together networking, compute, storage, and a dedicated space to tinker without sprawl.

The Rackmate T2, featuring 12 units of space, just over 2 feet tall.

 

The Vision

I had a few key goals going into this:
  •     Quiet operation — nothing louder than a gentle fan hum
  •     Low power draw — something I could leave running 24/7 without guilt
  •     Room to experiment — containers, ZFS, Kubernetes, media, dev work, all of it
  •     Total control — no cloud dependency, no vendor lock-in
But it also had to look good. Not flashy, just intentional. I wanted clean lines, tidy cables, white PLA panels, and magnetic filters — something subtle and satisfying to build.

I planned out my goals for the rack:


 

Needless to say, I got pretty invested. I started planning first - a spreadsheet of parts, sizes, prices and links. I spent hours trawling through the GitHub page for Project Mini Rack (or the more readable webpage version) taking notes on other builds and slightly dreading having finally commit to learning how to do some 3D modeling for the sake of the customization I knew I wanted. Thankfully, I've got a friend with a printer available to me (though I did seriously consider buying one for this project).

So the spreadsheet - I broke it up into 4 parts: The Rack and Networking Gear, the Kubernetes cluster, the Server, and the NAS.

The sheet got long enough that I couldn't capture the full list.

 

Each section went through countless adjustments as I discovered new parts or solutions that would fit the build. I considered building my own case several times, scrapping the Kubernetes cluster, tossing out my ITX server plans and just re-using my current device (which is on its last legs), and the NAS went through almost a dozen different iterations of plans. 

I was constantly thinking "Should I go with HDD's or SSD's?" "Which parts can I replace to increase power efficiency?" "Should I keep a GPU on the ITX board in the server for video encoding? Or can I use an Intel CPU for encoding? Can AMD do that now?"

The back and forth gave me whiplash. But now it's all ironed out and I've committed! Probably.

I've drawn up a general plan for the placement of the equipment in the rack:

 

2U's of space left over!


3D Modeling

After looking at the price of panels for the Rackmate T2 I decided that I had to go ahead and commit myself to some 3D modeling if I was going to achieve an aesthetic that I was comfortable with being visible in my home. So, I researched some software and dove into Autodesk Fusion360's...

..and was immediately overwhelmed. 

Rather than do the reasonable thing and watch some videos on how to get started, I jumped ship over to their baby CAD: TinkerCAD. A browser based solution for learning the basics. From there I drew up a 1U panel for the server rack:

I thought it was a decent start! There were plenty of models out there for the 1U panel though, so this was just a learning experience for me to get used to the dimensional tools of the software.

I took the 1U panel over to a new project to start making the first custom panel that I was interested in: a dust filtering 3 fan panel for air intake in the rack. I went through several iterations of this model.



This was a learning experience! The first print out made it obvious that the model was too thin to support three fans:

So I made the panels a millimeter thicker on each side and added a bracing support each side that would also act as a shelf for the panels to rest on. My plan to adhere them together is some magnets in these slots:

 

I'll have to give you an update on whether or not that works! Between the movement and the weight of the fans - I may need a different solution. There should be plenty of room for 3x40 mm fans. Here's the new version with a piece of paper sandwiched between the panels as an example of where the dust filter will live:
 


This version will also need some very slight tolerance adjustments. Version 3 will be printed in a white PLA, when it arrives.

Where It’s Going

At the time of writing this, I’ve:

  • Committed to the RackMate T2

  • Ordered the Ubiquiti switch, gateway, and the Arris modem

  • Designed and printed a custom honeycomb 1U fan panel that sandwiches a mesh screen between two magnet-held layers

  • Pivoted away from traditional Mini-ITX builds in favor of a Minisforum BD795i SE for its size and performance

  • And begun building out the dream: a full-featured homelab that fits in a rack I can actually live with.

This blog is where I’ll document the process — design choices, print files, wiring strategies, thermal wins, and occasional mistakes. Because if I’m going to go overboard, I may as well leave a map for the next person who asks, “Hey… what’s Kubernetes?”

Until next time,

Stay warm and toasty.

Tuesday, April 22, 2025

Down the Raspberry Pi Rabbit Hole

The world of microcomputers like the Raspberry Pi or the ESP32 is broad and ever-expanding. I've only had the chance to work with an original Raspberry Pi way back in school, and I just began a small project with an ESP32 today (more on that to come). Needless to say, my experience is limited. But last year, I was presented with a challenge at work: get a video stream from a Ubiquiti security camera to display on a Raspberry Pi so we could monitor part of the store. An update had broken the functionality of their previous setup, and now it was on me to fix it.

So why not just use a Viewport?

Viewport is Ubiquiti’s all-in-one camera monitoring hub. It’s plug-and-play, purpose-built for their surveillance systems, and ideal for monitoring multiple streams with ease.

But the downside? The price tag: $200. Compare that to “free” (minus my many hours of labor, which probably exceeded $200, but hey). We already had the Raspberry Pi—may as well use it, right?

My first objective was to investigate the previous setup and figure out what broke.

The device ran RPIsurv, a neat little program that turned a Raspberry Pi into a dedicated video or image streaming device. It could display up to four separate streams at once. The video output ran through omxplayer, which—surprise—had been deprecated in the update that broke the setup.

Enter VLC, the new video king on Raspberry Pi.

I wasn’t upset to discover that VLC checks all the boxes: versatile, open-source, widely supported, and capable of handling nearly any media format. Unsurprisingly, VLC supports the same media stream format used by many live video feeds: RTSP (Real-Time Streaming Protocol).

My mission was now clear: use VLC to stream the camera feed.

Simple, right? Hah.

The Hacky Solution

I should mention—I did all this on Raspberry Pi OS (with Desktop), not Lite as I probably should have. (More on that later.)

I started by grabbing the RTSP link from the camera’s settings in the UniFi dashboard. But something looked off:

rtsps://192.168.1.1:7441/example_stream_id?enableSrtp

RTSPS? That wasn’t going to work. I tried anyway. No dice—stream error.

After a bit of digging, I learned that a few key changes were needed to make the link work. This was likely obfuscated for security reasons (or just to make my life harder). Either way, I’m just a dude playing with tech at the mercy of its creators.

Here’s what I had to change:

  1. Change rtsps to rtsp
  2. Change the port from 7441 to 7447  
  3. Remove ?enableSrtp

A couple of quick edits, and—voilà! VLC successfully streamed the live camera feed.

Cue self-congratulations, back-patting, and a well-earned lunch.

Except... when I got back, the stream had died.

Crashing Streams & Band-Aids

I rebooted VLC to make sure it wasn’t a fluke. It worked, but not for long. Turns out, VLC isn’t built for 24/7 streaming. Over time, memory leaks or resource exhaustion cause it to crash or hang. You can tweak VLC’s buffer settings or enable keep-alive packets, but even with those adjustments, the stream still crashed every few hours.

If you need to tweak those settings, they’re here:

  • Caching: Tools > Preferences > Show Settings (All) > Input/Codecs > Network Caching (ms) > Increase to 3000ms or more.
  • Keep-Alive: Preferences > All > Input/Codecs > Demuxers > RTP/RTSP > Enable "Use RTP over RTSP (TCP)" and set keep-alive.

Neither helped.

So I asked myself: why not just reboot VLC?

It wasn’t pretty, but the stream didn’t need elegance. It just needed to work most of the time.

The Auto-Reboot Workaround

(Before you recreate this solution, just know—it’s hacky and lame. There’s a better one below.)

First, VLC setup:

  1. Tools > Preferences > Check "Fullscreen"
  2. Audio > Uncheck "Enable Audio" (especially important for two-party consent states)
  3. Input/Codecs > Demuxers > RTP/RTSP > Enable "Use RTP over RTSP (TCP)"

Then, I made sure the stream restarted on boot:

  1. Navigate to /home/username/.config
  2. Create a folder named autostart
  3. In autostart, create a file called autovlc.desktop with the following:
[Desktop Entry]
Type=Application
Exec=vlc rtsp://192.168.0.1:7447/streamlink

Reboot to confirm it worked.

Now, to handle VLC crashing, I wrote a script to kill and relaunch it:

On the desktop, create close-launch-vlc.sh:

#!/bin/sh
killall vlc
wait
gio launch /home/username/.config/autostart/autovlc.desktop

Then, in the terminal, make it executable :

chmod +x /home/username/Desktop/close-launch-vlc.sh

To automate this script every two hours, I used cron. First I had to check the display number:

echo $DISPLAY

For me, it was "0", then I opened up crontab:

sudo nano /etc/crontab

At the top:

DISPLAY=:0

At the bottom:

0 */2 * * * username /home/username/Desktop/close-launch-vlc.sh

Save and exit. Now, the stream rebooted every two hours.

It wasn’t ideal, but it kept the stream alive.

The Actual Fix

Until it didn’t.

The guy sitting near the monitor got tired of fullscreen hangs and reboot hiccups. He demanded a real fix.

Fine. Fine.

So, I decided that Raspberry Pi Desktop was too resource heavy for the little 1GB Raspberry Pi 3 that I was building this on. I installed the lite version and SSH'd into the thing. VLC wasn't ideal for this purpose. I tried a few other options.

My fiddling led to the RPi refusing to boot twice, one accidental reboot when I ran the reboot command in my own laptop's terminal instead of within the SSH session, and lots of cursing. Several attempts with several tools later, I landed on ffplay

After a lot of trial and error (I'm not much of a scripter to be honest) this is the code block I ended up with:

#!/bin/bash

# === 1. Update system ===
sudo apt update && sudo apt upgrade -y

# === 2. Force HDMI output & resolution ===
sudo sed -i '/^#*hdmi_force_hotplug/d' /boot/firmware/config.txt
sudo sed -i '/^#*hdmi_group/d' /boot/firmware/config.txt
sudo sed -i '/^#*hdmi_mode/d' /boot/firmware/config.txt
sudo sed -i '/^#*config_hdmi_boost/d' /boot/firmware/config.txt

echo "hdmi_force_hotplug=1" | sudo tee -a /boot/firmware/config.txt
echo "hdmi_group=1" | sudo tee -a /boot/firmware/config.txt
echo "hdmi_mode=82" | sudo tee -a /boot/firmware/config.txt   # 1080p
echo "config_hdmi_boost=7" | sudo tee -a /boot/firmware/config.txt

# === 3. Install lightweight X server and ffmpeg ===
sudo apt install --no-install-recommends xserver-xorg xinit openbox ffmpeg -y

# === 4. Create .xinitrc with placeholder RTSP stream ===
cat <<EOF > ~/.xinitrc
#!/bin/bash

# Replace the RTSP_URL below with your own stream.
RTSP_URL="rtsp://YOUR_CAMERA_URL_HERE"

if [[ "\$RTSP_URL" == "rtsp://YOUR_CAMERA_URL_HERE" ]]; then
  echo "❌ Please edit ~/.xinitrc and set your RTSP stream URL before using startx."
  sleep 5
  exit 1
fi

ffplay -fs -noborder -an -fflags nobuffer -flags low_delay "\$RTSP_URL" > ~/ffplay.log 2>&1
EOF

chmod +x ~/.xinitrc

# === 5. Enable console auto-login ===
sudo raspi-config nonint do_boot_behaviour B2

# === 6. Add startx to bashrc only for TTY1 ===
if ! grep -q 'startx' ~/.bashrc; then
  echo '' >> ~/.bashrc
  echo 'if [ "\$(tty)" = "/dev/tty1" ]; then' >> ~/.bashrc
  echo '  startx' >> ~/.bashrc
  echo 'fi' >> ~/.bashrc
fi

echo ""
echo "✅ Setup complete!"
echo "👉 To finish setup, edit ~/.xinitrc and paste in your RTSP stream URL."
echo ""
echo "Rebooting in 5 seconds..."
sleep 5
sudo reboot

 The script can be found over on my github. The beauty of this is that its one command to replicate it now. It just requires entering in the RTSP stream.

It took some learning and fiddling, but the stream is now up 24/7 without the need for reboots or hangups. Plug and play. Without the hackiness.

If you're interested, I used a few different videos while learning how to set this up: Eugene Tkachenko sets up a stream using a camera module directly on the Raspberry Pi itself. That Project created a wireless camera very similarly to Eugene, but had some code snippets in his video that I found very useful.

A Raspberry Pi and other Internet of Things devices are powerful tools, when in the right hands. It took a while for my hands to be the right ones here. 

I've got some more projects with IoT devices coming up, one focused on my love of Pokemon, of all things! 

Until then.

Stay warm and toasty.

 

Monday, March 31, 2025

D20 Tavern Game, Some Progress

To Manage A Tavern

One of the first big challenges I’ve run into as a first-time game designer is figuring out how to actually hold a player’s attention—not just for a few minutes, but for an entire playthrough.

It turns out, just having a story, mechanics, or a setting isn’t enough by itself. They all need to be blended together, and that blend needs to have a little bit of sugar on top: incentives.

So I started sketching out a basic gameplay loop:

  1. Introduce the story and initial goals.

  2. Engage the player with mini-game challenges.

  3. Reward the player with immediate incentives.

  4. Let them spend those rewards on upgrades.

  5. Pay off with story beats and introduce new goals.

  6. Repeat (but with more depth each time).

Simple? Hopefully. Effective? That’s the goal.

Environmental interactions shouldn't just be simple button presses. Filling a beer shouldn't be automatic—it should require the player to stop the pour at the right time to avoid overflowing. Sliding a drink down the bar to a patron could give extra flair (and bonus rewards). Lighting the tavern hearth? Why not make it a chance for the player to pull off a flourish, like a little fire-spinning trick?

 

Worldbuilding Needs More Than Fantasy Wallpaper

It's not enough to slap the word “fantasy” on a tavern and call it a day. Dwarves, elves, and barbarians shouldn't just look the part—they should act the part.

Dwarves should:

  • Challenge you to drinking contests.

  • Pay you with gemstones when they like you.

  • Maybe leave a mess every time they visit.

Elves should:

  • Prefer natural surroundings.

  • Sing hypnotically when content.

Barbarians should:

  • Challenge patrons to strength contests.

  • Laugh raucously and cause a scene.

Rogues should:

  • Gamble.

  • Pull tricks on other patrons (or even the bartender).

Both race and class should influence how patrons behave, what they like, and how they react to your tavern's decor and service.

The Dice Roll System

So how does this all tie into gameplay? I'm leaning into the good old D20 system.

Every patron will roll a d20 to determine how much they pay and how satisfied they are. The catch? Their roll will be influenced by the environment and your actions.

Example:

The dwarf dislikes the soft bar stools (-1), but appreciates the stone walls (+1), a strong drink (+1), a hearty stew (+1), and the roaring hearth (+1). That's a +2 bonus.

If he rolls a 9 on the die, it becomes an 11 after modifiers. Not amazing, but enough for acceptable service. He leaves the normal pay, no tip, and a nice little spill on the bar from slamming his mug.


Things I'm Still Considering:

  • Should there be sections for each type of clientele?
    A sunlit room with living wood walls for elves and druids? A moody stone hearth area for dwarves and rogues?

  • If you make a world-changing choice (like accidentally turning your regulars into undead by enabling a necromancer), should that be permanent, or could you eventually reverse it?

  • Should wealth progression phase out poorer patrons, or should they still show up even when nobles and kings start visiting? Maybe your choices decide—help the poor, or become the snob who bans peasants from the fancy tavern? I’m not judging.

For now, we've got a solid foundation, even if there are still some big choices left to make. I've been working on animations and art (trying very hard not to restart everything just to make bigger sprites, but I’m tempted). If ConcernedApe could make it work with small sprites, so can I.

Until next time,
Stay warm and toasty.

 

A City with Mountains on All Sides

The cities have always been my home. Accessible. Loud. Crowded. A little dirty. I worked there, shopped there, wandered late-night corners a...