Implementing Multiplayer

At the moment I am plugging SDL_Net into Ocean Horizons, the newly added basic AI and movement states need to send/receive requests to/from server game in multiplayer game, there are also tons of things needed to be addressed in network/SDL_Net/server game in general:

Message Struct:
Ocean Horizons needs an universal serialized header format to identify a message's type, length and possibly a timestamp indicating the birth of such message in game time.

Serializing Game Objects over Network:
Generally sending a whole object over network is a big nono in most applications. However, in a game like Ocean Horizons, such thing is unavoidable. Probably I will just copy-paste the save to file serialization functions and replace FILE/OFSTREAM buffer with a char* buffer =D Reusable codes *cough*

Sending AI order/action changes events over Network:
AI Order/Action are the fundamentals of a simple "state-machine" AI used in pretty much every game genre, sometimes they are also referred as "Goals" in games have relatively higher level intelligence, e.g:FPS bots.
An Order/Action should be as simple and as small in size as possible, since they change alot in a game, and every object that has AI has at least 1 instance of both.
For example, when sending an attack-some-target order, you will need:
1.The attacker
2.The target
3.IF in range THEN attack ELSE move-to-attack
4.IF move-to-attack THEN get-target-position

The order 'ATTACK' is just an enum or constant that is probably only 1 byte if you have less than 255 order types(well if you have more than 255 order types, you fail at making a game =o), while the attacker and the target are probably multiple bytes objects, to minimize the network overhead you will need an unique id for every object in game, sending Unique Id(usually 4-8 bytes, depends on how you handle Unique Id and how many objects your game has) is much more efficient than serializing the 2 objects, both in time and in space.

In Server Client model Ocean Horizons will be using the overhead of Sending AI order/action will be significant on server, basically one AI order/action message will need to be send [number of players] times by the server, so having slim AI order/action messages will be critical.

Synchronization over Network:
Synchronization is a bit tricky in a game with tons of objects, if you synchronize all objects every few second, you will probably run out of bandwidth. Though if you don't synchronize them frequently enough, desynchronization will happen, which is bad because one or more players might be playing an entirely different game from others..
Server Client model should minimize desynchronization, but it does come at a price:the reduced responsiveness when you are issuing orders, executing commands as non-server player. Basically you have to do:

1.Someone needs to issue order 'move to X' for my ship with id 123
3.Server receives Request and Process, if it's a valid order then send granted Request to all connected players
4.The original Request Sender being one of the connected players, so he receives granted Request and his ship begins to move to X eventually..

In-game join:
To join in game you probably need to download the last server game save and synchronize with all server's game states. I think there is no other simple and efficient way to do this..

Handling Dropped Player/Player X has left:
The best way of doing this I have seen is openttd's: when one player drops/leaves his units/buildings remain intact but got taken over by AI, other player or the dropped/left player may join to regain control over his old assets later.

I typed too much again =/


Pathfinding and Map Wrapping rants 2

I forgot that Planet Earth is a sphere...so the map wrap for Y coords is wrong, the intersection of equator and prime meridian divides meridian projection(tile map) into 4 "areas" like this:

Y Max
Y Min

So when your whatever moving object hits Y Max in [NW] area, your ship should reappear at [NE] area with Y Max minus 1..Hitting is Y Min in [SW] is similar except it's Y Min plus 1, also X coords is mirrored when your hit Y Max or Y Min:

X Min[NW][NE]X Max
X Min[SW][SE]X Max

Lets say we have a ship at X(100), Y(MAX-1) on 1000x1000 map(starting index 0):
[NW]'s X coords range would be 0-499
[NE]'s X coords range would be 500-999

When ship moves towards Y axis positively(north) by one, the ship reappears at X(999 - 100), Y(MAX-1)...It's very confusing, even on papers, in game the renderer needs to flip all tiles that have been "Y wrapped"(the "wrapped" tiles are on the other side of the sphere, so they are upside down and mirrored.It needs to draw from right to left and swap point 1,2 with 3,4 on quads...)

Though i will ignore this issue for now, since it's tolerable and in 1500's no ship could reach max Y(northpole) or min Y(southpole) intact... =o


Site updated

Updated the site hosted by sourceforge.net site to a few table-layout html pages with contents ripped from forums, it's definitely better than the old good blank page with 2 links. =)


Pathfinding and Map Wrapping rants

Okay, here is the rants about Pathfinding and Map Wrapping in Ocean Horizons,they are royal pains really, why? Let me explain:

Pathfinding on HUGE tiles map:
Initially I naively thought a decent pathfinding algorithm will solve the problem, so I ripped borrowed A* Array implementation codes from an excellent pathfinding example program called PathFinder2D, but soon I realized pathfinding on a HUGE tile map will be a CPU hog, not to mention the enormous overhead of memory used by PathPlanner to store tile information like block status, open/closed flag, terrain type and stuff.

I have to make a simple and stupid pathplanner that only plans next node to move towards, basically it loops through 8 directions and find the one that is closest to the destination, it sucks but works.Probably a last-node needs to be passed to that function to avoid lock between 2 tiles.

Additionally a navigation graph needs to be incorporated into pathfinding system, once the graph is contructed, the routes between nodes are trusted, which means there is no obstruction between 2 linked nodes in graph, so pathfinding is not needed when doing long distance traverse.

Map Wrapping:
What is Map Wrapping?You may wonder, Map Wrapping is wrapping the coords when reaching map edges, it's a must because planet Earth is not flat, at least in our game. So whenever the map reaches edges(MAX_WIDTH or MAX_HEIGHT), the map needs to be wrapped to X-0 Y-0 again, this sounds easy enough, but there is tons of stuff that need to take Map Wrapping into consideration:

When units move to a coordination that is larger than max x, max y, you will need to cap it.
When screen draws tiles x, y bigger than max x, max y, you will need to draw the wrapped ones.
Distance between tiles calculation must checkwhether the distance is greater than 1/2 of map height or width, because distance between X-1023 and X-1 is actually 2 on a 1024 width map, but you might get broken result 1023-1 if you don't..

Hopefully I will be able to resolve these headaches gracefully. =D


Source available at sourceforge svn

You can check out the source code via sourceforge svn now:


Or browse my hacks magick via sourceforge viewvc:

Browse SVN

Currently it's far from playable,though I would like to make the development more transparent to others.


Progress on pre-alpha part 3

I am having a problem with map at the moment,I will need to either store mover objects pointers in map tile or make collision-test on all objects every frame,apparently the latter sounds a bit stupid,but pointers-in-maptile has its own problem:

In Ocean Horizons,each tile is 32 by 32 pixels big,so in order to represent the 'world' at an acceptable size,I will need tons of them,more precisely 1024x1024+ of them,in a worst case scenario,there might be few hundreds objects overlapping each other in one tile at a time,let's say 200,then there will need to be 1024x1024x200 pointers,in 32bit it's 1024x1024x200x4 bytes or 800MB,in 64bit it's 1024x1024x200x8 bytes or 1.6 GIGABYTE!Now this sounds even more stupid than the collision-test on all objects every frame idea.

Perhaps I should allocate them dynamically,but a pointer pointing to array of pointers on each tile doesn't sound like a good solution either.Hopefully I will get this problem sorted out soon.


Why OSS game developments suck

Firstly, this is not a rant about OSS game developments(Open-Source-Software for those that don't understand geeky abbreviations), so don't take it personally.It's just some random thoughts I have after observing various OSS game projects.

1.retarded precise versioning
Almost all open source games use a 3 tier versioning technique,that is,Major.Minor.MinorMinor,as you may wonder:WTF is MinorMinor? MinorMinor is the actual version number that gets incremented by 1 every time a release is published.An example
game version 0.0.1(initial alpha)
minor release = 0.0.1 + 0.0.1 (takes 1-3 months)
major release = 0.0.1 + 0.1.0 (takes about 10 minor release)
breakthrough = 0.0.1 + 1.0.0(takes about 5 major release)

So...let's work out the formula
Development of an Open Source Games would take 5*10*(1-3months) or 50 months to 150 months to reach 1.0.0,I bet most players will be scared after reading this if they do play 0.0.x version of an OSS game.

2.Irresolute Cautious to do release
OSS developer always over-cautious about the quality of a release,whether it's alpha,beta or release candidate,this further increases the delay between minor releases.

3.More people make the project's development faster???
OSS developers believe more developers will make the project's development faster,this is simply NOT the truth.Sometimes 1 good developer with iron-fist style development style will be a lot faster than 2 good developers or more,since with more than one experts in one field,the actual works on code will be replaced by endless flamewars expert-exchanges between the developers.

4.Write perfect game not perfect code and documentation
An impatient player who cares only about graphics will take a look at the in-game graphics and say:this game looks like 80's,then uninstall it and never install it again.

An average causal player who cares more about gameplay will play the game for a few minutes,and he will uninstall this game if the controls/user interfaces is uncomfortable.

The most patient and wise player will try his best to play throughout the game and will only uninstall this game if it has no replayability or depth.

5.Mess with the best die like the rest
Exist libraries have been used/field-tested for years and they are ready for production,while some developers irresistibly want to write libraries from scratch for their game,because they think the exist wheel is not good enough,unfortunately their ambition usually ends up as a broken wheel,with a broken lib/core the game project's death will be imminent.

6.Get bound by your own freedom
What would you feel if your painting can be reworked by anyone including those who are not even artists and those who alter it in a destructive way?
To satisfy the project host,distro distributors,OSS project admins are forced to dupe convince the artists to release their arts under GPL/CC-by-sa.This behavior particularly pisses artists off,cause artists care more about the integrity of their arts and their names being mentioned as original author.

Please note that avoiding the problems I listed won't guarantee your project success,but it should help prevent your project from being slow-downed or killed by the pitfalls that creep in OSS game development.The key contributes to an OSS game project is still your dedication,and the best way to motivate yourself is to play and learn to love the game you are developing.


Progress on pre-alpha part 2

I was mainly working on Opengl renderer,the SDL blit speed is simply not good enough for 32bit color tiles,with 800x600/32x32 tiles and 256 Guichan image buttons,an optimized windows/linux release build linked against release version of SDL(provided by SDL site/distro,assuming they are O2) runs at approximately 10fps,while a debug one runs at about 5fps on windows/3fps on linux.
Now Opengl renderer is working and it has much better performance than SDL,but it will require a 3D card that supports 1.1 version of opengl.
Data loading via GM is sorta working,I can load info of different ship parts from .gm files.Current goal is to make a working ship sprite with 8 directions(45 degree per frame),so I could test the mobile object class I wrote earlier.Another goal is keeping both texture size and texture amount as low as possible,my goal is keeping total amount under 32MB.

32MB = 32 * 1024 * 1024 B = 32 * 512 * 512 * 4 B = roughly 32 512x512 32bit bitmap's

Wow that's a lot,now I should really stop talking to myself on this lifeless blog and get back to coding. =)


Progress on pre-alpha

I registered and created a project on sourceforge.net(and they approved my project,thanks sourceforge.net).I will import local svn repository on my harddisk into sourceforge.net as soon as test data is relatively complete and compile-able on both windows and linux.
Actually I have been working on this project for more than half a year now,but due to other projects draining most of my spare time,it did not progress very well =(

I wrote a simple tile drawer using SDL_Blit functions,but it's more 3d orientated than 2d orientated,so the performance is a bit unacceptable with 32bit per pixel.I might consider using OGL to do the pixel fill instead.

Current renderer features:
  • Draw background layer(draw an image before anything else)
  • Draw grids(a hack to draw 4 (1*TileWidth) rect to resemble grids around a tile)
  • Draw tiles
  • Per pixel scrolling
Despite all the crappyness,I still considered my renderer an improvement compare to the original game's render,because the old one was 1994 and it did not even support per pixel scrolling if memory serves me right.

Current Input system uses SDL input events,I added some basic features such as doubleclick and hold.

  • SDL input based input
  • double-click handling
  • hold handling with duration
GUI uses guichan library,which is probably the best and the most versatile GUI library available,its forums and its author are also very helpful,for a list of features it supports please refer to guichan's site: http://guichan.sourceforge.net

I use gamemonkey(GM) script,which is an underrated/unpopular scripting language designed specifically for games.GM supports universal table(any element in any table can be any data type) like LUA but GM is more powerful than LUA for games.

Currently GM is only used for data loading and storage.

Sound and Network:
No time has been spent on them yet,they have the least priority in my todo list. =)

That's all for now.


Magick Panda' FAQ

Q:What is your hobby game project?
A:It's an open-source clone of old school SNES game named Uncharted Waters: New Horizons Also known as Daikoukai Jidai II in Japanese,firstly released in 1994,with a superb graphics which is utterly unacceptable for you modern peeps who are accustomed to state-of-art 3D graphics.

Q:What is your game's goals?
*Top-down plain 2D game 32bit graphics(this roughly quadruples the amount of pixels to fill compare to 8bit(256),so 3D acceleration might be needed)
*All functionalities from original game
*Small scale MP support 2-8 players

Q:Ah you mentioned open-source,License?
A:code and contents I created will be released under GNU GPL V3

Will add more later

Magick Panda's blog test

I am never a fan of blog hype nor am I like writing articles and shytz online like most others do,but I would like to open a blog for my hobby game project.

This is a test post.