I have set about learning about networking on Unity3D in order to implement multiplayer support for Zombie Gecko’s Comrade In Arms. I have a fair amount of experience with networking, having first cut my teeth writing real-time transactional system allowing Unix hosts to update banking details to a IBM Mainframe using XNA, then working on early Internet credit card authorizations system and finally developing the server/networking code for Fung Wan Online MMOG. Well enough about me ;P
Unity3D uses RakNet for standard networking and who ever is implementing things will have a lot of plumbing to take care of inorder to get things working. Unity uses a “Networking View” component which must be attached to all objects which in turn Network State Synchronization and Remote Procedure Calls(RPC’s) to occur. You can set specific spatial components to be observed by a network view but usually you will implement a script that will pre/post process network information sent. This was something I missed when I first started out tinkering with networking on Unity
Let’s go back a bit and talk about the 2 different methods of communicating in Unity:
- State synchronization - this is basically a method of setting the network view to observe a script component that processes changes in states that can be sent to the server which in turn are transmitted to all listening clients.
- Remote Procedure Calls – This is a common enough networking concept that allows you send invoke functions on the server or all clients with parameters being passed.
You can do some additional reading on networking by looking up the following resource:
- Unity documentation
- iPhone Multiplayer demo – still works and you can substitute a web view for an iphone
- Unity Networking Example – Still works on Unity 3.3
- M2H networking tutorials – It cost money now, but there was a simple network tutorial that is floating around the network.
In a follow up posting, I will go through making connections,extrapolation,interpolation and hooking RigidBody objects.
Although an component system is the basis for most modern game engines and considered as the better(if not the best) way to put together a game. One of the biggest drawbacks is that when you create an architecture that is modular and loosely coupled, you introduce performance overheads.
On PC and other higher end devices, the tradeoff is smaller in exchange for elegancy of design and implementation. On the iPhone, especially older ones you have to to be care about how to implement things. The most common discussion on most game dev sites on the iphone is to watch your draw calls. On older 3G devices, 20-30 is a bandied around number…well that obviously and how many polys you are using plus if your code is running native or script…where is all this leading too….Ah yes the component system I was building on top of Cocos2D.
Here are some of potential performance overheads I ran into while implement it:
- One of design limitation you have to work on cocos2d uses a SpriteBatchNode to allow ‘sprites’ using the same texture to be drawn in a single draw. In a component system, everything is based around composition which means there is a lightweight ‘entity’ class with ‘components’ attached to it. So 1 entity = 1 draw call at the very minimum. With the older 3G devices, you are restricted to 25-30 draw calls (as a rule of thumb that is float on the Internet).
- Sharing of properties between components. While I have allowed the position property to be stored on the entity itself, other functionality specific properties aren’t. In order to do so you will have to either incur a dictionary look up (i.e. component foo = entity.lookupComponentByName(Bar)). Or you could directly link it up be assigning it to a pointer. Doing that however breaks a design principle of trying to make components loosely coupled for modularity
- Inter component communications. Besides directly looking up a component, a better way to talk to between components is to use ‘events’. For my component system, I built a addEventListerner,dispatchEventListener system similar to what Flash has. Like all events though everything is unidirectional and has a limited data payload of a single object.
In conclusion, I think for most of the newer games going with component system makes sense because once you get started you will be amazed at how everything clicks into place. If you are writing some more performance intensive, you will find components losing some of its appeal.
Components are being used in most modern game engines. My favorite (because of it makes sense to me is the PushButton Game Framework). I like the design behind it. So when faced with developing a game using Cocos2D, I tried figuring out how to approach it architecturally.
Cocos2D is a fairly mature framework and you might as why put something on top of that. I had the choice between choosing a Model View Controller Architecture and a Component (Composition Approach). I chose Components easily. I’ve only been working with the framework for a few days but I have already got that “wow” that makes more sense now feeling.
For example, here is some code to add a entity with a sprite renderer:
_entity = [[BBREntity node] retain]; BBRImageRenderComponent *renderComponent = [BBRImageRenderComponent node]; [renderComponent loadImageFromFile:@"test_image.png"]; [_entity addComponent:renderComponent name:@"Render"]; _entity.position = ccp(100,100); [self addChild:_entity];
And then here is how you add a touch component to it to make it do something when you click on it:
_entity = [[BBREntity node] retain]; _entity.name = @"Entity 1"; BBRImageRenderComponent *renderComponent = [BBRImageRenderComponent node]; [renderComponent loadImageFromFile:@"test_image.png"]; [_entity addComponent:renderComponent name:@"Render"]; BBRTouchEntityComponent *touch = [BBRTouchEntityComponent node]; [_entity addComponent:touch name:@"touch"]; _entity.position = ccp(100,100); [self addChild:_entity];
Simple huh. Each entity is added to the layer and that added to the scene. You can see the similarities to the PushButton Game Framework ;P
I have also implemented a way to add/remove/dispatch events inside of components plus a hash lookup system to manage entities.
Next on my list is to implement some audio components then I can start using it to build my game. Unfortunately no physics components yet because the game I am working on doesn’t need it.
After a fair brief stint of working on a Native Objective C App (A Non-Game…Shock and Horror), I am finally back to working on games. The 2 or so months I spent ‘learning’ Objective C was actually a nice break from normal development and gave me a greater sense of confidence in being able to add/extend functionality when need to on iOS devices. Prior to that I was very much looking at things purely from a C++ point of view and trying to ‘avoid’ using any Objective C.
The best big of strangeness was making sure I got my head wrapped around Objective C memory management. With C++ it was new/delete and life was easy or you could use Boost to smart ptrs and so on. With Objective C, I couldn’t figure out why my memory was going out of scope (Oh you do a retain), the way it handles private instance variables and a hours of going “Oh that’s what you want me to do”.
Now i’m back to Game Development, I am using Cocos2D for development. The biggest reason is to keep the footprint small because I am looking at how games instead of strictly always running stand alone can be packaged with other Non-Game Apps.
What I learnt from Last Call, is that there is just too many games out there on the iTunes. They are all fighting for space and customers simply don’t have the time to try them all. With this is mind (and being the new year and all), I thought a more prudent approach was to look at what customers are interested in first of all. You know real people, you want to reach with your games. For example interests such as food, fashion, cars, sports etc all need Apps done. With In-App purchase you could package a game with a clothing theme in a Fashion App.
Well that’s what I think anyways. I’ll let you know how this new company strategy when the Apps come out.
After I got all the technical “bits” of Game Center working for the Leaderboard and Achievement System for Last Call, it came time to design an achievement system for the game. As soon as I started with it, I found out that it was a lot more complex then what I initially imagined.
From the technical standpoint, an achievement system gets into all parts of your code from the scoring system and level progression to the power-ups. It’s bewildering everywhere and QA testing it is going to be a bitch.
From the design standpoint, I can’t wrap my head around what other than ‘wow! I finished that” you get from an achievement system. Other games give you a virtual reward but right now I balancing out my potential rewards with what additional content I can scrape together (or beg borrow and steal). Here are some examples of some achievement I am thinking of implementing:
- Finish story mode
- Clear 10,20,40,80 customers
- Purchase all bar upgrades
- Purchase all flair upgrades
- Purchase all drink upgrades
- 3FER 1,5,10,20,40,80 (3 same drinks in a row)
- 4FER 1,5,10,20,40,80 (4 same drinks in a row)
- 5FER 1,5,10,20,40,80 (5 same drinks in a row)
- Money Achievement (200,400,800,1600,3200)
- Flairless finish (Don’t use any special powerups)
- Time achievements (1 minutes, 2 minutes, 5 minutest 8 minutes, 10 minutes, 30 minutes, 60 minutes)
- Play X minutes without losing a customer (30 seconds, 60 seconds, 2 minutes, 4 minutes)
There are a mind-boggling more that I could implement. Yikes! There must be a dancing monkey in this some where.
A new version of our Game Last Call:for alcohol is on the App Store.
Here is the app store link if you don’t know about it;P
Yes we did think a lot of this game while drinking so but I did a few updates to add more polish and fun. I know it seems obvious but here are a couple of pointers for developing on the iPhone:
- Make clickable option/text/UI reactive. Player with fat finger want to know they have clicked something, and sometimes they and their pudgy little paws tap wrongly and the game just sits there ..Curses your users will say, this game sucks!
- Test it on as many version of the iPhone you can get your hands on. A game that runs fine on the 3GS runs terrible on a 3G (which I happened to finally get access to when my sister was around). None of my testers every told me so and they probably won’t.
- When you are loading something and it take a while..tell them so by displaying the word “Loading..” or have a progress bar…Curses! this game sucks it’s hung!
- It’s never to late to make your game better
- Marketing your game is a good idea (yes you can get all the sympathy buys and buys for people off Facebook/Twitter you like) but actually putting your butt out there and pushing your game is a good idea
- There is a such a thing as bad marketing…make sure you are ready with Press Releases
- Add social add-ons…researching OpenFeint now;P
For the past week or so, I have been investigating various Remoting solutions that I can implement for the Flex Games I have currently developing. The basic features that I am looking for were:
- Translation of complex data types (being able to map classes on the client and matched on the server)
- PHP supported
- Compressed data format
- Transparent RPC mapping
I initially started with AMFPHP but switched to ZendAMF. AMFPHP seems to be falling behind in support with the last release in 2008 which is decades in Internet time. Zend AMF is also backed by Adobe which is a good sign. On the side note, iPhone integration looks pretty good to with a Cocoa AMF. I would have preferred C++ but I guess it will do in pinch for now. I will be testing that next week or so.
Zend seems a bit fat, because you have to also include the Zend Framework as well. That’s something I’m going to have to figure out to see if it can add value to services I am writing.