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 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 ( 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....)