Devlog
Building in the open. Code, screw-ups, and some nerdy notes on the Linux machines I like building on. Click a day to read it.
Day 13 June 16, 2026 — dressing the road, houses in, UI locked
what I built
- Tracked down a stray ColorRect that was parented under the Truck and rendering as a bright bar across the scene. It moved with the truck because it was a child of it. Deleted it. The truck's actual visual is the Sprite2D underneath.
- Sorted the road laning for real: truck drives the right lane (x=0), yellow center line to its left, curb and houses on its right where the stops live, which is the side a garbage truck actually services.
- Finished dressing the road for all six built stops so the truck drives a continuous route with no gaps.
- Placed Luiz's house variants along the right side behind the sidewalk, scattered with some irregularity so it doesn't read as a repeating wall.
- Did a UI pass and called it. Left the portrait and text block where they are, it's in a good spot.
what I learned
- A node parented to the truck travels with the truck. Obvious in hindsight, but it's why that bar tracked the movement and looked like it belonged to the world when it didn't.
- "Truck at x=0" doesn't force a symmetric road. You paint more tiles on one side of the line than the other, so x=0 lands in the right lane while the road stays believable around it.
- Knowing when to stop. The UI was good enough to move on from, and the road only needs to serve the six stops that exist, not the whole eventual route.
what's next
- Trash bins at the curb as the visual cue for each pickup point (need to confirm the bin sprite first)
- Headlight/lighting pass over the dressed road
- Keep building stops past 6
how it felt
Good kind of session. Most of it was the unglamorous stuff, hunting a leftover node and painting tiles, but the scene finally reads as a place instead of a truck floating on black. The composition works now. That's the payoff for the boring work.
Day 12 June 11, 2026 — art assets, the camera (again)
Tonight was about getting the art assets in. First, though, the camera broke again — it wasn't following the truck. Dropped a print statement in to see what the camera and the truck were actually doing, and it turned out they'd matched the whole time: truck at zero, camera at zero. So it was never the camera. The sprite had drifted off on its own. Pulled it back, fixed.
Then I started painting the road and sidewalk in the editor. The truck's in the right lane, since that's the side a garbage truck actually works, with the sidewalk on the right where the stops will go. Coming along. Headlights next.
Day 11 June 6, 2026 — first full stop, end to end
what I built
Finally got one full stop built end to end. The bags stop, Stop 1, and I think it's close to final. The whole loop works now: drive up, the scene pops, investigate through the pages, then the choices come up and you pick one and it shows you what happened. Took a lot of back and forth to get there, but it actually plays now instead of just sitting in a doc. Also did a real pass on the prose for the stops, which is turning into the fun part.
what I learned
Spent most of the last couple days learning GDScript instead of building, and it was worth it. I'm a lot more comfortable writing the code now and actually knowing what things do instead of just pasting and hoping. Learned the difference between a variable and a parameter, what the dot actually means when you reach into another node, why node names and variable names are different things, and how to read an error instead of panicking at it. Fixed a few of my own bugs this session just by reading what the error was telling me, which felt different than before.
what's next
Twelve more stops to build out. The system works, so now it's mostly filling in each stop's writing and giving every one the same pass I gave the bags. Sound, the ending system, and the lighting all come later once the stops are in.
how it felt
Good. Slower than I wanted, but the kind of slow that pays off. Watching a stop I'd only ever read on a page actually run in the dark felt like the first time this thing has been a real game and not just notes. The prose is getting fun to write, which I didn't expect. Feeling more like a developer and less like someone copying a developer.
Day 10 June 1, 2026 — the third verb
what I built
- Rebuilding stops with new mechanics. I have a clearer vision now of what to make the game.
- Added a third verb, stop-specific, that either rewards or hurts the player: a deeper investigation into each stop.
what I learned
- I was right that the game was missing something. It was missing that third verb option to delve deeper into the stops.
- This isn't a game someone sinks 10 or even 5 hours into. It's a quick 1-2 hour run that's fun and gets you Steam achievements.
what's next
- Finish auditing the tells on Stops 3-6
- Build the consequence systems (headlight dimming is cheapest and most fitting, start there)
- Need more COMPLETE/leave stops; right now the split is lopsided toward log
- Playtest on a real person
how it felt
Felt good. What's in my mind is concrete right now, and I think this will be the fully shipped game idea. I have to remember, this is my first game. It's not going to be a masterpiece and it doesn't need to be.
Day 09 May 31, 2026 — the rule that makes the choices mean something
what I built
- Finished the complete testable slice last session (6 stops, drive → investigate → log/leave → clock-out ending). This session was mostly design and writing.
- Locked the core rule that decides whether log or leave is correct at each stop
- Re-audited Stops 1 and 2 so the rule is actually readable in the text
- Added the truck sprite (placeholder) and recorded a sneak-peek clip with sound
- Wrote the Steam store blurb
the rule (finally)
The thing I'd been circling for a while: the choices needed a logic the player could actually learn, or it's just a coin flip with a death screen. Got it.
Every stop is either COMPLETE or UNFINISHED.
- Complete: it's at peace, nothing missing, it wants nothing. Leave it. Logging it disturbs a stable thing.
- Unfinished: it's still reaching for something. Log it to freeze it where it is. Leave it and it goes and completes itself, and the cost lands on someone.
The skill is reading which one you're looking at. The tell is in the text, stated as flatly as everything else, so a careful reader catches it and a careless one doesn't. Solvable, but you'll get a couple wrong, which is the point.
consequences
Mostly you don't die. Wrong calls degrade the night instead: headlights shrink, the route stops making sense, things you mishandled come back changed. A few stops can kill you outright, kept rare so it stays tense. Your ending depends on what kind of driver you turned out to be.
what I learned
- The "what's the point of the game" question wasn't a motivation problem, it was a design hole. Couldn't pitch it because the choices didn't mean anything yet. Fixed the rule, the pitch wrote itself.
- Free 3D asset packs (.blend files) are useless for a 2D game; need pre-rendered PNGs
- Capturing game audio on bare ALSA (Void) is a pain; recorded the clip on the Mac instead
- OBS quality: capture at native monitor res, not OS-downscaled
what's next
- Finish auditing the tells on Stops 3-6
- Build the consequence systems (start with headlight dimming)
- Need more COMPLETE/leave stops
- Playtest on a real person
how it felt
Long session, mostly in my head instead of in the engine, but it's the most important the design has come together so far. The game makes sense now in a way it didn't this morning. Easier to build when you know what the thing actually is.
Day 08 May 30, 2026 — lighting, sound, and what the game actually is
what I built
- Full darkness/lighting pass: world is near-black via CanvasModulate, with a headlight glow (PointLight2D + custom radial gradient texture) on the truck, offset forward. You only see what the light touches.
- Ambient sound bed: looping low drone + truck idle (AudioStreamPlayers, OGG for clean loops)
- Positional per-stop audio: AudioStreamPlayer2D as a child of each stop, swells as the truck approaches
- Stop 1 (breathing bags): breathing that fades up out of the dark
- Stop 3 (doorframe): faint pencil scratch, the measuring still happening
- Stop 4 (the chair): rope creak + buried squelch layered into one texture
- Stop 5 (the freezer): the hum of an unplugged freezer that runs anyway
- Future-proofed the dialogue box (taller, handles any text length)
- Extended the road, repositioned stops to march up the route evenly
what I learned
- CanvasModulate darkens the whole canvas; PointLight2D + a gradient texture carves visibility back out of it
- AudioStreamPlayer (non-positional) for the ambient bed; AudioStreamPlayer2D (positional) for sounds tied to a place
- OGG loops cleaner than MP3 (MP3 padding causes a seam); ffmpeg converts
- Per-stop sounds need a big dB boost (+15 to +20) to cut through the ambient bed
- You can layer two AudioStreamPlayer2Ds into one custom texture (the chair's creak + squelch)
- The truest sound isn't always the most dramatic one; the freezer's mundane hum works only because the text says it's unplugged
the direction
This was the session the game stopped being a mood and became a game. It's route-horror, or "witness horror": you drive a night-shift garbage route, and what you log stays real while what you don't fades. Every stop, you investigate and then decide, log it or leave it, and neither is ever the clean right answer. Logging keeps a thing real and binds you to it; leaving erases it and leaves a gap. Those choices feed hidden counters that decide which ending you get. It's not a gore game. It's about attention, and what happens when someone has been paying it to the wrong thing for too long.
what's next
- Stop 6, then wire the four hidden counters + endings (~6-7 stops is the threshold)
- Chair/freezer already have sound; consider the jar staying deliberately silent
- Steam page + wishlist once a stop is screenshot-ready
- Housekeeping: delete unused MP3s from the repo (kept the OGGs)
how it felt
The biggest single leap yet. Lighting and sound together turned four dark rectangles into a place that feels real in the dark. And the design finally has a spine; I know what the game is now, not just what it looks like. Long session, real momentum.
Day 07 May 29, 2026 — bulletproofing the dialogue box
what I built
- Converted the DialogueBox from fixed-position labels to a VBoxContainer; dialogue text now auto-fits and wraps at any length, and the three choices always reflow below it
- Set autowrap + custom minimum size on the prompt label so wrapping works inside the container
- Added separation spacing so the prompt and choices have breathing room
- Repointed all nine get_node() calls in stop_point.gd to the new VBoxContainer path
- Killed the text-overlap bug for good; any stop, any length, works now
what I learned
- Containers vs fixed positions: a VBoxContainer stacks children automatically; fixed coordinates can't adapt to variable text
- Autowrapping labels inside a container need a Custom Minimum Size or they can't resolve their own dimensions (width depends on height depends on width)
- The scene tree is a filesystem: node paths work like terminal directories, and moving a node deeper changes its path
- get_node() just fetches the node; the .text/.visible after is what acts on it. A wrong path returns null, and acting on null is what crashes it, same as "no such file" in the shell
- Layout Mode has to be set to Anchors before the Full Rect preset appears, when the parent is a plain Control
- Launching Godot from a terminal makes it a child process; closing the terminal kills it (use & disown, or make a desktop launcher)
what's next
- Build Stop 3, the doorframe (height marks climbing past 9 feet, DELLA, the future date), already written
- Make a desktop launcher for Godot so it runs independent of the terminal
- Add Drive-off consequence: stop fades if ignored enough times
- Scott's depot note before route starts
how it felt
Short session, single focus, and exactly the kind of unglamorous fix that pays off forever. No new content on screen, but the next eleven stops just got easier to build. Beat by the end of it, but the good kind of tired, where you fixed the thing the right way instead of the fast way.
Day 06 May 28, 2026 — reusable stops, the fingernail jar
what I built
- Got the whole project running on the Void Linux ThinkPad from scratch: kitty terminal, Godot, PATH, SSH keys, repo cloned, Vulkan drivers
- Refactored stops into one reusable scene; dialogue, investigate pages, and log text all moved out of the script and onto each instance via @export
- Stop content is now fully data-driven; the script holds zero specific words, everything comes from the Inspector
- Log text pulled out of the script too (was hardcoded as Stop 1), now reads per-instance
- Added stop_completed flag; stops can no longer be re-triggered and spam the log
- Built Stop 2, Pruitt St., the fingernail jar. First stop written in the new tone
- Fixed reading-mode arrow bug; arrows no longer re-show choices while paging investigate text
- Set up Flameshot for screenshots, kitty as default terminal
what I learned
- DRY / data-driven design: separate content from logic so you build the system once and reuse it, instead of copy-pasting 13 times
- @export lifts a variable out of the script into the Inspector; @export_multiline gives a real text box; Array[String] gives a clean typed array editor
- _input and _process fire on EVERY instance with that script; shared UI nodes need a per-instance "is_active" flag or instances fight over the same keypress
- Behavior is the truth, not the editor tree: a missing disclosure arrow didn't mean a missing child; the collision worked at runtime
- Inspector array fields take Enter as "confirm," so line breaks need a literal \n converted to real newlines in code
- .godot/ belongs in gitignore; it's per-machine editor cache, never commit it
wins
- Two working stops, each with its own content, sharing one clean script
- The reusable system is real; Stop 3 onward is just "drop instance, fill text"
- The fingernail jar is the first time the writing hit the exact register I'm chasing
- Found and killed a shared-state input bug that would've poisoned every stop; only surfaced because I built a second instance
- Full Linux dev environment standing on its own now
what's next
- Convert DialogueBox to a VBoxContainer so text auto-fits and choices reflow at any length
- Build Stop 3, keep pushing the tone
- Add Drive-off consequence: stop fades if ignored enough times
- Scott's depot note before route starts
how it felt
A grind, but the good kind. Spent most of the night on setup and a refactor that doesn't show on screen, but that invisible work is exactly what lets the next twelve stops go fast. The jar was the payoff. When I drove up and read it back in-game, it landed exactly the way I wanted. That's the whole game in one stop.
Day 05 May 27, 2026 — the camera finally works
what I built
- In-game clock: starts at 23:00 and ticks forward in real time as you drive
- Night counter displayed in top-left alongside the clock
- Camera node finally working: attached to GameWorld, follows truck via _physics_process
- Stop 1 complete: full paging system, all three choices functional
- Investigate branch shows the full note across 5 pages, press E to advance
- Road length adjusted so movement feels correct
- Visible collision shapes debug helped identify positioning issues
what I learned
- Context matters for movement: without landmarks a moving object looks stationary
- Camera2D works correctly on Mac; it was always a Linux display issue
- lerp for smooth camera following
- %02d:%02d string formatting for displaying time with leading zeros
- Area2D CollisionShape2D position is relative to its parent node
- Keeping collision shapes away from the player spawn point
wins
- Camera works
- Full first stop working end to end: drive up, read, choose, consequence
- The note pages through cleanly
- Game is starting to feel like something real
- Night counter and clock give the UI life
what's next
- Build Stop 2, Pruitt St.
- Make stops reusable scenes instead of duplicated scripts
- Add Drive-off consequence: stop fades if ignored enough times
- Scott's depot note before route starts
how it felt
Frustrating first half, satisfying second half. The camera working after days of fighting it was a genuine relief. The note paging through on screen was cool.
Day 04 May 26, 2026 — the choice system + the log
what I built
- Choice system working: Log it, Investigate, Drive off at each stop point
- Cursor navigates up and down with arrow keys, E to select
- GameLog autoload/singleton: persistent global script that saves entries across the game
- Truck log UI: press I to open, shows all logged entries, press I to close
- Input cooldown variable to prevent cursor flying past options
- Share Tech Mono font applied to all UI elements
- Blue panel background for truck log (keeping it for now, has character)
what I learned
- Local vs class variables: var inside a function creates a temporary variable; without var it uses the class-level one. This bit me when the dialogue box wasn't showing.
- Autoload/Singleton in Godot: scripts that run globally and persist across scenes. Registered in Project Settings → Globals
- match statement: Godot's switch/case, cleaner than multiple if/elif
- Input cooldown pattern: a boolean to prevent is_key_pressed from firing every frame
- _input(event): fires exactly once per keypress, better than _process for toggles
- Arrays: adding with append(), reading with get_entries()
- for entry in entries: looping through an array
wins
- Full game loop working: drive → stop → choose → log → open log → read entries
- GameLog persists correctly
- Three videos posted total
- Patreon live with 6 tiers
- The game feels real now, not just a tech demo
what's next
- Make choices do different things: Investigate shows second dialogue, Drive off has consequences
- Add Pruitt St. stop
- Add Scott's stop
- Start making UI look better
- Second stop point on the route
how it felt
Best session yet. Things worked. The truck-log moment, pressing I and seeing your logged entry sitting there in amber text, felt like a game. Rough as hell but real.
Day 03 May 25, 2026 — first interaction loop, amber dialogue box
what I built
- Rebuilt scene cleanly after yesterday's mess
- Road and StopPoint added correctly
- Stop point trigger working: truck stops when it hits the Area2D
- Dialogue box built with Panel and Label inside a CanvasLayer
- Amber monospace font (Share Tech Mono) installed and applied to the dialogue box
- Text reads like a real dispatch log entry
- Press E to dismiss the box and continue driving
- Set up Godot on the Mac Mini and my old T480s, with SSH keys
- Posted a TikTok video
what I learned
- Local vs class variables: putting var inside a function creates a temporary variable that disappears; leaving out var uses the class-level one. This caused the dialogue box not to appear.
- get_tree().get_root().get_node(): how scripts reference nodes elsewhere in the scene
- body.can_move = false: how two scripts talk to each other
- CanvasLayer keeps UI fixed on screen regardless of where the truck is
- How to import custom fonts into Godot
wins
First complete interaction loop working; it actually feels like a video game now. The dialogue box looks atmospheric with the amber terminal font. Troubleshot multiple issues and got them corrected. I'm actually learning this stuff and really enjoying it.
what's next
- Style the dialogue box border
- Add multiple stop points with different dialogue
- Start building the truck log system
- Figure out the camera bug eventually
- Record more content
how it felt
Felt awesome. I feel like I can actually do this. The dialogue box moment was great.
Day 02 May 24, 2026 — the camera bug begins, Patreon goes live
what I worked on
Spent the entire session troubleshooting a Camera2D bug in Godot. Any Camera2D node in the scene, whether parented to the Truck or to GameWorld, completely breaks vertical movement. Left and right work fine but up and down stop working entirely. Still unsolved. Posted to r/godot for help.
Rebuilt the scene multiple times trying to isolate the issue. Ended up back at square one with just a working truck on a black background. No road, no stop point.
what I learned
- CharacterBody2D needs move_and_slide in _physics_process, not _process
- Camera2D can interfere with CharacterBody2D movement in ways that aren't fully understood yet
- ColorRect is fine as a visual node; it wasn't causing the physics issues
- How to convert mkv to mp4 with ffmpeg
- Basic OBS setup on Linux
wins
- Truck moves in all four directions without camera
- Posted first TikTok video
- Set up Patreon
- Ordered dock, keyboard, and mouse
what's next
- Fix audio levels in OBS
- Rebuild road and stop point
- Get text box appearing when truck hits stop point
- Figure out the camera bug
how it felt
Frustrating. Spent more time fighting tools than building the game. But posted the first video anyway, which felt scary and good at the same time.
the bigger picture
Started a Patreon and TikTok today. Nervous about it, but I did it, and posted once on each. I'm hoping this starts something. I want it to make money, sure, but if it takes off in the right way I want to give a lot of it back: random giveaways big enough to let someone take a sabbatical from work or school to pursue game-making or writing for a year. There's so much creative space out there, and enough of us who love these things to pay for them, that it's possible. Might pan out to nothing. In the meantime I'm teaching myself game development, and I believe I'll get a game on Steam. All in, stomping the gas.
Day 01 May 23, 2026 — the first truck moves
Worked with Godot for the first time. Got my first "truck" created and used GDScript to make it move.
Hit some static with the movement once I ran the code and had to troubleshoot, but eventually got it moving up, down, left and right with the WASD keys.
next session
- Dark background so it looks like a night street
- A road to drive down
- A stop point the truck reaches
- A text prompt that appears when you hit the stop