Monday, 25 April 2011

Alcohol could be the answer?

It's official - being drunk puts your mind on a clear path to programming enlightenment.

I wouldn't have believed it if I hadn't experienced it myself this very Easter weekend. Based on that statement, I can only assume that being completely sh*tfaced leads to some sort of coding Nirvana, but that's an experiment for another day.

I feel a little back-story is required. Every Easter (and August) Bank Holiday I meet up with a collection of like-minded friends in a London suburb and we generally have a laugh, play videogames, get drunk, have a dodgy barbecue, stay up ridiculously late then crash out into a tent that doubles as a greenhouse etc..., I'm sure you get the picture. Anyway, Easter just gone was no exception. Now I wouldn't usually dream of coding at a LAN party, but there were a few chill-out moments between games and this multiplayer issue was getting me down, so I thought "sod it, I'll take the flak" and opened up my development software. As it happens, no one gave a toss. (That's what it's like at these events - anything goes and no one judges you for it - we're all equals there, regardless of profession, race, gender, age, weight, height, Android/Apple allegiance...)

Anyway, after trying different things with the code, I was again getting frustrated with myself for constantly failing with the multiplayer data transfer problems I was having. Of course I was offered drunken solutions to the issue, friends hosted testing servers for me etc, but it simply wasn't happening. So I resorted to more Cider. Magners to be precise. After a while I had a strange sensation of just "knowing". Now I know that sounds like complete crap but I swear, it's as if being a bit drunk opened my mind to new ideas, it aligned my thoughts and made things clearer!

So after a few more drinks, and a few more mods to the code, and few tweaks here and there (nipples included) - I fired it up and lo' and behold I had a connection between the host and the client! I mean a connection I could send data packets across, quickly and reliably. Now I know that isn't a big thing, but to me it's a massive achievement, one that has been eluding me since...er....I can't remember, you'll have to read earlier blog posts.

So even though there is a long way to go, I am one step closer now. And it kinda made the weekend a tiny bit more enjoyable for me. Strange how different things affect different people eh?

Here is a picture of the client sending some data to the server, just for historical reference as much as anything. The data transfer is quick and reliable, and now hopefully I can progress a bit.



This might be laughable to many people, but to me it's a monumental achievement!

So now all I need to do is go through the code line by line, working out exactly how I can use the transferred data in an efficient way. I also need to build a proper datagram; the one I used here was just to see if I could actually get the data across reliably. It's still really early days, but everyone has to start somewhere, right?

I've had many experiences this weekend, some of which have already transformed into treasured memories, and I've learned one crucial thing regarding the development of Tank - if I'm ever stuck on something and there doesn't seem to be a light at the end of the tunnel... 

Have fun,chill out, get drunk and the answer might just reveal itself!

Tuesday, 12 April 2011

The failcakes are baking...

OK, this blog entry is a little depressing for me to write.

I am really, really struggling with the multiplayer thing. At the moment it feels like I've hit a brick wall and I can't see a way over. This is the first time during the life of this project that I have felt deflated, and came close to giving up on more than one occasion.

On a more positive note, I have learned quite a few things about how multiplayer games work. Although that is bittersweet because it also shows me how far off the mark I am. To break it down and really simplify it, the basic premise of client/server multiplayer is like this..
  • Hosting server constantly listens for new connections
  • Client connects and is assigned an ID
  • Client is sent data regarding other player position, orientation, state etc..
  • Client processes all this data and updates the game state as necessary
  • Client then builds a "datagram" of its own playerstate and sends to the server
  • Server receives and acknowledges that information, processes everything, then passes it on to the relevant player(s)
  • Back to step 3..
Now that sounds easy, right? Well in theory it is. OK, I've not even mentioned projectile positions and paths, collisions, explosions, sounds etc, but I've learned two pretty major things lately...

Firstly, if you're going to write a multiplayer game, you need to code for it from the start. You can't just "bolt it on" at the end which I am pretty much trying to do. The multiplayer code is so embedded, so integral to the core of the program, that nothing short of a rewrite would make it happen properly. That's not going to happen here.

Secondly, the data packets that are transferred between the client and the host need to be unbelievably efficient. They need to contain all the necessary data, and yet be tiny, and at the same time need to be sent only when absolutely needed, and in a set order. Adding to this, data packets don't always arrive at the server in the same order they were sent, sometimes they don't arrive at all. So this raises the need for prediction and correction algorithms. And all this is happening 60 times each second.

So far, the multiplayer code alone contains more lines than the actual Tank game, and I've only just got it to connect reliably to the host. I'm not giving up on it yet, but I am so close!

All of this has made me realise (and respect) the amount of work that goes into modern day games that we all take for granted. Now I understand why games like CoD have seperate executables for single player and multiplayer, or those games which have a single exe, are usually huge in terms of redundant code.

So right now, I have written a hosting server. Clients can connect to this server and stay reliably connected. The server also knows (and handles the event) when a player leaves for whatever reason. All this works on a local host (127.0.0.1) or over a LAN connection, but that's it. One client doesn't know if another has joined, left, died, fired or anything. I'm still working on it but I'm starting to wish I'd gone down the AI/singleplayer route.

The failcakes are slowly baking but they're not quite ready to eat. Yet.

Monday, 4 April 2011

Server? What server?!

Well the game has now reached version 0.7a - it's "playable" in that you can drive around the map, firing projectiles at things (mostly towers, the floor etc..) and it detects collision damage a lot more accurately than the last version did. There are no enemies to shoot at yet - see later in this blog post as to why.

So now the floor has a texture - actually there are two floors - one is placed slightly lower than the other, but the upper one is transparent (a bit) so you can see the one beneath. This gives the effect of parallax scrolling while moving, without actually having to write any scrolling code :)

The "Towers" as they are now known, also have textures and the projectile knows if it's hit one, or the floor, or gone off the "gaming grid". An appropriate explosion or sound effect is generated depending on what has occurred.

I have tweaked the Tank attributes a little too. It now drives a bit faster, but I still need to look at the turning circle. The damage meter is more accurate now, and if too much damage is taken then the game ends. At the moment it just ends with a message as to why you died, but the plan is to put some sort of routine in there. It is also possible to die if you go out of bounds now (or "off grid" as I call it).

Various sounds have been added as well as the explosions. There is an effect for when the Tank has no ammo and thus is unable to fire, and there is an effect for when a projectile is fired "off grid" or falls down the (intentional) gap between the edge of the grid and the surrounding "walls".


Earlier I mentioned enemies - as in, there are non yet. Now I have to make a huge (in coding terms) decision here, and that is whether to go down the multiplayer route, or turn this into a single player game. Both have advantages and disadvantages. I know how to code neither :(

Single player obviously won't require me to learn how to create netcode - and trust me, I don't know where to start.

Multiplayer won't require me to learn how to create AI code (Artificial Intelligence) - and trust me, I don't know where to start.

The other thing about Multiplayer - I will need to write a hosting server. WRITE ONE. There is no download available for this. As you know, the game is completely original and written from the ground up. If I want a hosting server, I'm going to have to code one. From scratch. But multiplayer can be amazing fun and well worth the effort, and it will give me some coding knowledge I can (hopefully) use in future projects.

Not that AI programming isn't just as important. Even multiplayer games have NPC's (non player characters) that rely on AI routines to give them life.

So I'm at a crossroads right now. I think I'm going to attempt to write the MP server code and see how I get on. If it is above my ability - and I fully expect it to be - then I might have a crack at AI. Though that is probably above me too.

One thing is certain though, without either Multiplayer/Server or AI, there will be nothing to shoot at. (Apart from Towers....)

Monday, 28 March 2011

Projectiles Ahoy!!

Did some more work on "Tank" today. After discussion with my IRC friends (yes, they are friends in real life too!), the game seems to have chosen that name for itself.

After some highly technical (and frankly, baffling) talks with a highly intelligent colleague, I've decided it might not be a great idea to use PhysX for the in-game projectile movement. This makes LOADS more work for me because now I need to code some sort of physics engine in software to allow for gravity and the ballistic properties of the projectile, but the reasoning is sound - if this game is to be played multiplayer - which is the eventual aim - and some players have nVidia cards (with a PhysX GPU) and others have ATi cards (software only PhysX) then there might be some discrepancy with the projectile placement co-ordinates, thus giving nVidia users an unfair advantage. Presuming the hardware GPU is more accurate than a software one, which one would expect.

Aaaanyway... Tank now has a turret. It is movable by design only along the x-axis (it can only be raised and lowered, not swivelled left to right). I did this for two main reasons, (1) to control a turret independently of the main Tank body would mean having an extra set of controls. While this wouldn't be too hard to code, I want this to be an arcade game not a Tank simulator. And (2) after playing around with the game model, it's too easy to turn the turret to 90°, pop out from behind a building, fire off a shell, then reverse back behind the building. At least if the turret is fixed (along the z-axis) then the player will be forced to drive out, physically align his Tank with the target, then fire off the shell. This will hopefully force the gameplay along and not turn it into a pop-out-and-shoot-then-hide turn based game of chance.

Talking of the projectile, the Tank can actually fire one now! OK, at the moment it's just a White sphere, but just pretend it's a Quazar Pulse*. Or something. I have incorporated a reload cycle to stop spam-shelling, and an ammo counter which depletes with each shot. The plan is to eventually have ammo crates dotted about at strategic positions. Of course during development I can re-arm the Tank without an ammo crate.




The projectile also incorporates collision detection. I'm still working on this subroutine at the moment because it's not entirely accurate (or it can be very accurate but slows the game down too much for my liking). My next job is to optimise this collision detection routine. Also, I need to write something that signifies the shell has hit a building or something.

The Tank also has a very primitive health system which I am still tweaking, more of that in my next post.

UPDATE: Here is a small youtube video showing the engine in action. As you can see, I have written an explosion routine, but the projectile doesn't disappear just yet.



Onwards and upwards...

(*The term "Quazar Pulse" is copyright ©petethesparky 2011).

Friday, 25 March 2011

Making some progress

I had a good day today. While the end isn't even in sight yet, I feel compelled to do more and more, the ideas are flooding in with each addition I make to the program. I need to keep it real though and not be tempted to add things to the plan that I have no ability to realistically implement.

I now have a floor upon which "Tank" sits. It is flat, and textured randomly with a selection of Four tiles which change each time I run the program. This is only a temporary solution, once I somehow get a graphic artist on board, I should be able to get a futuristic tile set created which  will make it look so much better. I am so pathetic at graphics that I've just labelled them Tile 1 - 4 for now. But at least the code works. If the tiles are to have any form of intentional placement, then I'm going to have to code some sort of level designer. That in itself is a large undertaking given my limited knowledge of coding. But this is why I started the project right, to challenge myself?


So at the moment, the entire tile set looks like that. Impressive huh?

I also added some "buildings" instead of the block which I was using to judge speed and distance. These are currently just randomly placed blocks of varying height. Again, to create a meaningful level, I'm going to have to invent some sort of level editor. But at least I get the feeling of driving as I manoeuvre Tank along the paths and inbetween the "buildings". And I implemented collision detection now! At the moment it just stops Tank dead but it's a start.


My ToDo list is growing by the hour, and I don't know where to begin. But I've only been at this for a few days, and already I'm starting to feel like I've accomplished something.
   

Wednesday, 23 March 2011

First Steps

I actually started coding today. It is the most basic of stuff, but it is code - and it does something!

The package itself has some great help files, and the community forum is really good, it didn't take long to get the hang of some basic commands. Some of them I remembered (miraculously) from my coding attempts of the distant past, but the ones I've used so far are very self-explanatory, such is the way with BASIC, it's the main reason I chose to use it.

Anyway, so far I've managed to accomplish the following:

  • Set up a display port, and limit the framerate to 60fps using the vertical sync.
  • Hide the mouse pointer
  • Set up some variables (Integer and Floating Point)
  • Create and position a 3D Block (which I am calling "Tank" for the moment)
  • Create and position another 3D Block, set it to be semi-transparent, and make it rotate at the rate of 0.25 Degrees for every cycle of the main program loop (This is a temporary marker which I can use as a reference point to judge distance and speed of "Tank")
and here is the cool part... (well I think so)...
  • Use the cursor keys to move "Tank" forwards and backwards, and turn left and right - at rates defined by the variables I defined earlier
  • "Tank" is also affected by a friction variable, meaning he doesn't stop instantly if you stop pressing the "up" key, he gently slows to a stop. I intend to use the friction variable to accommodate different driving conditions/surfaces. Maybe.
That's pretty much it for now, here is a screencap of where I am right now...


Tuesday, 22 March 2011

Starting point

Not really a blog update as such, but a screenshot of what I'm looking at right now.


This is where I start, I guess...