17 Nov 2007

AC's Political Correctness BS

Assassins Creed displays something along the lines of "this product is a work of fiction and has been produced by a multiethnical team of various religious beliefs" when it starts up. This is the most hilarious/concerning quote I have ever seen in a video game. They should have written instead "we are a scared bunch of spineless pussies who are afraid that our studios are blown up by christian and/or muslim fundamentalists". What's coming next, a disclaimer in a World War 2 game, that members of various - uh - political beliefs have worked on the team just to appease the nazis and communists? The end is near I say.

The game is much more controversial where it probably didn't intend to be: game-design and game-play. There are many things I absolutely love, and one or two things I absolutely hate. I haven't played through yet, so I'm not qualified to write a "proper review", but I think I can already say that it is definitely a must-have game. It does many things different then the mainstream, and that's already enough reason to buy the game, even if it tries sometimes to be too innovative and too avant-garde which may put off some players. We'll have to see how it does commercially. I hope it does well to demonstrate to publishers that innovation may actually pay off. As a gamer I'm usually more conservative though, a game should do at most one or two completely new things, and use established mechanics and even clichés for all the other elements in the game, otherwise I'm not really feeling comfy and at home, especially in the beginning of a game. On the other hand, some games have to be the forerunners and crash-test-dummies for new game-play mechanics. Otherwise we'd still be stuck with Pong.

15 Nov 2007

Nebula3 November SDK

Alright, here's the new Nebula3 SDK: http://www.radonlabs.de/internal/n3sdk_nov2007.exe

Some notable new features:

  • first version of the Application Layer plus a small sample app
  • now also works on ATI cards which support shader model 3.0 (X-above-1000)
  • a new global light source type
  • resources now loaded from zip archive
  • many bugfixes

There are a quite few known issues in this release:

  • some (new) VSM-related visual artefacts in the shadow system (light leaking and shadow grain near some shadow casters), this must be fixed by tuning some VSM parameters which I didn't quite have the time to do right
  • new Application Layer sample app has clumsy controls and camera
  • shadows are not rendered when shadow caster is not visible which leads to shadow pop-up in the App Layer sample application
  • re-building assets requires the Nebula2 Toolkit For Maya
  • some new Doxygen docs pages are messy
  • ODE, OPCODE and GIMPACT not credited yet in the docs

So this release is a bit rough, I hope the next one will be more polished. But I really wanted to push it out the door instead of spending even more time to fix stuff.

Here are a few screenshots:
This is the testviewer.exe with one global light (cannot cast shadows yet, I'm planning to implement Parallel-Split Shadow Maps for global light sources), plus 2 spot lights which cast VSM shadows.

The next one is a screenshot of the new testgame.exe sample application, with a player-controllable avatar and some physics boxes to play around with:


Enjoy!
-Floh.

12 Nov 2007

COD4

Call Of Duty 4 rocks in every aspect. No point in babbling about it here, you really have to see for yourself. If you only play one FPS this year, make it COD4. If the game would have a R6-Vegas-style cover system, it would reach critical mass and collapse into a singularity of pure gaming perfection, thus destroying earth and human civilization. Maybe that's why they left it out.

4 Nov 2007

Shadow Fixes

Phew, I think I have fixed most of the pressing problems in the VSM code. I didn't manage to get the number of executed instructions in the pixel shader down to a reasonable number with dynamic branching as I was hoping. So I went the shader-library way and added shader variations for 1 local light, 2 local lights, etc... up to 8 local lights, so that performance with a low number of dynamic lights has become dramatically better especially on graphics cards with low fillrate (shader optimizations aren't a big priority yet however). Shader model 3.0 still has some annoying restrictions when trying to do a single-pass/multiple-light shader, so the übershader approach isn't very practical in the end. Hmpfh. I'm almost starting to consider deferred lighting... at least as a second option. Shadow quality has been improved a little bit because some bugs in the 2x2 downsample and gaussian blur filters have been fixed, finally I'm now emulating bilinear filtering when sampling the shadow buffer in the pixel shader so that shadow borders should now be properly smoothed also on cards which don't support bilinear filtering of G16R16F texture formats (like ATI's).

I'll try to get a new SDK out of the door next week, it's a little more complicated to coordinate a release now that 3 people are actively working on N3.

Bored To Death

Alright, I think I've had it with JRPGs. Eternal Sonata came out 2 weeks before in Germany. I've enjoyed the demo quite a bit actually so I gave it a try. The graphics are very, very pretty, and technically the game is very solid. But: story and gameplay ... oh where to begin... what the fuck is up with the cutscenes? Very pleasing to the eye but even the cheapest, most shittiest German telenovela is more entertaining. On the one hand, everything is so extremely childish that if I would be a 10-year old boy I would be completely embarrassed to watch this shit. On the other hand it's about heavy stuff like drug abuse, terminal illness, revolution and war. WTF? And they are tooo loooong. I swear it took 15 or 20 minutes of completely useless chatter until the game actually started. Well at least it's possible to skip the cutscenes... which brings us to the second problem: gameplay. This game is so extremely linear that watching a DVD offers about the same set of choices. You can pause, rewind, or go forward. There is almost no sense of exploration, no choices in customization (everything is just linearly upgraded), shops are pretty much useless, they basically just offer to buy some piece of equipment which you may have missed in the previous area during exploration (and it's nearly impossible to miss something because every treasure chest is right near The Way). Combat is actually quite fun because it's more action oriented compared to the traditional purely turn based battle, but it's too repetitive to keep me interested in the long run (yes, my attention span has suffered a lot since I switched to console gaming). Eternal Sonata has a very pretty, expensive looking shell, but unfortunately it seems to be completely hollow inside.

On to something completely different: Naruto! I never heard the name in another context. Guess it's some anime that's currently running in the USA, maybe here in Germany too on some obscure TV channel. I've seen the pretty screenshots, read some good things about the game, so I bought it in favour of the Orange Box which came out last week as well (Portal will have to wait a little bit I guess). And the game doesn't disappoint at all. The graphics are really impressive: stylish, great, consistent art direction and a lot of attention to little details. I've spent quite some time just running around in the world and looking at all the pretty scenery. Gameplay is a shameless mixture of GTA and Tekken with a very little bit of JRPG.... aaalriiiight, let me explain: The GTA aspect is there because the village where the game takes place is basically your sandbox where you can run around and solve small quests and do errands for the villagers. At the start of the game everybody hates you because you're that small annoying little brat who wants to be a ninja. By helping the villagers with their problems, more and more of them start to like you, which is good because villagers that like you can give you directions in future quests. The JRPG aspect is there because combat doesn't take place in the game world, but as you encounter an enemy, the actual fighting will happen in a small fighting arena just as in a typical JRPG (thankfully that's where the similarity to JRPGs ends). The combat is just like in an arcade fighter with simple combos, blocking, throws and special attacks. The special attacks are especially funny, because they are accompanied by absurd and completely overdone anime effects SHADOW-CLONE-JUTSU!!! Blam-Blam-Splat-Wooosh!!! You get the general idea :) They even managed to sneak Quick Timer Events into the game in a way that isn't annoying, which earns an extra point because usually I hate QTEs. The story is told through traditional 2D anime clips which look like they're taken directly from the original TV series and is - well... mildly entertaining to me, but probably a big deal for fans of the original series.

3 Nov 2007

The Nebula3 Application Layer

Nebula3's Application Layer provides a standardized high-level game framework for application programmers. It's the next version of Mangalore (Nebula2's application framework) integrated into Nebula3. N3's Application Layer is the result of years of refactoring (one could say that this started with our very first big project "Urban Assault" 10 years ago). Mangalore has now reached a rather stable state, where no "big" design changes are intended in the foreseeable future. Thus programmers familiar with Mangalore will immediately find their way around in the Nebula3 Application Layer.

Mangalore had officially been started in 2003 when we learned the hard way that it is critical for an independent developer to work on several titles for several publishers at once to spread out the risks (German publishers have the unfortunate tendency to go nearly bankrupt quite frequently). So one very important design goal for Mangalore was to provide a common game application framework for a company where several teams work on game-projects of different game genres, and most importantly, a game-framework which enables us to do small - yet complete - games in a very short time-frame (our canonical "most minimal project" has a 3 month production-time-frame, and a team size of 5 people full-time (2 programmers, 2 graphics guys, 1 level designer), plus a half or third of a project manager). To make a long story short: building several "small projects" in parallel is many times harder then doing one "big project" because there are many parts of a game-project which simply don't scale down with the overall project size. On the content side, our strictly standardized asset pipeline in the form of our toolkit was the precondition for our multi-project strategy because it enabled us to switch modelers and animators between projects with practically no overhead (for instance it is not uncommon to build all graphical assets for a small project in only a few weeks, to directly share character animations between projects, or to have key people (like for instance character animators) help out in another project for a few days).

Mangalore (and now the N3 Application Layer) basically tries to solve the same problems in the programming domain, to enable our application programmers to start a new project with very small setup-overhead, and to help implement its game-play features on-time and on-budget. The following bullet points are probably the most important Mangalore features:

  • provide a fully functional generic "skeleton application" so that something is visible on the screen from Day One of the project
  • integrates with our standardized level-design and modeling work-flows, and thus provides a common "social interface", mindset and vocabulary between our programmers, modelers/animators and level-design guys
  • has very few, very strictly defined concepts how an application should implement its game-specific code (it's relatively easy for a Mangalore programmer to decide the "where" and "how" questions when faced with the implementation of a new game feature)
  • it's modular enough to enable a team of programmers to work on the game-logic without stepping on the other programmers' feet too much
  • "New Game", "Continue Game", "Load Game" and "Save Game" are standardized features (that's an important one: Load/Save works right from the beginning, and mostly without requiring the programmer to write a single line of load/save-related code)
  • provide a growing set of reusable modules for future projects (we formalized this a bit more in the N3 Application Layer compared to Mangalore by introducing so called "GameFeatures")

The Application Layer is built around the following basic concepts:

  • Entity: a game object, container for Properties and Attributes, manipulated through Messages
  • Property: implement per-entity aspects of game-logic
  • Manager: implements global aspects of game-logic
  • Attribute: key/value pairs representing the persistent state of an Entity
  • Message: used for communication between entities
  • GameFeature: groups Properties, Managers, Messages and Attributes by functionality

An Entity represents a single game object, like an enemy space-ship, the player avatar, or a treasure-chest. An important aspect of the Application Layer is that the class Game::Entity is not sub-classed to add functionality, instead Attributes and Properties define the actual game functionality of the entity. We learned very early that representing game objects through a class hierarchy in a complex game project brings all types of problems, where spaghetti-inheritance, fat base classes and redundant code are just the obvious ones (let's say you do a traditional realtime strategy game with vehicle units, so you create a Vehicle class, and derive a GroundVehicle and an AirVehicle class, which can implement navigation on the ground and in the air respectively, but now you want to add combat functionality, hmm... create a CombatGroundVehicle class, and a CombatAirVehicle class? Or would it be better to create a CombatVehicle class and derive GroundCombatVehicle and AirCombatVehicle? But wait, some of the vehicles should gather resources instead of fighting... you get the general idea, I think every game programmer faces this problem very early in his career).

That's where Properties come into play. A property is a small C++ object which is attached to an Entity object and which adds a specific piece of functionality to that entity. For instance, if a specific entity type should be able to render itself, a GraphicsProperty is attached, if it should be able to passively bounce and roll around in the game world, a PhysicsProperty is required, if an entity should be able to control the camera, a CameraProperty is added, and so on. Or for the above strategy game, a GroundMovementProperty, AirMovementProperty, CombatProperty and a GatheringProperty would be required, which are combined to create the functionality of the different unit types. Ideally, Properties are as autonomous and independent of each other as possible, so that they can be combined without restrictions (in a real world project, some Properties will always depend on each other, but experience has shown that the resulting usage restrictions are mostly acceptable). Properties pretty much solve the inheritance-problems outlined above. A new entity type is not implemented by subclassing from the Game::Entity class, instead new entity types are defined by combining several specialized properties.

The next problem we need to solve is the interface and communication problem. Properties need to communicate with each other (either with Properties attached to the same Entity, or with Properties attached to other Entities). Calling C++ methods on other Properties would ultimately introduce a lot of dependencies between Property classes which we want to avoid because this would very soon result in the same set of restrictions we just solved by fixing the Entity-class-inheritance-problem with Properties. Virtual methods would help a little bit because it would limit the dependencies on a few base classes, but this would just move the inheritance problem from entities to properties. Messages are used to solve this dilemma. Think of a Message as the next abstraction level of a virtual method call. While a virtual method call requires that the caller knows a target object and a base C++ interface, a Message just requires the caller to know the target object in the form of an Entity but no specific interface. The Entity will route the Message to interested Properties which will ultimately process the Message. The caller usually doesn't know which Property processes a Message, or whether the Message is even processed at all.

A C# programmer would now raise his arm and remark that this is exactly what Interfaces, Delegates and Events are for. And of course he's completely right. Alas, we're working in old-school C++. There is however more room for optimization in the Application Layer in the future (for instance, Message dispatching could be optimized by implementing a delegate-like mechanism).

Attributes are typed key/value pairs attached to entities. Each entity has a well-defined set of attributes which completely represents the persistent state of the entity. Attributes are used to describe the initial state of an entity, and to save and load the state of an Entity using the standard Load/Save mechanism of the Application Layer. Usually, a specific property is responsible for a subset of the entity's attributes. As a general rule, a specific attribute should only be manipulated by one property, but may be read by everyone.

Many features of a game-application don't fit into entities and are better implemented in some central place (the overall code design of some of our early projects suffered a lot from failing to understand that NOT EVERYTHING is an entity). For instance handling input or controlling the camera in one central place is sometimes (often?) better then spreading the same functionality over several Property classes, which then may need to spend a lot of effort to synchronize and communicate with other properties). Those global aspects of game-logic are put into subclasses of Manager. Managers are typical Singleton objects and usually provide services which need to be available "everywhere" in the game code.

Finally, a GameFeature is a new concept which didn't exist in Mangalore. A GameFeature is more or less just a nifty name for a bunch of source files which compile into a static link library consisting of related Properties, Managers, Messages and Attributes (all of them optional). GameFeatures are mainly an infrastructure to encourage and standardize code reuse between projects. The idea is that at the beginning of a project the lead programmer starts by picking and choosing from the existing set of GameFeatures those which suit his project, and (ideally) to group new functionality into new GameFeatures which may be of use for later projects. The Application Layer comes with a small number of standard GameFeatures, enough to implement a generic 3D application with a player-controllable avatar, chase camera and passive physics for environment objects, but it's really intended for more complex stuff, like a dialog system, a generic inventory system, or lets say, the guts of a typical "horse riding game" ;)

The Application Layer isn't perfect and doesn't solve all problems of course. For instance it may be difficult to decide whether a piece of functionality should better go into Properties or into a Manager. Also, a typical problem we are frequently facing is that functionality is split into too many, too small parts which results in too many, too fine-grained Property classes, which in turn requires too much communication between those properties. So a project *still* needs an experienced and pragmatic lead programmer which lays down the basic infrastructure of the code at the beginning of the project.