Best Games - Moto Racer
Moto Racer is a deeply unfair game. Every slight bend in the road could end your race. A mistimed button press could mean the difference between finishing first or last. Nailing every corner, every straightaway, every jump is absolutely required to win. That’s on the medium difficulty. Moto Racer demands perfection.
That might sound like a recipe for a bad game. Players typically don’t want to trial and error their way through most games, let alone a racing game. Racing games are supposed to be about speed and timing and weaving through opponents. Taking advantage of opportunities when they present themselves. Balancing aggression with racing tactics. Moto Racer isn’t that type of game.
There is a certain joy in learning and then perfecting a system. Optimizing to the minimum number of movements in the shortest span of time. That is the type of game Moto Racer is. You are presented with a handful of tracks in two different modes. In the street racing mode it’s all about speed and careful use of a turbo that boosts your bike forward, but also decimates your maneuverability. In motocross mode it’s about drifting hairpin turns and hitting jumps with the right amount of speed so you land cleanly with your speed intact. In both modes you will have to hit buttons and lean your bike at exactly the right time lap after lap after lap.
That’s really what this game is about. Moto Racer doesn’t boast a realistic physics model, or complex tracks, or deep upgrades. It’s about learning the tracks, perfecting the tracks, and then trying to shave millisecond off your lap times. It feels like racing.
You will not win the first time you play Moto Racer. Every time you start a new track, you will lose. It won’t matter how well you did on the previous track. It is unfair in that way. It is unfair as a game. Run a track 5, 10, 20 times though, and you will start to memorize it. When to let off the turbo and when to open it up. How early to start a turn, and when to dive out of a corner. You will master the tracks and you will win. You will have earned it.
Moto Racer might not be able to stand up to modern racing games, but the developers added something to the game that a lot of its current day counterparts lack. The heart pounding feeling of pushing your precision to the edge and succeeding.
Moto Racer is brilliant and it’s one of the best games.
A full first draft of the new story is up here. Like all first drafts it's a little janky in places and will have errors, typos, and plain busted stuff all up in there. If you read it and have suggestions on how to correct that jank, please let me know. I'll probably give it a couple weeks to breath and then revisit the story to punch it up. I have another one that I am in the process of punching up, so I'll probably do that first. In any case, if you read it, I hope you enjoy it.
Added a few more pages. I thought this one was only going to be about 5 pages, but I blew past that and I'm only about half done. So probably closer to 15 or 20 pages when it's all done. Not super short, but regular short story length. I'm getting better at predicting how long a story will be but I'm not good at it yet.
Continuing to write this small story over here. I've plotted it out to only be between 5 and ten pages, so I'll probably have it all wrapped up next week. If I were you, I would wait until then to read it.
Started a new one over here. It won't be a very long one, but it might take a week or two to get it all out.
This page will be moving. Again.
I started this thing on Blogger. I only wrote about 20-30 posts before moving it all over to Weebly. I’ve spent the last several years posting at least once a week to weebly and now I’m moving again. It’s just not the right platform for what I’m doing.
Last time the move wasn’t too much of a problem. A couple dozen posts ranging anywhere from a few hundred words to just around a thousand. That was mostly just a copy and paste job. Well, copy, paste, and change some links and image locations.
Now I have added more than 400 posts. A dozen short stories. Some interactive fiction. I can’t really copy and paste all of that. I couldn’t even begin to imagine manually fixing all of the images and links.
Weebly doesn’t offer a great way to download blog content so I had to rip my own site from their servers in a really clumsy way. It kinda of sucked, but I have all of the content sort of in a messy pile. Now I have to organize that pile into something I can put up again. So, what to do, what to do?
I wasn’t about to do it manually, so I wrote a program. A pretty simple C# program that sifts through the pile, pulls out each of the over 400 posts, dusts them off, updates the image locations, repairs as many of the links as it can, and writes them back into cleanly formatted new files with the proper names and dates. It isn’t a complex program, but I don’t really write this sort of thing so it was a bit of a challenge. It took the better part of a day to make sure that the resulting posts contain the bare minimum of errors. On the upside, it only took about a day. Trying to move them over manually would have taken ages and I can’t imagine how monotonously soul crushing that task would have been. Just taking the chance that I would accidentally read an old post was too much to risk.
I still have some organizing and design cleanup to do before I can fully move the site over to its new home. When that happens I will post again to mention any changes to the RSS feed. I have two or three bugs to squash before the full move but it should be no longer than a couple weeks away.
Best Games - Burnout Paradise
Does the idea of spinning donuts around the infield of a baseball stadium sound appealing? Would you like to launch a car off a ramp, sail an unreasonable distance, and nail a perfect 4 wheel landing losing no momentum? Would you like to nudge a supercar into a barrier and watch it crumple like foil knowing there would be no consequences or injuries? What if you could drive impossibly fast not only over the road, but through buildings, on train tracks, on park pathways, and more? Burnout Paradise has you covered.
Burnout Paradise might be a perfect driving game. You will notice that I didn’t write ‘Racing Game’. Burnout Paradise is a driving game. It’s an exploration game. It’s a toy car sandbox game. There is racing in it but it’s not, strictly speaking, a racing game. The draw of the game is not the racing. I suppose for some people it might be but the game isn’t really designed around the racing. It’s designed around the driving.
No matter what you do in the open world of Burnout Paradise, the game tracks it. How far you drive. How fast you drive. How much time you spend in the air. How many flips and spins you do. How many cars you crash, both your own and your opponents. If it’s a trackable stat the game probably tracks it. The game tracks it and then rewards you for it. It incentivizes driving over winning races or completing challenges. Burnout Paradise is a game about driving.
There are a lot of people who didn’t like it when the Burnout series shifted from the focused event based structure to a flowing open world with potential events at every intersection. There were complaints that it took too long to get from one event to another, or that it was too easy to get lost in the labyrinth of city streets and shortcuts. Not liking a game is no real crime. There are and were certainly other games for people who didn’t enjoy the open world of Paradise, but I can’t help but feel like they missed the point.
It’s a driving game not a racing game.
The events are secondary to the reason you load the game up. You play Burnout Paradise to drive. You play it to drive in the most irresponsible and chaotic way possible. You play it to manifest fantastical driving situations. You play it to enjoy the feeling of speed and impact and exploration.
Burnout Paradise is about driving and it is one of the best games.
Imagine you were to get to see some amazing old sculpture. A real museum piece. The Venus De Milo. You get your eyes on the Venus De Milo. You’re looking at it and you want to steal it. There is a museum curator watching you, there are security guards, other museum patrons, etc. There is absolutely no way they will let you do that. Also, the statue has to weigh close to 2 tons. You aren’t going to be hauling it out on your back, but you can take a picture of it. Maybe a lot of pictures. Maybe a lot of pictures with a camera that can capture depth and minor variations in the surface of the marble. Pits, cracks, dust, all of it. You and your camera take a quick buzz around the Venus snapping shots the whole way, and bug out.
Now that you have all of this information in images, it should be possible for you to start with a blank approximation of the Venus De Milo and recreate all of those details. Will it be exactly the same? No, of course not. Could you deceive the other art thieves with it? Will it look convincing enough from a distance to get you into all of the art thief parties? Only one way to find out.
Now since I do most of my art stealing digitally and figuratively, I set up a tool to make that high detail image capture easier.
You see, when you set up digital 3D models for use in real time applications, that is exactly what you do. You take heavy, detailed, high resolution art and you crush it down to something that a computer can draw to a screen 30, 60, 90, or 120 times a second. The better you can steal that detail and pack it up into images, the more convincing the final result will be.
Some stuff I have been working on required nice seamless tiles of high detailed fakery. There are tools and techniques that let you do this, but most of them are clumsy, slow, or expensive. I spent some time this past week to fix that.
Just to be clear, I haven’t made anything revolutionary here. This isn’t some sort of stand alone tool. I put together the equivalent of a carpenters jig. A simple tool that helps you to do a more complicated job more easily.
If that sort of thing doesn’t seem up your alley you can bail now. It’s okay, I get it. I’m going to break down how I set up one of my tools in Blender.
Let’s start with the camera. I set up a single orthographic camera right above my work area and set the orthographic scale to 2. I set it to 2 because I will be using a 2x2 plane as the extents of my texture. You can set it to whatever size you like, but I find this works for me.
I also set its render size to 4096 x 4096. You could set it to 2k or 8k or whatever size you want, but I wanted nice high resolution square textures at the end of this process. Your textures don’t need to be square, but that’s for you to decide.
You will also notice that I set the output to the openEXR file format. This isn’t strictly necessary but openEXR can contain a 32bit color depth and a linear color profile. sRGB non-linear color spaces, like 59.94hz NTSC signals, is one of those things that should probably be un-invented. Since we can’t do that, keeping your textures in a linear format, while not entirely required, is good texture hygiene.
Under Render Properties I set the display device in the color management dropdown to None. This prevents visual color crunching from alternate color profiles.
This is what the camera setup looks like with a 2x2 plane under it. Not really very interesting but it works.
Now that the camera is taken care of I need to model something under there. I quickly made up this screw head, since it’s the sort of thing that you wouldn’t want to model a thousand of and is a great candidate for casting off to the 2D world of texture images.
And this is what the camera sees.
That’s great and all but not really useful. To make it useful I needed to set up some materials.
This is what the same screw head looks like when I apply a normal shader to it. The normal shader encodes, in rgb pixels, the way that light would bounce off of a surface if it were 3 dimensional rather than 2 dimensional. The colors represent the deviation from the surface normal (perpendicular to the face). So it looks bumpy without actually being bumpy.
And this is what it looks like when I apply a depth shader to it. This one colors the surface in a smooth gradient from black to white based on the distance between two objects. I made these objects two non-rendering empties because that was a useful way to represent them. You could use anything. The distance between world 0 and the camera. The bounding box z dimensions of the model, or just some arbitrary numbers.
And this is the shader node graph for both the depth and normal shaders. I combined them for convenience and set up a switch to go between them, but you wouldn’t need to do that.
Since the entire depth graph is visible I will go over that first.
I’m passing all of these into an emission shader because emission is a pure representation of the output color we are looking for. No lights or shadows mucking things up. I get the position of the geometry that has the material applied to it with the geometry node and pass that to a Separate XYZ node. We are only interested in the Z position so I take that and pass it to a Map Range node. I want to take the distance between my two measurement objects, my ZMin and ZMax, and remap that distance to a 0-1 scale. This will give us a pure black to pure white gradient. I pipe that result into the emission shader and then pipe that to the material output. In this case I go though my mix shader for switching from depth to normal, but I wouldn’t need to.
You might notice that the ZMin and ZMax are purple. That is because those Value nodes contain a float driven by the Z position of my two measurement objects.
You can drive damn near any value with any other in blender just by right clicking on the input field and clicking on add driver. It’s something I don’t do nearly enough of but it’s very handy.
Now for the normal map. As you can see up there I use another geometry node (I could have used the same one, but whatever) and pass that into a node group that converts the normal vector into color data.
This is what’s in that node group.
I could absolutely clean this up and simplify it, but this is working. I’m taking the normal vector and converting each channel into the appropriate color. It set up like this because I was messing with each of the channels for a bit to get them tuned. I might clean it up, but it’s working now so I probably won’t bother. The Combine XYZ node is doubling for a Combine RGB node, but numbers are numbers and Blender doesn’t seem to care what node they come out of.
I take the new colors, put them into an emission shader and we’re almost done.
Now for the real reason I put together this setup. Baking.
The common workflow for this sort of setup is to make an empty image texture and ‘bake’ the detail from your screwheads or whatever into that image texture. Then you save that out to a file and you’re done. Great, right?.
No, it blows. Baking is slow, uses a different render path than I’m using to display the results, and sometimes contains artifacts and issues that you can’t see before the bake is done. I had depth and normal maps where two adjacent pixels that should have had a lot of contrast between each other turn into a mushy mess when baking.
To get the result out of the new method I use EEVEE (Blenders real time rendering engine) in the camera viewport and I press this.
Using this new method those pixels come out perfect. What you see is what you get. Not only that, but when reapplying the depth information, I now get perfectly sharp edges and details. What is the cost of this increased precision? Well I went from bake times I could measure in minutes to render times I can measure in seconds. More precise, faster, and easier to iterate. It’s vastly better.
Then it’s a click of Image - Save As to save the OpenEXR file and I’m done. I think that, in the future, I could set up a python script to run through the whole process for any maps I have to export and it could be a one click type of process. For now though, this works, and more important, it works so much better than baking.
Of course this works for flat surface details. Stealing the detail off the Venus De Milo might take a bit more work, but I have some ideas about that I might sort out one day.