messing around with the playdate again
getting some perspective
getting fancier!
i'm a chronic bayer-hater so i replaced the structured dithering with blue noise, and to me it looks a lot nicer. runs at full speed on the real device, too!

starting on player-controls

the camera is following behind a car...but you can't really tell because the car isn't rendered yet

starting to draw a car and some tire tracks (the car is temp-art for now)

a floor

this drops my fps to 40 (max possible on playdate is 50) but i'm hoping/assuming i can find more stuff to optimize. worst case, locking the game to 30fps seems like it would be OKAY, and maybe even the more sane choice for a handheld (to save on battery power)

the real ideal thing would be if you could pick between 30fps (power-saver mode) and 50fps (try-hard mode)

better floor (now with ambient occlusion!)

back up to "usually 50fps" on the device, sometimes dips down to around 47

working on a drifting mechanic

it needs more tuning but i'm absolutely stoked about it already

starting to draw a proper car - i did this first version in a really basic way so i thought it'd tank my performance, but it turns out it still stays at like 45+ fps on the device. not bad!

i'm very bad at lowpoly modeling so the car accidentally looks like an old-timey beater, but i think that's sorta funny so i'll probably try to keep that vibe

night sky - drops me to about 40fps on the device, but i think i can still find more room to optimize

would be nice to add some clouds or something...

adding some presentation at the start of the race, and some basic timer/scoring stuff

all hail lobster font, lobster font will lead us to salvation

made a fancier finish-line and now i'm gonna need to write my own triangle-rasterizer instead of relying on the playdate sdk's fillTriangle() helper - i'd like to get rasterized meshes to use the same dithering as the walls/floors/sky, and also i need the meshes to get occluded by walls
custom rasterizer which allows the finish-line banner to be occluded by walls

working on replay recording/playback - yes, the clip looks the same as the others in the thread, but it's a pretty good run since i was retrying the map. if you think "i see places where the racing line could have been improved" then the game is working, lol

replay data is quite small: stores keyframes containing a bitmask of user-input states (one byte), along with how many frames you held that state for (one byte). a "normal" 30 second replay tends to be around 200 bytes

unfortunately i doubt there'll be a way to do any online-sharing because of playdate limitations (i'm gonna try to get libcurl to work anyway though - i think they use it for OS features, they just don't expose any networking stuff in their sdk at this point)
racing the ghost of your fastest run

smarter sampling on the floor...

when it samples the floor tex, it raycasts the texelspace grid to see how many screen-pixels it'll step along the scanline before hitting the next texel, and it can reuse the latest sample until then - fewer samples, sharper result!

it also does some smooth LOD, where it starts using a bigger and bigger "screen-pixel steps per sample" ratio as pixels get farther away

(before/after)

added a realtime shadow for the player's car

it only works on the floor (not the walls) but that's probably okay-enough for me

kinda going off the deep end here but now the car can cast its shadow onto the walls

it's kind of a ridiculously subtle effect, but it ties the mesh-geo, the raycaster-geo, and the skybox together, so uhhh maybe that's something

starting to think about a title screen but i'm not really sure wut to do yet

but hey i have an easy way to make text into 3D meshes (thank you, blender!) so that seems like a sane place to start

now we're talking!

been pretty busy for a few days, so not much progress here - but i've started getting into a track editor

initially this is just for me to make some built-in tracks, but i might polish it to make it user-facing if i can figure out a comfy way for people to share their maps

i can now save tracks as files, and then load them - the ghost-car in this clip is included in the track data. the spiral track file (including that ghost's replay) is 161 bytes

zipping the file actually makes it larger (241 bytes) so i think i did good. lol

conveniently, i already wrote a playdate serializer for C, for that previous music-maker app

here's the code for serializing/deserializing a track and its replay. serialization and deserialization use these same functions (the Serializer has a flag to tell it whether it's reading or writing) - so there's no need for annoying/error-prone "near duplicate" routines for input/output

it supports ascii format (more legible) and binary format (smaller file)

mostly boring backend stuff lately, but here's a clip of a track i made on the playdate and then loaded in the desktop simulator app - it includes four replays to compete against (bronze, silver, gold, author), and it seems like i can afford to show them all at once!

reduced the framerate to 30fps since it still beats that on the device, but in doing so i instantly radicalized myself into one of those "30fps is literally unplayable" people, so now i guess i have to optimize for 40 instead

(30 is fine with me in other games, i'm just used to 50 in this one)

whelp turns out i can't figure out how to get it back to 40 (particularly with 4 ghosts active) but 30 actually looks fine on the device - the lower framerate is only noticeable to me when testing in the desktop simulator

something something magic playdate screen. good enough!

added a way to save your replay from the daily challenge, as a way to "chess by mail" against your friends without having to author a map first

also a nice idea from @fsouchu: ghost cars become opaque when you're not touching them

fuck it, all the ghost cars can cast shadows too
adding some obstacles for extra level-design options
nicer tire-tracks: old version was 2D lines, new version is mesh-based. the main reason i did this was to get them to be occluded by walls, but they also gained some width variation to make them look a bit messier/dirtier

making some campaign-mode tracks - each one has four replays to compete against (bronze/silver/gold/author)

you'll unlock the next track if you get at least the bronze (or silver?) medal. maybe the author-ghosts are only unlocked after you get gold on every track? not sure yet

trying a different style of wall rendering

"walls are just meshes" simplifies a lot of the code and adds lots of new possibilities, but it also adds a slew of new demands, both in terms of code (LOD, sorting, etc) and aesthetics/legibility. feels promising so far, though

added object-sorting to fix the "inside out" walls (check the right side of the screen in the previous clip to see that) - i haven't mixed the cars into that sorting pool yet, but i'll do that soon

gonna need to figure out some static-object culling to skip faraway stuff quickly...there are a lot of small wall-meshes in a full track

various adjustments and new things

(this dips a bit below 30fps on the device, but it feels like there's still a good amount of room for improvement)

some more visual improvements
this bug is the good kind of bad
new car model - the change is...more subtle than i was hoping for, but it's got little hubcaps and side-mirrors now
another upgrade to the car model, closer camera angle, plus new trees (which are lower-poly, so i can draw more of them)
working on a second environment

adding some music and sound

(final music undecided, for now it cycles between 3 songs)

Behold, fish!
therefore Time for fish
working on a third environment (which will probably be second in the final game's level progression?)
second implementation of obstacles: the original style was "just add some extra walls," but that only worked when the walls were rendered wolfenstein-style, and also it just kinda sucked in general. new style is much more forgiving if you're not going for a tryhard perfect-run
lotta backend stuff lately, but i tried enabling tire-tracks for all the ghost cars and that's pretty fun (plus, it shows you whether or not a car is drifting, which can be really useful info!)
some UI improvements for the main menu
working on the browser-based companion app today, which intends to make it easier for people to share their maps and daily-track ghosts with each other
added a final obstacle-layout type to let me get to my campaign-mode target of 24 tracks: three pylons in a little row, so you have to do a "thread the needle" maneuver to get past them cleanly
been working on options-menu stuff - the latest part is a car-select screen, but i only have one car model so far, so i had to make an extremely high-effort placeholder to test the UI with a second car

making a weird bonus-renderer for little prize-scenes, for players who do well enough in the campaign mode (pre-render a gbuffer offline, do user-controlled lighting/fog/sky on the device)

i'm keeping the actual scenes a secret since they're player rewards, so here's a temp tester-scene instead

a neat thing here is that the actual triangles never make it to the device, so polycount doesn't affect performance or the game's download size. in this scene, each monkey-head is 60k+ triangles!

added a replay-viewer mode with some procgen camera angles:
- chase cam: random world-offset from the car, as if a drone is following it
- rigged cam: random local-offset from the car, as if a camera is attached to it
- tripod cam: random upcoming wall position, as if a bystander is watching the car go past
the game's heavy dithering looks good on the real device, but not so good when viewed fullscreen on a computer monitor - so i've been preparing for trailer stuff by getting the game to export greyscale footage

fun fact, the greyscale export operates by sicko-mode rules: it renders each frame of gameplay 32 times with different dither-pattern offsets, then blends them all together to get a final greyscale image (this is also where that scanline effect comes from)

since the game is optimized to run on a small handheld, when it's running on a PC it can do this in realtime - so the software renderer is hitting like 1000 fps (while also writing 30 files to disk per second)

got a third car mesh from a guy on the playdate discord (named choosh, i dunno his handle here!), also made some improvements to the greyscale exporter so it handles low-alpha stuff better (shadows, faded ghosts)
finally got my video-exporter to output audio as well, so now i'm ready to record trailer footage

trackminia has been approved for sale on the official playdate catalog!

probably releasing...in a few months, i don't have a date yet and it pretty much depends on their schedule

alright, Trackminia is now available!

store page:
https://play.date/games/trackminia/

trailer: https://www.youtube.com/watch?v=3NAtRmIOikc

Trackminia for Playdate

A drifty 3D precision-racer.

@2DArray I completed 5 campain tracks for now, and it's a really fun racing game so far! :D
@2DArray did you try to add some kind of reflections to the car? At least on the grayscale version, I think it would add a lot. Dunno about how it would look dithered, though. A per-vertex solution shouldn't have big performance impact.
@johann one of the rules in my rendering engine is "no per-pixel rendering" and unfortunately, even vertex-attribute interpolation is included in that! each triangle needs to be a solid color so I can blit long horizontal rows all at once (playdate screen is 1-bit, so I can tap up to 32 pixels in one "move uint32_t" instruction - hard to justify doing any per-pixel math when that type of blitting is available!)
@2DArray This looks so freaking cool
@2DArray Holy crap that's impressive!

@2DArray All the shadows make it hard to make out the real car's outline now.

I think giving the main car a cell shading white outline might look good. Have you tried that yet?

@alanxoc3 outlines are tougher here than usual (no vertex shaders, no post processing) - could potentially try making an expanded outline mesh manually, but it might be too expensive to justify it (could be a lot of overdraw)
@alanxoc3 gave it a shot, not completely sure how i feel about it yet but it might be worthwhile? it does help clarify the car's edges, but i dunno if it fits in with the rest of the game's visuals

@2DArray TBH, I think I kinda like it, but it's your game.

It looks better in pause screenshot than in the actual video, and the outline on the bottom kinda goes away at the wheels sometimes, which makes the wheel merge with the ground shadow again. But the outline on the top part seems fine to me.

@2DArray It is mind blowing to see what people are creating with the Playdate. Bravo!
@2DArray Oooh, some Megarace water level vibes, I love it!
@darkgriffin @2DArray I was just about to reply to say the same thing! :D
@2DArray As someone who has no skills in game development, it’s super interesting to see this kind of gradual progress
@2DArray Nice. Do you plan to add more than one car? This one looks more sporty, while the older one had more of a classic feel.