Wednesday, November 10, 2010

Development diaries - August 2010 archive

Still working towards loading a complete level for Tiled into the game. It is almost there, it needs a bit of ironing... Additionally we need to determine what properties will be specified for each object in the Tiled editor, as well as create some predefined animations for the enemy ships. Looking good so far.

Still haven’t looked into texture specifications and other stuff for the artists. Hopefully I’ll do this tomorrow.

The game is now data driven! Enemy (spawner) objects are positioned and customized with data loaded from the Tiled Editor map file. Committed changes and new files (Commit #13). It still needs some testing but the main functionality is there. Have to discuss with George what parameters the designer needs to set for each object.

I also added some texture specifications to the Cocos2D engine doc. We still need to determine the actual texture/sprite sizes for the game.

Changed EnemySpawner and tilemap import to take number of Enemy Ships in each wave and not time-to-live. I feel that this is a more intuitive way to set the wave, must check with George at the next Skype Meeting.

I also did some game code profiling today, I’ve already caught a silly bug. According to Shark (profiling tool provided by MacOS) the tilemap is very expensive, since it takes about 50% of the game time (updating and rendering), if I am reading it correctly. To be more specific rendering costs ~30% of the total time. An the rest 20% is CPU tilemap update and draw call overheads.

Currently the tilemap is 1500, 32x32, sprites which use minimal OpenGL state change and a SpriteSheet for texturing purposes. So rendering should be quite cheap one would think. I have read in forums that it is beneficial to break the tilemap up into smaller tilemaps during loading and use them instead of a single large tilemap. Maybe I will have to look into this.

As requested by our game designer I added a “heavy” level to the game. The tilemap had 90x20 tiles (32x32 pixels) each, which meant double-width screen. In order to accommodate this I had to add a camera to the layer in order to allow the player to “scan” the whole level. Apart from the background tilemap I added an additional (parallax) one with some planets.

It should move at different speed to the background one but it does not at the moment. Finally I added an Enemy Layer with 24 spawners generating enemies at various rates. Also, I made all enemies shoot the player (although not kill it) creating a bullet rain almost throughout the level. Particles explosions (fire+sparks) remained as they were. To top it up, I added background music to the game.

Although this set -up is not realistic, it nevertheless stressed cocos2d quite a lot. There are times, when the screen is full of enemy sprites, bullet rain and explosions that the frame rate can drop as low as 20 fps. A final note, the new camera stuff broke the UI sprites, although one can still navigate and shoot lasers using the same areas (bottom-right and left). I committed everything back to SVN with commit #16.

There are a bunch of optimisations I have in mind to speed things up in terms of raw rendering power. First I will batch enemyship rendering at least per enemyspawner, or more. Particle explosions can be sped up as well using fewer draw calls to render them. Finally the tilemap should be split up into smaller ones, to allow for visibility culling. This should send smaller drawlists to the GPU and hopefully make the expensive tilemap a bit faster.

Converted enemy ships to use a SpriteSheet (one for each enemy type) instead of individual textures, in order to make them render all in one draw call (batch rendering). Benchmarked the 30 first seconds of the “heavy” level, it seems that total scenegraph update time goes down from 1940ms to 1340ms and total rendering time goes down from 7350ms to 5390ms. It does make a difference, although this level is not representative of a real level as it has way too many enemy ships. Every little helps though. Eventually I will do the same for the bullets as well. The tilemap will be trickier though.

I also reduced the camera viewport in order to prevent the player ship to be hidden from the UI controls. Now there is space at the bottom of the screen to add the virtual joystick, life bar, weapon selectors etc. Committed everything with Commit #18.

I changed the layout of the Game Design guide in order to make it more playership centric and in the process I created even more work for George. :-). We need thorough descriptions of each playership type, weapons and upgrades since we should start implementing those feature soon.

I also reworked scene and layer layout of the game in preparation for the implementation of the menu system. As a test, I added a simple menu with a few options (only one works). I also added a NetworkManager class for George to play with. Committed with commit #20.

Still haven’t worked on the TiledMap protocol document, hopefully I will do this tomorrow.

Started to gradually add new classes for the game objects described in the design doc. Soon enough I got lots of similar classes. Extension through inheritance for some many similar objects seems rubbish, I am contemplating using composition, or at least some data-driven way of creating the game objects.

I’ve also started working on the Tiled how-to guide, in order to specify a protocol of creating the game level and reading them into the game.

Updated game with George’s submission to SVN and it builds fine. So as long as he doesn’t touch the project file, it should be ok to develop code collaboratively even if we have different SDK (most of the time at least).

I put the Tiled how to guide on hold until I decide how to design and implement the various the game entities in code. Inheritance becomes quite inflexible ofter some subclassing since the number of classes grows a lot and it is not easy to combine object behaviour.

A very interesting alternative is component systems, which uses composition instead of inheritance. While very tempting and flexible, I do not know how fast this approach is, especially on the iPhone... Yet there are some games that use this architecture (Dungeon Siege, Munchee’s Oddysey) as well as game engines such as Unity. Maybe there isn’t a significant impact on performance after all.

Finally, I added initial functionality for debris as well as changed the code file directory structure. Committed everything with commit #23. I hope SCM picked up the folder changes...

Worked on an upgradable weapon system... weapons are now individual entities that can be attached to player ship or enemy ships. I also added a separate PlayerShip class to better manage the player’s ship. No commit yet, I will refine and commit tomorrow.

Added upgradable weapons as well as a bonus system to the game. The player’ ship can now upgrade the weapons according to bonus items created in Tiled Editor. Added a bunch of classes and managers to perform said functionality (Commit #25).

Worked towards making the game data driven. Now, enemyTypes and spawners are defined in Tiled. I also removed any extra classes for Enemies, all enemies will now be of type EnemyShip. As a test I added a new tilemap which defines a new enemyType named SlowFighter and it works fine.

In terms of triggering enemy spawners, I removed the need to define a trigger since it was not very intuitive to understand how large it should be. Instead, I now only use the spawner location to specify when the enemyspawner should start spawning. In order to keep the spawning process invisible to the player, I slightly move the spawner upwards along with the viewport in order to always remain just out of sight. It works fine this way and is much easier to place enemyspawners in the world

Also, speed in now measured in pixels per second. Finally I made the game use a “real” camera, in the sense that now the camera moves relative to the background which remains static. Committed everything with commit #27. Next I will work towards making weapons definition data-driven as well as enemyship animations which are now fixed.

Data-driven bliss! Enemies, enemyspawners and weapons/bullets are now defined in Tiled and subsequently created in code. Weapons are now game entities that can be assigned to any space ship (enemy or player). The only thing that is not data-defined yet is enemy animations since we haven’t decided how they will be implemented.

Also camera scroll speed can now be set in Tiled as well, as a property (CameraSpeed) to the background layer. With the latest commit (#29) i have broken bullet collision and bonus items, will fix with next one.Finally I have added the interceptor ship created by Nick to the game, it is not that bad, although it feels a bit small!

I have second thoughts about the way I have implemented the various managers of the game entities... Fearing that creating new cocos2d nodes every time I need a new enemyship or bullet etc I have created pools of entities that I never delete but reuse each time I need a new object... This now seems unnecessarily complex...

According to cocos2d best practices, creating new nodes every frame is possibly expensive, but we hardly create new enemy ships or bullets every frame... maybe a simpler solution of keeping an array of “live” entities and releasing them when not need is preferable. The problem is that I don’t have the time to test this...

Anyhow, the need for programmers becomes less! Long live designers!

Kostas Anagnostou

No comments:

Post a Comment