Dreamrider is an 80’s style music arcade game. Here’s a video from a few days ago

The Concept:

  • Pick a sound track
  • Drive

Current Status:
- Playable

  • Drag-and-drop music support

Planned Features:

  • A death effect
  • Sounds
  • A menu
  • Shield Powerups
  • Landscape that reacts to the song (If I can find an audio analysis library that doesn’t need 100Mb of data)

I was actually gonna suggest making a landscape that depends on a song but you beat me to it :D. Have you looked at the wave module? I’ve used it here and it works pretty well. Here is the main code from the visualizer for the amplitude of the music:

import wave
from array import array
from bge import logic
import random
import aud

scene = logic.getCurrentScene()

WAV_FILE = logic.expandPath("//shadows.wav")

def amplitude(own, wav, t):
    frames = wav.getnframes()
    rate = wav.getframerate()
    head = int(t * rate)
    delta = head - wav.tell()
    if delta < 0:
        delta = head
    chunk = array('h', wav.readframes(delta))

    if len(chunk) > 1:
        logic.power = abs(chunk[-1])/5000
        logic.change = (chunk[-1]-chunk[-2])/10000
    return chunk if chunk else [1,1,1]

def analyse(cont):
    own = cont.owner

    s = cont.actuators["Sound"]

    if not "init" in own:
        own["init"] = True

        music = WAVE_FILE#this is the music file in wav format. I used ffpmeg to convert other formats to .wav
        logic.avgAmp = []
        s.sound = aud.Factory.file(music)
        s.mode = 4
        logic.wav = wave.open(music)
        logic.power = 1
    logic.soundTime = s.time
    logic.amp = amplitude(own, logic.wav, logic.soundTime)

You might need to rework the code a bit though.

I actually want to work on my game, Speed Farrow cause I think it could be a lot funner with some more to it.

The issue with the wave module is that I want it to work with any audio track. So if I can find a way to convert the audio to wave without adding too much extra time, then that’s certainly a possibility. I’m trying to figure out if there’s a way I can use blender’s built in ffmpeg to do the conversion to wav file, but haven’t found anything suggesting I can…
If I can’t find a good solution, I may make some sort of track editor where you can define points for the landscape to change, and what sort of landscape it should be. I may even introduce some … color variation!

And here are some screenshots of some landscapes blender’s hetro_terrain generator (which I am using in real time via the mathutils.noise module) can put out:

I’ve spent the past day or two optimizing it and throwing caches around, and finally have something that should run well on most PC’s. I’ll release a version for performance testing in a day or two.
(Only about 600-700 verts have to be changed each frame, which is the only reason this is even possible CPU-side at 60FPS. Interestingly, of the time spent updating the world, a not insignificant amount of it is spent inside pythons max() and min() functions…)

I actually used a separate ffmpeg.exe file and called supbrocess to use it. I didn’t use Blenders ffmpeg.
Those tall mountains look nice to contrast to all the small ones.

Woah, the modulating environment sounds awesome! I also like the new speedometer. Definitely looking forward to playing the new version.

Here’s a version with the new landscape generator. Please ignore the powerup graphics test. Running into it is currently bad for you.
Dreamrider.zip (8.71 MB)
Runs at 60FPS on my laptop, but at <20FPS on a friends.

I did some tests last night on using a vertex shader for the land, and instead of struggling to push 600 verts per frame, it can handle 65,000 verts per frame while generating the noise (on my laptop). I still need to write the proper noise generator (hetero terrain) into the GLSL shader, and then learn how to actually shade things, but it’s proved that this is a superior approach (and will definitely teach me more GLSL)
I need to have a think about how I’ll handle physics. Maybe a camera pointing down from the top, and sample the depth buffer? Either that or I have to have equivalent noise generators in python and on the GPU (write a trans-compiler probably).

Terrain tech test with 65000 verts (nothing too fancy visually, this is just for my future reference). If you want to see my noobish GLSL mashing, take a look.
noisegen.blend (4.18 MB)

Perlin noise implementation uses snippets from https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 though I think I will end up writing my own noise generator.

Incorperating the GLSL world generator will be a huge architectural change. I think I’ll re-start most of the code, using proper architecture rather than what I botched together in the four hour contest.

That looks great. I got 60 fps on my relatively bad computer. My critiques are: in the beginning some of the mountains came up right in front of me and I had no time to react to swerve out of the way. Also some sort of horizontal constrain must be put into place, or infinite horizontal mountains because after running into the mountains on the side, they went down and I was able to get off the path.

Otherwise, It’s looking great and I really like the curvature effect on the ground and the boost effect.

Edit: strange issue: Running from DreamRider.blend makes the game look different from running from the game.blend.


Also some sort of horizontal constrain must be put into place, or infinite horizontal mountains because after running into the mountains on the side, they went down and I was able to get off the path.

Yep, this is an issue with the current system. With that system I don’t have the polygons to make the terrain big enough to prevent that from happening, and I didn’t want the artificiality of putting in walls. This should change with the GLSL shader version, where the environment will follow the players position (much as the original did)

in the beginning some of the mountains came up right in front of me and I had no time to react to swerve out of the way.

I plan for the mountains several units in front of the player to be ‘sacred’ and allow nothing to make them taller except by approaching. It’s also a problem when the ground re-grows after a hit.

Edit: strange issue: Running from DreamRider.blend makes the game look different from running from the game.blend.

I know about this issue in UPBGE ( https://github.com/UPBGE/blender/issues/563 ) but it shouldn’t happen in BFBGE. If it’s in BFBGE, what changes?

Yup BFBGE works fine. another issue similar to the mountains appearing too close in front of me: a mountain came up from below me.

Porting blenders hetero_terrain function into GLSL wasn’t to hard:

But woah, defining a 512 int hash table inside a GLSL shader does not sound like a good thing to do, and there is a huge tonne of stuff more easily done with GLSL specific datatypes (eg vec3’s). Fortunately you can replace the underlying noise function, so I think I’ll try find a better basis. To be honest, I’m surprised it’s running at 60FPS with the number of iterative loops within the ‘newPerlin’ code.

To do the landscape changing I need to sample the landscape twice. To generate surface normals I need to sample three points per vert. So yeah, six calls to the hetero_terrain will be needed.

What is the benefit of using glsl instead of python?

Performance mostly. I could not make a wide enough terrain in python because of the cost of moving vertices individually. The GPU is already spitting those vertices around the place, so we can hook into it’s power to move them where we want to.
In python it was struggling to generate and move 600 verts per frame (5-10ms). In GLSL I am currently moving some 40,000 and it isn’t even showing up on the profiler.

This inability to move enough verts was causing me to have to take some shortcuts - such as only generating the terrain far away. This limits what can be done. For example, if the player moves sideways I cannot generate the terrain next to them until they catch up with the horizon. With the GLSL approach all the verts are being generated every frame. So moving sideways is no issue at all.

The downside: I know nothing about lighting in GLSL. It’ll be a learning experience.

Hey look, we can calculate surface normals! - this requires generating the height at three different places per vertex.

With how I plan to do terrain changes, we’ll need to do all this twice - requiring generating heights six times. But seeing as I haven’t yet nudged the profiler bar off the bottom that shouldn’t be an issue.

Wow, amazing. GLSL is now on my bucket list.

I uploaded this video a few days back

Time to start thinking about how GPU based terrain is going to do collisions against the vehicle. I have some ideas.

I created a logo:

I did it in Krita, teaching myself how to use it’s vector tools. I think I’ll re-do it in blender where I can use instancing, proper beziers and a far superior system of compositing. I’m happy with the ‘d’ and ‘a’ - mostly happy with the ‘r’ and ‘e’, and need to figure out a better ‘m’

And on my tablet I doodled a main menu concept (this was also the first version of the logo):

You select a song in the middle, it’s details appear on the right, and you hit the big audio-style ‘play’ button. The background won’t be plain black, but will be a fly-through of some generated terrain.

How were you able to generate the file buttons when they are warped like that?

It’s concept art. I drew it by hand. I have yet to implement it in BGE.

I have gone through and planned a significant amount of this game’s backed. I still need to design the internals of the game’s menu’s, and am not quite convinced of my abstraction around the world generation yet. (Though that is a feature uncertainty rather than something technical). So behold the current plan:

I spend the evening implementing the eventsystem package, and the two planned widgets (more will be added as the menu is created). As a result, we have the speedo with the new architecture.

The great thing about planned architectures like this it that they allow better testing. As a result, here is the speedo running on some test data (sine wave driven by time for the speed, modulus of time for the boost):

Yes, I agree that the text background makes it a little unclear. I’ll have to darken it slightly, or lighten the main text.

What’s really cool about this implementation is that there is a python variable that adjusts the range of the dial, so I don’t have to twiddle UV maps and then worry about the speed not lining up with the speedo marks.

The plan for the next lot of free time is to:

  • Plan out the menu (including concept art, software and blend architectures)
  • Figure out a way to do screenshot-diff testing of modules (eg the speedo)
  • Create a build system for generating some of the procedural textures (eg the speedo ticks, the terrain grid texture)
  • Revisit game design for:
  • Scoring
  • Track generation (how much control does a track have, is performance adequate, how to do physics)
  • Game Modes (eg lives, powerups)


Heck yeah! That looks shweet! Very sophisticated and retro.

Yes, I agree that the text background makes it a little unclear. I’ll have to darken it slightly, or lighten the main text.

That’s the only thing I was going to suggest. I think a little of both. It will also be clearer when its smaller. If I step back I can distinguish the numbers just fine. A bloom effect might also be interesting on the HUD.

Hmm, I hadn’t noticed that it was easier to distinguish when further away. Very interesting. I’ve never had much luck with bloom filters improving the appearance of this LED style text. I think that’s because they use very ‘pure’ colors, and so they don’t get the same extra glow-boost that non-pure colors do (probably because the one channel saturates). Maybe I’ll have to give it another shot sometime.

Here’s a new logo. Done in blender render so it can be generated as part of the build system:

If you notice anything weird about any of the letters or the underline, let me know so I can fix it! I’m in two minds about the dot on the “i” as I think it breaks the ‘flow’ of the letters.

Yes, the “i” looks kinda weird, maybe change its dot to something like: ||