Gaming Your Way

May contain nuts.

The world in words and pictures

My calendar icon tells me it's Monday  - and July already. This means I've not only missed the start of the summer, but also don't know what happened during the last six month.

All I know is that I started to work on a small scale semi top-down racing game that should be finished in "not more than 3 weeks solid work".

Ha!.

Anyway, the blog needs writing and images.

I've added a new car (see image), coded parts of the backend (for storing tracks "in the cloud" - just to use a buzzword) and a lot less bugs than on my last post. All tiles have been redone, as I needed to split the floor (road) and side (rails) colliders and even a few deco tiles have been added to the editor.

"Right away Michael."

"Look, it's a tree"

What I don't have is solid physics and a working AI. The first is a matter of bending the rules to my favour - which slightly collide with the rules the physics engine believes in. The latter results in parts on the first problem and my stupid idea to control the AI cars using the same principles as the player car, read instead of telling the car to "drive at speed Y" or "turn left X°" I simulate the controller as if a human would be playing. Of course I have a stupid (but perfectly valid) reason for that - playing back things.
Right now I'm brewing a nice mix of waypoint driving, raycasts and player data and it nearly works the way it should, well it works the way it should, but at times it fucks up due to "unforseen" events. 

I'd love to write some more, but just as the weather became fine, there are deadlines to meet ...

 

nGFX

Colliders are mean shits in Unity, let me tell you.

Lots of problems have been revealed since I started to roll my own set of car physics *without* car physics. At first it all seems so easy and logical, get rid of wheels, torque, motor and what not else to get a better control over the car's handling and setup.

 


(first setup, notice the shitload of settings ...)

 

I wanted to be able to take the car and set a top-speed from 1 to 10, as well as acceleration, a value I called "handling" and maybe "boost" or something like that.
Normal wheel based setups are a bugger to tune and I've spent a fair time trying to get the values right but still it felt ... wrong.
Anyway, the idea was simple enough: make a rigidbody box (so I can have "easy" collisions) and move it along the track, but you cannot simply move rigidbodies (or it isn't a particulary good idea as physics calculations depend on force). 

 


(simple box collider setup)

 

OK, just apply force to the box in the direction I want the car to move, which works (in a way) but then failed after I altered the track's physics material to behave more like a road.
Now the friction killed any movement and the easy solution was to just let the box float (representing the car's body only) and that seemed to work well until I recalled that I have sloped tiles. "Oh no problem", I thought and was wrong again.

[we fast forward here a good deal and stop at a point where I have a semi floating box that is always aligned to the ground, does slopes, accelerates, breaks and what not else]

 


(new setup, less settings, looks odd, but the
capsule colliders have their purpose...)

 

Looking at the image you might ask where the difference is, the most obvious are the 4 capsule colliders at the car's corners and you might have noticed that the wheel colliders are back.
There is a simple reason for this setup: it works. Using wheel colliders with no friction is heavy cheating, but it keeps the car's body afloat and always aligned to the ground (esp. on slopes). Reading out their contact points also allows the put the tires on the ground and using the suspension.
The rest of the setup consists of a box collider for the car's body and four capsule colliders (not really needed, but they simplify the handling of some of the collisions).

Yeha!

On to colliders ...

Reading out collisions is easy and Unity offers three events to track these:
- OnCollisionEnter
- OnCollisionStay
- OnCollisionExit

"Oh cool, just listen to OnCollisionEnter and detect when the car crashes into something."

In theory, yes.

In reality it isn't reliably reporting when you collide, and OnCollisionStay is reporting all the time as the wheels nearly always touch the ground (as they are part of the rigidbody setup).

But this is the story for the next post ... 

 

nGFX

And with this I killed a perfectly working game.

This post seems to be somewhat out of context, I fear - but if you follow my posts on google+ you know that I've been working on a racing game.

The problem is that this blog needs writing and updates, but it always seems to be an overkill to post the minor updates (mostly just a few lines)... sometimes these become longer post that would well fit in here - this is one of them and to make it more appealing using an rss reader I start with an image...

 

Where am I?

My last post on MTR dealt with the fact that I tinkered with the tiles, mainly allowing tiles that are larger than 1x1, which resulted in a shitload of new possibilities and problems.

Map formats: [,]

As always there's more than one way to fuck things up and I think it starts with the way you handle our map data. Lets start with the basic things a single tile needs to know: the tile to use and in this case the way it is facing (3d and all that).

The most obvious choice would be the 2d array [x,y], it is easy, clean and simple. Placing a tile is a nobrainer.

So we can use aMap[x,y] = Tile;

Any basic tilebased tutorial teaches you that. We need to store a direction in there to and as we're lazy right now the 2d array becomes a 3d array, using the 3rd dimension to store tile and direction.

aMap[x,y, 0] = Tile;
aMap[x,y, 1] = Dir.

Still easy enough. I'll skip the part where you use an object to store the data of a tile.

Now we're adding 2x2 tiles to this map and voila: instant fuckup.
You could just store the pivot of the tile and leave the other map slots empty (not good if you need to test if the place you want to store a new tile in is already used or not).
Or you could store a reference to the pivot - either as id (but then you have too look up where the pivot is) or as coords pointing at the pivot (but then you need to find a way to store the coords).

Map format [] and [,]

Another way to store the map is to just store the tiles as sequence and use a simple int[,] as index. The size of the tile doesn't matter that much this way (but it offers it's own range of trouble, again, I'll skip that part unless someone wants to know).

We'll use a simple struct for storing the data (tile, direction and some meta stuff):
aTiles[index] = new Tile(Tile, Dir [, coords]);

and store the index in the 2d map array:
aMap[x, y] = index;

Getting back the tile needs some more code, but it's still readable:
Tile = aTiles[aMap[x, y]];

The neat thing is, for a 2x2 tile I can now add a single tile to the aTiles array and do whatever pleases me to keep the map in sync. I settled with -(id + 1000), as -1 marks an empty space on the map. So a larger tile will be stored like this:

aTiles[10] = new Tile(1, 0, 10, 5); // meta shows a 2x2 tile ..., also storing coords in here
aMap[10, 5] = 10; // pivot
aMap[11, 5] = -1010; // this place is used, but it's not the pivot
aMap[10, 6] = -1010; // this place is used, but it's not the pivot
aMap[11, 6] = -1010; // this place is used, but it's not the pivot 

This way storing the map is also a bit easier as we just have to spit out aTiles as "[Tile, x, y]" (instead of dumping the whole map).

Of course ...

... the drawback of changing the map format is that the whole game stops working unless you have all the methods back in place and working again - and that's what I'll be doing after this commercial break.

And hopefully I'll rember to post the next dev log here .... otherwise you know where to find updates.

nGFX

Mack The Knife is back in town ...

... or checking a track for errors

 

Let's start with a screen shot and jump right into the fun stuff, without messing much with the underlying game (where users can create their own tracks).


[a very simple user (read: me) created track]

As always the problem is with teaching that damn computer to see if this is a valid track before it can be played. So what makes a valid track?

  • only one start tile is allowed
  • it must be a closed loop
  • the AI track must be valid and reach all tiles
 

Only one start tile is allowed

This is an easy one, loop over the map and count the number of start tiles. Another easy step to prevent 2 or more of these would be to disable the tile after it has been used one time.
I guess not.

What if you decide that the start you placed in the beginning might be better suited just before that bend you added a few minutes before, you could however just delete it, place it at the new location, then fill the gap ... yeah sure.

 

It must be a closed loop

Now that's a tough one and it took a few minutes to get the right idea. Basically it's using a node based pathfinder (again) and dungeon cells (stolen from Hellstrom.

A screenshot first.


[dungeon cells "applied"]

So each track gets a new property "exits", which is a four character string "0" (white) for a closed exit and "1" (orange) for an open one and as bonus "2" for start tile's start direction. A simple straight track becomes "0101" (N, E, S, W) a corner "0011".

Let's go over all the tiles connected, starting with the start tile ("0201") ... next one is a "0101" and a "0011" (which also change the direction to the next tile to "2" or "South"). While adding new cells to the map we also add a node for the pathfinder and connect it to the previous cell's center.

Blabla bla (new Screenshot)


[Cell'ed up and connected]

At last, we add another node to the start tile when we reach it (and we don't connect it to the first node), just run the pathfinder and see what happens (we should end up on the start tile ...).

 

We continue with the last check after this entertaining commercial about SEO scum that spams our mailbox with the promise to bring us into the top 5 positions on google - or, if you can't see the commercial, when I've written that check.

 

nGFX

Beware! Information ahead!

Nothing game related this time from me (you don't want to hear about the ups and downs of [re-]writing an e-learning platform, do you?)

So what we have here today is something Lego related. I think I mentioned once or twice my fascination for Lego and for architecture (on g+ at least) and in between coding session I started to build my own version of Case Study House #22 (or CSH#22 for short, also know as House Stahl). I'm not entirely sure what I like more, the house itself or the picture of it (done by Julius Shulman).

I began tinkering with it sometime last year (the early part) and I guess a first model was ready by mid 2011, ordering it through Lego's Design ByMe wasn't quite an option as the model came in at about €180 (some 930 parts after all), so I filed it away as a nice thing done.

Came December and I felt the need of buying something useless so I had another look at the CSH#22 model and started to redo it, reducing parts and adding a base to the model and ended up with 841 parts and a model I was pretty pleased with. Still €149 is something to think about (esp. in December) - no order for me.

Finally on Jan. 18th I decided I *want* that model. NOW! Too bad Lego discontinued the service on the 16th. What a let down I can tell you. To cut that part short - I ordered all the parts through Pick-A-Brick (€50 less, btw) and now it waits to be assembled.

Erm - what was I about to write about again?

Oh, yes. The model went on http://lego.cuusoo.com/ (go, sign up there ... and vote for it) - although I think 10k backers might be a bit ambitious ...
Anyway, from there I was contacted by a nice fellow who asked if he could do renderings of the model (as the screengrabs from DigitalDesigner are not really making anyone "wow").

So here they are:

 


A shot not unlike Shulman's foto (click image for larger version)


Front shot (click image for larger version)


Overview (click image ... you know)

Images rendered by Phillipe P. (see his other renderings on Flicker or at http://www.argobrickmodels.com/)

I'll post an image of the finished "real" model ... when it's done ...

 

nGFX

Happy New Year

I don't think I have to say much after that title.

[Add one very gruesome image of the number 2012 written in fireworks]

No list of good intents, just the wish to find more time to write about game coding (and of course writing on games).

 

So have a good one (and me being too buzzed to sleep, I do some coding)

 

nGFX

Unhappy meals - and that's OK

If you come here often you might have seen the screenshots of the "random mine" game, well this one won't make it to a full game.
There's a good reason of course (actually there are a good number of reasons).
I still like the appeal of random created levels, but this one didn't quite work as well as I thought. The early alpha version showed that a jump & run game needs carefully designed levels in order to be fun and you can't fake that by adding elements from other genres.
That was something I discovered pretty early in development and changed the idea from "really random" to "random pieces" or blocks.
This created levels that were playable, but in worst case quite repetitive. The obvious thing to do was to create more variations of the basic tiles (or parts). 

 
These are the basic blocks the generator used.

 
A version of the 0101 block.

I create a set of variations for the blocks (each one uses 30*20 ingame tiles) which worked well at a first glance.  But due to the random nature could appear multiple times in a large map. That drained the fun more than I expected. In the end it proved as much work to create varied and fun blocks as to create a whole level.
Tough decission, but I didn't want to design a jump & run game, I wanted to write code that does that for me.

Zipped and stored away for later use.

 

So while Squize works on an AAA title I'm back at the beginning of a new project.

 

You've seen Knuckles (I think he might change a bit in the end), the main character in the Unity game I decided to do (that mine game should have been done in Unity in the first place, too - but flash seemed to be make a faster development possible).

The Idea for Nuckle's game evolved from a 2d sidescroller into a 3d game, so using Unity seems the better choice - even though there's the promissing stage3d api around.

Right now I'm focussing on the controls, aiming at a mouse only controlable game, but adding optional keys for movement. I think point 'n' click controls are what I'll use in the end.
But first there's a lot of stuff to code for the first level and I need to find ways to wire things in the game (like alarms and lights) to create an working environment.
If that proves to be "fun", more things can be added for the later levels (guards, cameras, more types of alarms and security).

nGFX

We're back ...

I finally managed to convert the layout from the old blog (DasBlog) to the new one (BlogEngine.NET).

So far everything seems to work, although I might have not changed all the css styles - give me a shout if you find something odd.

Not using Disqus for comments atm, because all our old comments would have disappeared - not quite ideal imho.

We need to clean up the categories now and convert most of them into tags, but the I think it's done.

nGFX

 

Edit:
I just noticed that we have a new RSS url, so you might want to change it to:
http://blog.gamingyourway.com/syndication.axd 

More Nuckles

[forcezoom]

Pretty much where I want it to be now. Not textured yet and only using plain colours.
I guess I'll add bones now and do a simple walk cycle. With that in place it's time to do some environments (and props) for walking around in.

 


nGFX

Meet Nuckles

Just a quick picture post and at that a quick WIP shot of Nuckles.

Nuckles, WIP
More details later ...

nGFX