perjantai 11. joulukuuta 2009

T+x

As I said in the very first posting, I wasn't going to make this blog a burden for myself. This is the reason I did not write anything when the deadlines started to approach. The two games were part of a bigger project: getting me graduated before xmas. The sheer amount of work writing all the reports and finishing the loose ends felt pretty masocistic at times, but I'm now very happy that I finally reached my goal.

I think I might just stick with this blog btw. The name "Keely 440" has kind of funny vibe. I know there won't be too many readers, but I write for myself mostly so it doesn't matter. I have no idea that I'm going to write about, but I guess I'll just write whatever feels interesting, whether it's gamedev-related or not. Now I feel like writing a few passages of post-mortem about school, so here goes:

I never had great ambitions for education or consider graduating some kind of larger-than-life event. At some point earlier in life, I actually made peace with myself on the subject: If I'd graduate, great. If not, no biggie. Six years ago, I applied to our school, because that was something "everyone does" or something that "you are supposed to do". I don't regret the decision. I made it based on what I felt was right at the time. If I could rewind back time, and be myself six years ago, with the self awereness I have now, I would skip the ordinary education and teach myself. I think by now, I'm an expert - when compared to our school organization - on how, what and why I need to learn. I also think that - albeit trying to foresee the future is kind of retarded - the working culture is shifting more away from the formal education and the degree I now have probably makes a near zero impact on my career or life in general.

School had a positive impact too. I met alot of interesting people and new friends along the way. I'm still in touch with many of the guys we started the school with (even though they graduated 3 years before me). Also, now in the final months, I suddenly had like dozen new gamedeving pals through the Gamelab @ school, when earlier I had none. There was big chunks of "free time" in school to think about what I want to do or what is it that makes me tick. All great stuff.

But, for a critical thinker that I am, these are all pretty much false arguments. It's pretty hard to predict what kind of people would I have met or what kind of positive situations might have risen, if I had skipped the school all together. No way of arguing one way or the other. It is called results-oriented thinking, and narration of random events into what seems like solid arguments. This kind of phenomena is very common in a very complicated modern society, where people like politicians, businessmen and other decision-makers, have to cover their ego from the fact that there is actually very little that they know or can do in terms of making the right choice, because there is no such thing as right choice to begin with.

We are all children of the primitive men of the savannas. Results-oriented thinking makes sense, when you avoid getting killed by lions or try to hunt for rabbits. It doesn't make sense in the complex society of 21st century. There is just no way to measure a value of a hard decision, like going or not going to school, before or after, with the way you measure a simple decision like "should I hide from this lion to tree or run for the caves". Back then, you got an instant and accurate feedback. Fast forward a few million years of evolution and BOOM, here we are: Children of these primal men, now in a totally different new world of information and complex structures, crippled by our past.

Of course there is randomness in the lion example too. You could find your mates in the way to the caves, who make the lion back away. Or maybe all the trees nearby could be too hard to climb. But when you compare this to the randomness of the modern world, you might understand where I'm getting at: We are trapped by our primitive genes and protect ourselves and our precious egos from the fact that many of the big decisions we make, are just a diceroll with a tiny fraction of determinism. It is hard for a human being to let go of the idea, that you could control your destiny. I'm not even sure that anything positive follows from my realization, that there is very little I can do, or atleast no proof to think otherwise. Sometimes I think that I'd actually rather be the ignorant young fool that I used to be, but I can't help being the critical thinker that I am now.

Wisdom brings pain, but I hope some more joy also. Maybe the ultimate conclusion that you can derive from this, is that not everything in life is random, and you can still try to make good decisions. It's just that you should not get too stuck with the negative results of your hard decisions when they (eventually) arise. When you can indentify the sheer amount of "dicerolling" taking part in the course of your life, you might become more relaxed to face the hardest of decisions and the worst of results, and still be able to enjoy the ride.

Now I'm going to make some nice cup of coffee and just watch my dogs play outside. I've earned it.

torstai 3. joulukuuta 2009

T+305

We were required to write a short documentation on the project to pass the course, so I went on to write one for the Tanksalot. I'll just copy-paste most of it here, because I think it'll make a nice blog entry on it's own.

---

PREFACE


Introduction to Game Development Tools was a joint course of University of Turku, University of Applied Sciences of Turku and Digital Arts, Turku. It was a course which emphasis on practical work. The requirement of the course was to create a (small) computer game. One could use any tools creating the game, but the lectures and examples were first concentrated around the Panda3D-engine and later on around Unity3D-engine.


LANGUAGE


I had some game-related code sitting on my PC in Java already, so we decided to be rebels and do our game with Java and OpenGL. To be honest, I (Juha) decided it, and the rest of the group did not object (out loud anyways). Later on, I was worried that I might have ruined the course from the others, by dominating the selection of the language. However I discovered that Tomi and Joose, aside from doing modeling, audio and graphics for the main game, ended up doing some moonlight experimenting on their own with Panda3D and Unity3D. I think it all ended up nicely and everyone got what they wanted.

TOOLS


The models of the game (mainly the tank) were done with Blender, and then we used Newtek’s Lightwave as a pass-through solution to save our model in the correct .obj –format, so that my existing parser could understand it. There was no need to do yet another parser for yet another new format. Miro used to Adobe Photoshop CS3 to create our 2D graphics. Audio placeholders were recorded with Adobe Soundbooth, but we eventually replaced them with free audio effects from various internet sites which we fine tuned in Cubase. We used Eclipse as an IDE for programming .


ENGINE


As mentioned earlier, we used some of my already made Java-code for the basis of the project. It is not a game-engine, but rather a large codebase to draw features from. All of the code is built on top of the Java Lightweight Game Library (LWJGL), which is very low-level wrapper to interfaces such as OpenGL, OpenAL and DirectPlay. To create our nice looking graphical outlook, we also used custom GLSL-shaders, which employed a standard commonly reffered as the “shader model 3.0”. It narrows down the display adapters that can run the game, but 3.0 is a common choice for a minimum requirement for a new game in late 2009, and it is hard to do good looking post-processing effects (like Bloom) or celshading with older shader models like 1.0 and 2.0. For the physics side of things, we plugged Bullet Physics -middleware to do the work for us. Actually we used the JBullet, which is Java porting of the original library. Bullet Physics is a new open-source physics middleware, which is supposedly also used in multiple AAA-games. It has native support for raycasting vehicle, which made our tank driving model with 6 wheels very easy to create.


GAME


In the first meeting, we had two options. A game where you could control a ball in a maze with physics. The second was a top-down tank duel. The war mongers that we are, we wen’t for the shooting. At the end, it wasn’t a top-down game, but a split-screen 3d battle. The original IP also had some kind of maze or walls in it, but later we decided to make the game arena sort of a round desert. Main reason for this was the quick deadline we had to commit to, because of graduating timeline that some of the group members had setup for December, and there was no time to make the objects work and look good in our game.


When the game starts, players are dropped in the corners of the arena. There is a little hole in a place where they start, so that they can’t see each other just yet. Each player is given 3 ammunitions (out of 5 max), and full health. These are clearly visible on the HUD. Powerups (health and ammo) are dropping at a constant pace out from the sky. They are wooden boxes that slowly float down with parachute on top. The idea of the game is simple: kill or get killed. The round ends if one of the players drop health down to zero and the winner is given a point.


TERRAIN


The terrain is not totally flat, and it is 100% procedural. There is a heightmap generated at load-time, with diamond-square algorithm. We also made the algorithm to raise from the edges in circular matter, so that the form of the round arena is generated. We also made a small foxhole in two spots where the players start. From this heightmap, the polygons of the terrain are created in a obvious and straightforward zigzag. Bullet Physics has a support for heightmap-collision shape (which is actually converts to a normal trimesh), which suited us well, since we already had a heightmap lying around in our code.


The terrain is rendered with a special shader. This custom shader was needed, to get the lights of the missiles to make a brighter areas where the missile was close. We used OpenGL standard light-structure to pass the light positions (maximum of 8 simultaniously) to our shader, which then calculated a sum of the missile light intensities for each vertex real-time. This value was then added to a per-vertex sunlight value, which we precalculated from the normal vectors during the pre-calc.


CELSHADING


Our celshading approach was the one you could call “the easy way”. It doesn’t use post-processing pipeline or complicated depth-buffer magic. We simply scale up each of our models slightly (with OpenGL glScale) and render all the back-culling faces in outline color (which is usually black). Then on top of this black shape, we render the object with normal shading and normal scaling. Since the size of the black rendering is slightly bigger, this creates a black outline around the object. This is a neat and fast trick, but it has some artifacts when the shape of the object is not very round and conformed. You can see the problem for example in the tip of the cannon of the tanks, where the outlining is not what you would expect from a cartoon artist. The other part of the vanilla celshading is the polarization of light. This means that we do not draw smooth transitions of light, but rather a more binary on/off kind of shadow. This is done at the end of the light calculations of the pixel shader, with a simple if/then-structure. You could also use some 1D-texture to “wrap around” the linear gradient that your Phong, Gouraund or whatever-light-algorithm produces, but we decided to do it in the dirty hard-coded way.


AUDIO


There is an inherent problem with a split-screen game IP and OpenAL 3D-sound interface. OpenAL paradigm is based on the assumption, that there is only one listener object in the scene, with a singular position coordinates. This makes sense for the 99% of the games. You render your view of the world from one camera at the time, and can assume that the sounds of the game can be rendered based on what is heard in that position. In a split-screen game however, this is not the case. You have two equally important listeners and cameras, and can’t represent 3D audio with this single listener paradigm. So we had to make a workaround for this. We made a parallel fony world only for our audio. In this world we put the listener object in the origo. Then we put two audio source objects on fixed positions at front-left and front-right. This represents a two-speaker system with a listener in the middle. Then if a missile (sound source) in a game created sound, we would manually measure which player it was closest to, and then played back the sample accordingly in our parallel audio space. We could not use the great 3D-features like the Doppler effect, but this didn’t hurt too much.


SCREENSHOTS


Finally some in-development screenshots of the game to illustrate the development cycle of the visuals.





tiistai 1. joulukuuta 2009

T+272

I think there was a bug in my 440h takeoff calculator. I "dirtyfixed" it now in the headline of this entry, and I have now exactly 7 days (168h) to go. I'm writing this entry after some extreme coding strech. I think I woke up at 12pm yesterday and went straight to my PC. I did some coding and then headed for my dayjob at 3pm. There I coded some more and left around 8-9pm, just to eat a quick pizza and do some MORE CODING back home. As I'm writing this, it is now 8-9am the next day, and I'm still pushing it. So far that's 20 hours of straight coding, which would normally make me into a passive-aggressive zombie, but I'm feeling suprisingly zen-like now. It must be those D-vitamin supplements I've been eating a few weeks now.

My projects have gone forward and I'm more pleased than I was when I wrote the last post. I have finished Tanksalot now, and all I need to do is write some light documentation about it, and it's wrapped. I think it still would not work on those 64-bit win7 machines @ school, but I'm not going to spend my energy on that. I have more important nuts to crack at the moment. The toughest being the networking in the Quickrally.


Last post included a video with four players on LAN with the very first multiplayer demo I managed to pull together. It worked well, but there was still some stuff and inconsistensies when the cars collided with each other. I also used too heavy frequency of updates because I knew that we would be testing in LAN and I didn't want to tinker with all the details just yet. Now I'm happy to say that in these past few days, I was able to get the whole thing much more robust. It's pretty smooth and consistent at the clientside, even if I send something like 5 packets per second from server to clients. If I'd throw in 20+ players now, I think the scalability in the networking-side of things should be playable. I'd be more worried about physics calculations with 20+ raycasting vehicles. Of course the networking could still potentially explode with 5 players. Testing multiplayer stuff locally with one PC and NIC loopbacks is just not going to make me feel like 100% confident, but I'm feeling about 96% right now.


The new IP


My friend showed me this youtube clip of some PS2 "partygame" they were supposedly playing the night before. I forgot what was the name of the game, and can't find it anymore, but I will post it later when I do. It was a multiplayer racing game with single top-down view and pretty arcade gfx and controls. The idea was simple: The camera follows the top car and if you drop out of the camera, you lose. When all but one player has dropped out, the player who survived gets one point. Then everyone is respawned again in the current camera location and another round begins. The game ends after some player has 20 points and he is the ultimate winner of the whole match.


I have never played this kind of game, or even heard such things exists. After 5 seconds of watching the youtube video, I felt like "WOW!". It was somehow instantly clear to me, how superior this idea actually was. "Perfect for multiplayer racing!" I thought. The very reason it is so good, is that it cleverly removes the greatest obstacle between fun and multiplayer driving games: It's boring to drive alone. When you take your average Need for Speed, and go for a spin with couple of online buddies, this is what happens: First there is a big hazzle at the start, followed by couple of critical knockouts. After this comes the "10 minutes of boredom", where you try to catch your friend who is playing it safe. At the same time, you are taking huge risks, and eventually crash (with curses and moaning). There is the good ole "catch-up" concept, where the game gives extra boost to guys behind, but that just feels so lame! What is the purpose of trying to get ahead, if the looser behind you always gets back with fony catch-ups, and eventually the winner is the one, who gets the timing of the last corner right. This new format with very quick knockout rounds is very different. It's action all the way. There is constant
interaction between the players. That is what multiplaying is all about, right?

I'm going to try to implement this in the Quickrally asap. I will do couple of twists compared to original game, since mine has multiple views and I don't want it too be too arcade. I think I'm going to do it in a way that if you are leading the race, you gather some kind of "mojo", and after it's "full" you win the round. If you are overtaken, the mojo will go down fast. Also I think I will make the player who is in the last position, when the round ends, lose a point. This motivates the guys at the back, who were knocked offroad by evil peers, still put in the effort, even if it seems they lost the changes of winning the round. I'm pretty excited about this, and I hope my implentation is atleast half as fun as the original. I'm still trying to find that youtube-clip with no luck, and probably need to ask about it from my friend again.. Anyone know this game?

update:



This is the game I was talking about.