Realm Racer Devlog #1: Inspirations and Procedural Generation

     If you've been following our twitter, then you'll know we've been making some progress on our game! If you haven't, well, then you should be following us!

     We've done some concept work, and are pretty satisfied with the direction of the game. It's planned to be mobile game—an endless runner, to be exact. However, what excites me most is that it will all be procedurally generated. The whole game. I'm talking the track, the obstacles, the power-ups—everything (even the environment, if we are really good)! It might be slightly hard, trying to balance the game and give the user a fair chance at making some headway, but the challenge will be fun and, more importantly, a learning experience.

Concept Art and Inspirations

     We drew inspiration from some things that consumed a large part of our childhood: HotWheels!

Concept Art Concept art from player view.

     To be more specific, Hot Wheels World Race, Hot Wheels AcceleRacers, and Hot Wheels Velocity X. The first two are movies (well, we own the game for the first one as well, but the the movie was the real inspiration), and the last, a game. The main inspiration from the movies is the exhilarating speed at which the drivers move through bizarre environments, all the while surviving dangerous obstacles.

World Race

Acceleracers (Top) Scene from Hot Wheels World Race as the StreetBreed team helps the racers navigate an alternate route on the ice. (Bottom) The Cosmic Realm in HotWheels AcceleRacers.

     The game lends the idea of power-ups, but not quite for the same purpose. In the video game, you have to fight other cars. In ours, you are only trying to drive for as long as possible.

Car with top mounted weapon, approaching another power-up, in HotWheels Velocity X. Picture courtesy of www.gamesdbase.com

     In the end, this game has a lot to do with simply reliving our childhood passions, but through our new passion in game development. What you receive, you must give back, right?

Procedural Generation

     Now, I want to give a small explanation for how I built the procedurally generated track. The main gist of the procedural generation is heavily borrowed from this GameDevTut. I'll show you some of the integral parts that makes ours just a tad bit different.

     First, a simple picture of one of the main pieces in the prototype of the track:

Red is the X axis, green is the Y axis, and blue is the Z axis.

      You'll notice that I have at the start a node oriented as per the tutorial. The other node is at the green arrow, and it follows the same protocol (you just can't see it because in jME, one can select all the nodes, but only the first one's axes shows up).

     Now, after implementing the tutorial's algorithm for connecting pieces, and a little of my own hand waving, we get this cool piece of work:

gif of connecting

     It took a little extra work in jMonkeyEngine to visualize the correct movement, both position and orientation, of the nodes with respect to the scenegraph. In fact, there is more to this track than meets the eye. If you think about how the current procedural generation works, my track can easily collide with itself within a couple of iterations of the loop, simply because of how my track can turn left or right every time. Three turns and BAM—I've hit my track already! How do I avoid this?

     Well, there are two trains of thought for this. Like many endless runners, I don't need to store the rest of the track behind the user. Therefore, I can destroy the rest of the track behind the user, and that way, any conflicts with it will be avoided.

     The only issue with this is its dependence on how far ahead of the player the track is being generated. If it's extremely close, then it'll probably work. However, this means the player might be able to see the track being generated. While, in some games, that mechanic works really nicely (there is a game I saw from /r/gamdev's Feedback Friday, but I can't recall its name; please link it if you can), we don't think it suits our game too well. While I should still be deleting the track behind the user for memory purposes (it's being culled, but I don't want the camera to even have to think about whether or not to render it), I need another way for the track to not collide with itself.

     This is easily accomplished with some raycasting techniques. The pseudo code goes something like this:

boolean[] canPlace = new boolean[]{true, true, true};
collidables = track
loop:
    node = Node to attach next piece too.
    left_cast = raycast to the left
    right_cast = raycast to the right
    forward_cast = raycast forward
    left_collisions = new CollisionResults();
    right_collisions = new CollisionResults();
    forward_collisions = new CollisionResults();
    node.collideWith(left_cast,left_collidables);
    node.collideWith(right_cast,right_collidables);
    node.collideWith(forward_cast,forward_collidables);

    if(left_collidables isn't empty) canPlace[0] = false;
    if(right_collidables isn't empty) canPlace[1] = false;
    if(forward_collidables isn't empty) canPlace[2] = false;

    Random number from 0-2. If it's false, repeat. Else, use that as chosen direction, grab appropriate piece.
end

     This is slightly naive, since I don't check the distance to my previous track in the collidable, just that it's there, either in front, to the left, or to the right of the current track piece. This means the track will never turn back in the direction of previously laid down track. Instead, I could have checked what the distance to each first collision was, and then made the decision as to what track piece to lay down. That's just only a couple calculations away from what I've done currently, so whether I put that in or not won't affect the code heavily, but it may affect the design of the game.

     See the second half of the image in our concept art? It shows the user on the outside of the track, able to view the environment he is driving through. Currently, the code implementation deletes the track the user has been through and never has the track turn back on itself. But these both mean that the user will never be able to see how far he has come. If you were driving on the inside of the tube, and all of a sudden, jumped to the outside, wouldn't you want to take a second to view the world around you? Take a second to see just where it is you are driving through, and how far you have driven to get there? I know I would, and I hope to build that feeling into the game. There's another reason for this too (more childhood inspiration!), but I'll save that for another post.

     You may notice in the gif that an axis object is rotating and translating around the track. That's how I'm moving the player around the track! Think of the player as merely orbiting around this point—that's all it is. That, and some camera adjustments, gives us our latest twitter update:

PrototypePG

     That's one hefty update! Hope you enjoyed that!

Tags

Joraaver Chahal

I'm currently an undergraduate at UCLA studying Computer Science and Engineering, but I take part in a myriad of other activities, like game development, soccer, and robotics, that keep me busy.

comments powered by Disqus