I love weekends. Not because I want to escape coding, quite the opposite. As a full-time principal engineer, my weekdays belong to meetings, architecture decisions, reviews, and production responsibilities. Evenings are short. Energy is limited. But weekends? Weekends are different. Weekends are pure.
They're the only time I can dedicate an entire day to building something just for the joy of it. Writing. Experimenting. Creating.
Recently, I started participating in DEV challenges and it's been one of the best decisions I've made in a long time. There's something powerful about building in public. Shipping something playful and sharing it with your community.
This challenge, in particular, just felt right - the weekend challenge.
To the Community I Call Home
The DEV community has been my home since 2017, since the very beginning of my professional software engineering journey.
More often than not, I found comfort here when things weren't going well. Especially in those early years. When imposter syndrome was loud. When mistakes felt heavier. When growth felt slow.
Reading other developers' stories helped. Seeing their struggles. Their wins. Their lessons. It all reminded me that we're all just figuring it out.
Now, years later, I wanted to give something back.
Sunday DEV Drive is a game, but not in the traditional sense.
There are no bosses to defeat, no side quests, no objectives, no timers.
It's intentionally different.
It's a browser-based synthwave driving game where your DEV Community articles become neon billboards along an endless procedural road. You type in a username, and within seconds you're cruising through a retro-futuristic cityscape with your article titles, cover images, and actual quotes from your writing towering above the highway.
And as you drive, billboards around the city display articles - yours or someone else's, pulled dynamically using the DEV API.
Imagine cruising through a digital city and suddenly seeing your own words glowing above you.
Or discovering another developer's article while driving past a virtual skyline.
It's not about winning, it's about reflecting, it's all about feeling proud and transforming written content into a spatial experience.
It Works in Three Modes
Your articles: Enter any DEV username. The game fetches their posts via the DEV API, extracts real quotes from article bodies, and renders them onto billboard textures in real-time.
Motivational mode: If a user has an account but no articles yet, every billboard becomes an encouraging message with "Click here to start writing!" - each one linking directly to dev.to/new.
Test drive: No DEV account? No problem. Take a demo spin and let the game convince you to join the community, every billboard becomes an invitation.
Every billboard is clickable. See a post you want to read? Click it, and it opens in a new tab.
Beyond billboards, green road signs display your profile stats as you drive: total articles, lifetime reactions, reading time, your top post, favorite tags, and the date you joined DEV.
But wait, there's more.
You can even switch to first-person mode and drive straight from the cabin for full immersion.
The Idea Behind It
We usually consume articles passively, scrolling on a feed. But what if your writing became part of a world? What if your thoughts lived on digital billboards? What if discovering developers felt like exploring a city instead of browsing a list?
Sunday DEV Drive turns articles into scenery. It makes community content feel tangible.
More Than Just a Game
At its core, this project is a thank-you letter.
To the platform.
To the writers.
To the readers.
To the beginners who are still doubting themselves.
If you've ever published even one article, you deserve to see it shining in neon.
If you've been thinking about writing, maybe this is your sign. WHAT ARE YOU WAITING FOR? START NOW. A year from now, you'll wish you'd started today. Regret is avoidable by taking action.
Enter your DEV Community username, hit Start Driving, and cruise through a neon-lit synthwave world where your articles appear as roadside billboards. Each billboard shows a title, cover image, and a snippet from the article body. Click any to open the full post.
Each module owns its domain: road.js generates the path, car.js builds the car, billboards.js handles the article-to-texture pipeline. The main.js entry point wires them together and runs the animation loop.
Procedural Road Generation: Stochastic Steering
The road is infinitely generated as you drive. There's no predefined track, it grows segment by segment using a stochastic steering algorithm:
Every few segments, a new random turn rate and duration are chosen. Because the turn rate accumulates over multiple segments rather than being applied instantly, the road produces smooth, organic curves, gentle sweeps, not jarring zigzags. Randomizing both the magnitude (0.042 range) and the duration (4β10 segments) creates surprising variation from very simple math.
The road surface itself is a ribbon mesh: a sliding window of 200 segments rebuilt from raw BufferGeometry. For each segment, perpendicular edge points are computed using the path angle:
constrx=Math.cos(pd.angle);constrz=Math.sin(pd.angle);constlx=pd.pos.x-rx*ROAD_WIDTH/2;// Left edgeconsthx=pd.pos.x+rx*ROAD_WIDTH/2;// Right edge
The ribbon follows the car. When you've driven far enough, the mesh is rebuilt centered around your position. The road is always beneath you, and always extends into the horizon.
Canvas-Rendered Billboard Textures
This is where the DEV API meets the Canvas API. Every billboard texture is a 512Γ768 canvas (roadside) or 1024Γ512 canvas (overhead), painted section by section:
Header bar - neon-bordered strip with author and reaction count
Cover image - letterboxed from the article's cover_image URL, loaded asynchronously
Snippet - an actual quote extracted from the article body
Footer - reading time and tag display
The tricky part: cover images load after the texture is already applied to the 3D mesh. Three.js handles this beautifully with tex.needsUpdate = true:
if (article.cover_image){constimg=newwindow.Image();img.crossOrigin='anonymous';img.onload=()=>{drawImageLetterbox(img,cx,cy,cw,ch);tex.needsUpdate=true;// GPU re-uploads on next frame};img.src=article.cover_image;}
For articles without cover images, the cover area becomes a playful "404 / cover_image: null / (the author was too busy)" message, complete with a retro grid background. In motivational mode, it reads "Click here to start writing!" instead.
Snippet Extraction: Turning Markdown Into Billboard Quotes
Simply showing article titles on billboards wouldn't be enough. I wanted actual quotes from people's writing. But the DEV API returns raw Markdown, not clean prose. The extraction pipeline strips away code blocks, images, links, and headers, then picks paragraphs in a sweet spot - long enough to be meaningful, short enough to fit a billboard.
The 60-400 character filter is crucial. Too short and you get orphaned sentences. Too long and the text overflows the billboard canvas. The result: clean, readable quotes that actually represent what someone wrote.
Car Physics: The Struggle Effect When Both Pedals Are Pressed
The driving model is simple but has one detail I'm proud of. When a player presses both throttle and brake simultaneously (a common thing with gamepads), instead of canceling out, the car settles into a "struggle" state, which is basically low speed, high engine strain:
if (throttle>0&&brake>0){conststruggle=CAR.maxSpeed*0.08;carState.speed+=(struggle-carState.speed)*0.04;}
The speed converges to 8% of max through lerp smoothing. It simulates the feeling of fighting the brakes, the car doesn't stop, doesn't accelerate, just vibrates with restrained energy. It's a small detail but it makes the physics feel alive.
Acceleration also uses diminishing returns, the faster you're going, the harder it is to go faster:
This single line replaces what would otherwise be a complex drag model. At zero speed, you get 100% acceleration. At top speed, you get 15%. The curve in between is completely smooth.
The 25-Article Shuffle
The DEV API has a quirk: the list endpoint returns titles and metadata, but not the full article body. To get actual text for snippet extraction, you need a separate request per article. For a user with hundreds of posts, that's hundreds of requests - too slow and too aggressive.
And I'm not planning to brutally overload our favorite creators' platform. I'll be easy on it. So Jess, Ben, Peter, if you're reading this, don't worry, I got you.π
The solution: shuffle the full article list and deep-fetch only 25 random articles. The rest get their description field as a fallback snippet:
Each request has a 350ms delay to respect rate limits. If the API returns 429 (Too Many Requests), it gracefully falls back to the description instead of failing. The player never notices, they just see billboards with quotes. Whether those quotes came from a full article parse or a description fallback is invisible.
Billboard Click Detection via Raycasting
Clicking a 3D billboard to open an article isn't trivial in a 3D scene. The solution is Three.js raycasting, converting a 2D mouse position into a 3D ray, then testing intersection against billboard geometry.
Each billboard stores its article URL in userData. The raycast checks both front and back panels, so billboards work no matter which direction you're looking at them from. The orbit.active guard prevents accidental clicks during camera rotation.
Building a Car from 46 Boxes
When I was a kid, I'd grab random little wooden scraps nobody seemed to need (or at least I thought nobody needed), hammer them together into a rough car shape, and nail four bottle caps on as wheels. Perfect toy car. Good times.
Who would've thought that, more than 20 years later, the same "stack-and-nail" approach would actually come in handy... in code.
There are no 3D models in this project. Every part of the car like body, cabin, hood, trunk, wheels, rims, windows, dashboard, headlights, tail/brake/reverse lights, steering wheel, interior screens, is built entirely from BoxGeometry and CylinderGeometry primitives, carefully stacked and positioned by hand.
And boy did I spend a lot of time on that! Totally worth it.
Lower body β Mid body β Hood β Trunk β Cabin
β 4Γ Wheels (cylinder + torus rim)
β 4Γ Windows (transparent glass material)
β Dashboard with neon trim + dual screens
β Steering wheel (torus + cylinder spokes)
β Headlights (emissive mesh + PointLight)
β Tail/brake/reverse lights
The steering wheel actually rotates when you turn:
Visible only in interior camera mode, but it's there. These kinds of details don't matter until they do.
So Much More to Talk About
This project was a blast to build. Every component of the game required a ton of thought, and I learned so much along the way. What I've shared here are just the most exciting parts, there are plenty of other fascinating details. If I included everything, I'd probably end up writing a book. Maybe that's a story for another day.
What I Learned This Weekend
Building a 3D game with zero dependencies and zero build tools in a weekend taught me a few things:
The Canvas API is absurdly powerful for textures. Every billboard, every road sign, the sun, the skyline, all drawn with fillRect, fillText, and drawImage. No texture files needed.
ES modules are production-ready. Import maps + CDN + type="module" gives you a complete module system with zero tooling. Twelve modules, clean dependency graph, no bundler.
Simple physics beat complex physics. A one-line diminishing-returns formula (1 - speedRatio * 0.85) gives more "feel" than a proper friction simulation would. Games aren't simulations, they're about how things feel.
The DEV API is a goldmine. Public, no auth, generous rate limits, full Markdown body access. Building for the community with the community's own API felt right.
This project was built in a weekend with coffee, a gamepad, and a deep appreciation for the DEV Community. Every article you've written deserves to be a neon billboard on an endless synthwave highway.
Now it's your turn. Take your car for a spin, share your journey in the comments, grab screenshots and show it off to your friends, colleagues... anyone! I'd love to hear everyone's reaction. Let's show everyone that we're by far the best community.