10 Nov 2009

Drakensang River Of Time - Personal Edition

Check this out: www.amazon.de/amflussderzeit

Amazon starts pre-ordering for the super-limited German *personalized edition* of “Drakensang - River Of Time” with your own name on the box. First time any game offers this, as far as we’re aware at least. I really, really dig the DVD box cover by the way. We got some of those posters a few days ago and they’re simply admirable :o)

5 Nov 2009

Nebula3 SDK Nov 2009 Changelog

Here’s the new N3 SDK: download link

As always, this only includes the sources for the Win32 platform. Console platform specific source code (Xbox360, PS3 and Wii) is not included for obvious legal reasons.

Here’s a rough change log since the Apr2009 SDK:

 

== Major New Features

  • unified XNAMath support on Win32 and Xbox360 platforms
  • PS3 support (not part of public SDK, but lots of fixes for GCC 4.x in platform-agnostic code)
  • HTTP filesystem wrapper now working properly, this allows to create standalone N3 apps which load all their data from an HTTP server (see testhttpviewer.exe for an example)
  • “binary XML” support for much faster loading of big XML files (circumvents TinyXML)
  • new “FrameSync” system for running main and render thread in lock-step
  • new “Jobs” system to implement parallel jobs (CPU-thread-pool on Win32 and Xbox360, SPUs on PS3)
  • window parenting, it’s now possible to open the render window as a child of another window, this makes it possible to embed N3 into another Windows application
  • FMOD integration 

 

== Foundation Layer

Core

  • new Debug::StringAtomPageHandler to inspect string atom table from web browser
  • type casting methods optimized in Ptr<>
  • optional allocation from memory pool support for RefCounted objects (currently unstable!)

Util

  • Win32StringConverter: helper class to convert between UTF-8 and wide character string (currently only on Win32 platform)
  • Util::Array::InsertSorted() now returns index of inserted element
  • new Util::BitField<> class to allow bit mask operations on masks wider then 32 bits
  • removed classes of old string atom system: Util::Atom<>, Util::Proxy<>
  • new method Util::FixedArray<>::Resize()
  • classes for new string atom system: Util::StringAtom, Util::StringBuffer, Util::LocalStringAtomTable, Util::GlobalStringAtomTable
  • new method Util::Queue<>::Reserve()
  • new direct access methods in Util::RingBuffer<>
  • new method Util::Round::RoundUp()
  • new class Util::SparseTable, for 2D data tables with a lot of empty cells
  • Util::String:
    • new method CopyToBuffer()
    • new optimized versions of Tokenize() which fills a provided string array with the tokens, allows to reuse an existing array object
    • new static wrapper methods: IsDigit(), IsAlpha(), IsAlNum(), IsLower(), IsUpper(), StrCmp(), StrLen(), StrChr()
  • new util functions to help with “type punning”

IO

  • BXmlReader: stream reader for “binary XML files” (created by the new binaryxmlconverter3.exe utility)
  • some low-level-optimizations in ZIP filesystem wrapper
  • application root directory stuff moved from AssetRegistry into Core::CoreServer
  • new class GameContentServer, used to properly setup game data on some console platforms
  • added support for http: and httpnz: schemes for reading data from HTTP servers through the N3 filesystem wrapper

Math

  • Xbox360 and Win32 math classes have been unified into XNAMath classes
  • low-level performance tweaking

Memory

  • experimental memory pool support on Win32 platform
  • on Win32 platform, dynamically allocated memory is now 16-byte aligned (NOTE: there seems to be a hard to reproduce critical bug in Realloc() where HeapSize() returns a wrong value)
  • new HTML debug output in Debug::MemoryPageHandler for memory pools

Threading

  • Threading::CriticalSection rewritten with "Fast critical sections with timeout" by Vladislav Gelfer (on Win32 platform)
  • Threading::Event now supports “manual reset” behaviour
  • Threading::Interlocked class now uses compiler intrinsics on Win32 and Xbox360 platform
  • new class Threading::ThreadBarrier: stops a thread until all other threads have arrived at the barrier
  • optimizations in Threading::SafeQueue

System

  • new class System::Win32Environment to access environment variables (Win32 platform only)
  • Win32Registry class now reads registry key values as wide char and converts them to UTF-8
  • type punning fixes in System::ByteOrder

Timing

  • removed MasterTime/SlaveTime system, global timing is now provided by the FrameSync subsystem

Messaging

  • the Message::SetHandled() method was not thread-safe, now uses Interlocked::Exchange() to update its status
  • Messaging::AsyncPort rewritten to allow better control over message handling behaviour through subclasses of HandlerThreadBase
  • new async message handler thread classes BlockingHandlerThread, RunThroughHandlerThread

Net

  • some type punning fixes in debugpacket.cc

Http

  • new classes HttpClientRegistry, HttpStream, HttpNzStream to implement a transparent HTTP filesystem, the HttpNzStream uses client-side zlib decompression to improve download performance

Debug

  • no noteworthy changes

App

  • new application identifier strings AppTitle and AppID, this is necessary for some console platforms

Jobs

  • this is a new subsystem to distribute tasks either across threads in a thread-pool (Win32 and Xbox360) or the SPUs on the PS3

FrameSync

  • this is a new subsystem which implements better synchronization between the game thread and render thread

 

== Render Layer

CoreGraphics

  • parent window stuff in DisplayDevice (Win32 platform)
  • it’s now possible to share depth/stencil buffers between render targets
  • the ShaderServer now parses a dictionary file (created by the shaderbatcher3.exe tool) instead of listing the directory content of the shaders directory
  • removed array support from shader variables (shader parameter arrays are not very portable)
  • some restructuring because of the PS3 port (some classes have been split into a base class and platform specific derived classes)
  • new private method in D3D9RenderDevice: SyncGPU() this is called inside Present() to prevent the GPU from running too far ahead of the CPU (this is a driver-internal “optimization” which can lead to frame stuttering under some circumstances)
  • better control over clearing a render target through clear flags
  • the RenderDevice::SaveScreenshot() method is now responsible to set the MIME type on the output stream, this is because the actually saved MIME type may now be different then the requested type
  • no more byte-order conversion when loading mesh files, this happens in the asset pipeline now
  • new class MemoryMeshLoader, setup a mesh object from an existing VertexBuffer and IndexBuffer object

CoreAudio and Audio

  • the CoreAudio and Audio subsystem are obsolete and have been replaced with the FMOD-based Audio2 subsystem, which “automatically” works across all platforms, please check the FMOD license restrictions for commercial projects!

CoreAnimation

  • the following classes have been removed from CoreAnimation: AnimDrivenMotionSampler, AnimMixer, AnimSampler
  • new file format for animation data: nax3
  • new animation curve type: Velocity, this is used by the AnimDrivenMotion feature

Input

  • no noteworthy changes

Frame

  • minor changes for Pre-Lightpass-Rendering
  • better control over render target clear in FramePass
  • FramePostEffect: rendering a full-screen-quad has been moved into new helper class RenderUtil::DrawFullScreenQuad
  • frame shaders are now loaded on demand
  • new LightServer class: LightPrePassServer implements light pre-pass rendering (a variation on deferred shading, currently only implemented in the PS3 port)

Animation

  • anim evaluation has been “jobified”
  • no more AnimDrivenMotion specific code in Animation subsystem (this is now handled through a new anim curve type which contains velocity keys)

Audio2

  • new FMOD-based multiplatform audio subsystem

Characters

  • skeleton evaluation has been “jobified”
  • on PS3, skinning is now running on SPUs
  • the entire character subsystem has been optimized (essentially rewritten)

InternalGraphics

  • uses the FrameSync subsystem to run render thread and game thread in lock-step (this basically fixes all stuttering problems)
  • more debug infos displayed in web browser through GraphicsPageHandler
  • lots of fixes to the attachment system (character joint attachments: swords, shields, etc…)
  • restructured the Update/Render-Loop for better parallelization support, the idea is basically to make more room between updating an object and rendering an object so that asynchronous jobs have a better chance to finish on time before rendering requires the jobs output data

Graphics

  • some new messages to communicate from the main thread to the render thread (see graphicshandler.cc)

Models

  • nothing noteworthy…

Particles

  • some restructuring for better portability
  • particle updates have been “jobified”

RenderModules

  • no noteworthy changes…

RenderUtil

  • new helper class RenderFullScreenQuad
  • new helper class NodeLookupUtil to lookup a ModelNodeInstance in a hierarchy

Resources

  • nothing noteworthy

== Moved into Addons:

  • fx
  • network
  • locale
  • posteffect
  • ui
  • vegetation
  • vibration
  • video

== New Stuff in ExtLibs:

  • FMOD
  • RakNet

Enjoy!

23 Oct 2009

Drakensang River Of Time Intro

Here’s the intro video of our new Drakensang game (River Of Time):

(Go here for the bigger version)

The cutscene has been created in-engine with our new cutscene editor tool described in one of my former blog posts, and then captured frame by frame and encoded with Bink at 1280x720 (the YouTube version unfortunately looks quite a bit darker then the original if I’m not mistaken). The characters have higher resolution meshes and textures created especially for the intro video, but the underlying joint skeleton and facial animation system is identical with the ingame-characters. The decision to encode the cutscene into a video stream instead of running it in real-time was done early in the project to remove a few risks. We couldn’t be sure what the performance would look like with the high-res assets and all the dynamic lighting, and whether or not a lot of post-processing would be necessary after capturing the raw frames. Turns out that the real-time cutscene looks so good that no “cheating” was necessary, so in future projects we will probably do everything in real-time from the beginning.

The advantage of building and tweaking the cutscene with an instant real-time preview can’t be stressed enough. The intro to the original Drakensang was done the traditional way, short scenes have been built in Maya, rendered over night, and then arranged and cut in some video editing tool. The massive turn-around time between tweaking something and seeing the result was a huge problem and in the end we ran out of time. Creating the new intro video was completely painless and straight-forward. The artists actually had fun creating it (at least that’s the impression I got watching them from time to time hehe), and I think that’s clearly visible in the result :)

10 Oct 2009

Ninja Gaiden Sigma 2

I’ve played halfway through the campaign of NGS2 yesterday evening, with mixed emotions. It’s very obvious that the director of this game has a very different vision of Ninja Gaiden then Itagaki. Sometimes for the better, but most of the times I would not call the changes actual improvements. It’s surprising how many gameplay elements which worked well have been removed. I hope that some of the shortcomings will be fixed in the higher difficulty levels (I’m currently playing on Warrior difficulty).

The Good:
  • Graphics have improved dramatically! The game generally looks a lot crisper (I guess that NG2 was upscaled, and NS2S is native 720p), textures seems to be higher resolution, normal mapping and specular highlight effects have been tuned, it’s really a difference like night and day (in some cases literally, when returning to the Ninja village in chapter 2 it is now broad daylight, not night time). This is what the original NG2 should have looked like.
  • New minions: There are a couple of new enemies in the game, some variations of NG2 minions, and some variations of original Ninja Gaiden monsters.
  • New and tweaked bosses: There are a couple of new boss fights in the game which are variations of the final boss in the original NG2. The Genshi fights are more interesting (you can now do an Izuna Drop on Genshi for instance).
  • Excessive rocket spam removed: that’s about the only good gameplay change, almost all of the “unfair” rocket spam has been removed.
  • Mission Mode now included in the game, plus Coop: Since the original NG2 wasn’t released in Germany, there’s also no downloadable content on the Xbox Live marketplace (damn you Microsoft). NG2S includes a mission mode, and adds 2-player-coop to those missions.

The Bad:

  • Much fewer enemies on screen: this is most painful change. The oh-shit-moments of NG2 when 15 blood-thirsty spider-clan-ninjas where rushing down a hallway, running into Ryu which is starting an Ultimate Technique, turning the whole screen into a mess of flying body parts, and then cleaning up the survivors with a series of Obliteration moves. That’s no longer happening in NG2S. Typically, there are no more then 3 or 4 enemies on screen. Generally, combat encounters are much shorter and easier then in NG2.
  • Slowdown, tearing and in-level loading still there: The dreaded slowdown from NG2 still happens, it’s not happening so often as in NG2, but only because the number of enemies on screen and rocket spam has been reduced. When the slowdown happens it even kicks in sooner, with less on-screen action, then in the original NG2. This is a big let-down. There are places with screen-tearing even when there are no enemies on screen, and the game still pauses mid-game to load data. It’s not game-breaking but disappointing considering that the team had over a year to tweak and optimize.
  • Empty hallways: A lot of combat encounters have been removed from the game, locations which were packed with enemies in the original are desolate in NGS2. I really hope this is just a difficulty level thing, and that there are more encounters in the higher difficulty levels.
  • Fewer choices: some of the design decisions are downright stupid:
    • Weapon upgrades are now limited to a few shops, and the first time any weapon can be upgraded to level 3 is very late in the game (at the start of the Moscow chapter). Weapon upgrades don’t cost any money now however, sounds good at first, but money and shops in general quite useless now (at least in Warrior difficulty).
    • Life Of The Thousand Gods is now immediately activated when picked up, and no longer refills the life bar. This removes a very nice tactical elements from the game (should I use the immediate benefit of having a longer life bar, or should I use it as an additional health potion during the next boss fight)?
    • Same with the Life Of The Gods items, it’s no longer possible to manually activate them when needed, instead they auto-activate when picked up.
The Rest:
  • I actually like the new blood-effect-replacement and toned down violence, it makes the game more arcady and more enjoyable (IMHO).
  • One really starts to appreciate how good the 360’s controller is after 5 or 6 hours of playing with the PS3 controller. My left hand literally hurt after the session.
  • The additional campaign chapters with the new playable characters are disappointing. It’s too little to feel comfortable with the new characters and their moves, they’re limited to a single weapon, and the levels are mostly reused from the original game.
  • They actually tried to fix the story LOL. There’s a “prelude comic” during installation and a few fixes to the cut-scenes during the game to make the story more comprehensible and give it more of a background… as if anybody gives a shit about the story in a Ninja Gaiden game. The result is a complete mess. I can imagine a game featuring ninjas where story actually plays an important part, but not in the Ninja Gaiden universe. It’s really too late for that hehe. The only thing that’s really missing in Ninja Gaiden are pirates, oh … and zombies of course.

If NGS2 is an indication of what the future of Ninja Gaiden looks like without Itagaki then I’m out. The game looks shiny, but the changes to the core game-play are all aiming into the wrong direction for my taste. I was hoping that NGS2 becomes what Ninja Gaiden Black was to the original, a real improvement to an already great game, and if there’s any game which really needs a good polish, it is the original NG2. But NGS2 adds only very few improvements, and abandons too many good ideas from its predecessor. It’s just different, not better then NG2.

6 Oct 2009

Tools of the Trade

We have ramped up tools development at Radon Labs considerably during the development of the two Drakensang games. Traditionally we have been (and still are) a bit conservative about inhouse tool development and try to avoid re-inventing wheels as much as possible. Each new custom-tool requires permanent maintenance work and if a “standard industry tool” exists for a job it is usually better to just use this. But especially in the domain of “game-logic stuff” there are basically no standard tools, so the situation is much more dire compared to graphics or audio tools.

We have traditionally been using Excel tables and XML files compiled into an SQLite database for “game data”. This works pretty well if the number of “work items” is around a few hundred. But for complex RPG games, the number of work items is in the range of tens-of-thousands (quest tasks, dialog takes, voice over snippets, graphics objects, textures, items, NPCs, monsters, behaviour scripts, and so on…). Excel tables and raw XML files don’t scale up very well because they lack game-specific features for filtering, searching, statistics, and of course the possibility of human error is very high, and finding and fixing those errors isn’t much fun either.

 

The Texture Tool

The very first custom tool in C# (to try the waters so to say) was a simple replacement for an Excel table which defined texture attributes (stuff like the size and DXT format of a texture, mip-map quality and so on). The Excel table allowed to give each individual texture its own set of attributes. For a small project with a few hundred textures this works pretty well. Drakensang has around 15,000 textures however, and this is way beyond the territory where Excel is starting to become a pain in the ass. Thus we wrote this:

texture_tool 

The tool manages the same information as the Excel table it replaces, but has much better filtering and manipulation features. The left hand sides gives a tree-view of all texture categories, and it’s possible to either display all textures, or textures of a given category, and it’s also possible to further filter the textures by a pattern (for instance to display all normal textures of the “armor” category, click on “armor” in the tree view and type “*_bump.*” into the top most line of the “File” column. Entering a value into one of the other top-most column-entries will set this attribute value to all displayed textures. It’s a very simple tool, but it’s easy to use and scales up very well to tens-of-thousands of textures while still making it possible to find and tweak a single attribute of a specific texture with ease.

 

The Story Editor

When we started planning Drakensang, we knew that we would need new tools for creating quests, dialogs and game logic scripting. On the surface, these 3 things are something completely different, but for the game core, quests, dialogs and scripts aren’t that different (the common element is the use of Conditions (small C++ objects which check whether some condition in the game world is true) and Actions (similar C++ objects which manipulate the game world)). Thus the Story Editor was born (actually, it’s a Dialog/Quest/Script editor). The Story Editor loads and saves XML files, which are compiled into the game database during the build process, or directly from the tool to immediately check the results in the game. We couldn’t anticipate all required features for the story editor at the start of the project, thus the editor was constantly worked on during the development of Drakensang (we added a lot of features to improve localization, proof-reading or voice-over integration for instance).

Note that the Story Editor currently suffers a bit from the typical “inhouse tool UI aesthetics problem” ;)

Here’s a screenshot of the Story Editor when working on a simple quest:

story_editor_2

On the left is the simple linear task list, the panels on the right show the attributes of the currently selected task (for instance the conditions and actions associated with the task).

Here’s the screenshot of the Story Editor with a simple action script:

story_editor_1

We opted against a traditional scripting language, but instead used a “point and click” approach. A script is just a simple collection of Conditions and Actions. These could just as well be wrapped into LUA functions for instance. Our current approach is probably not as powerful as real scripting system, but definitely less error-prone and easier to control.

Finally here’s the Story Editor when working on a dialog:

story_editor_0

Dialog takes can be associated with Conditions (to show or hide dialog takes based on some in-game condition), or Actions (to manipulate the game world as the result of a conversation). The Comment tab on the right side is most useful to add instructions for audio recording sessions.

 

The Sequence Editor

In the first Drakensang, in-game cutscenes had been hand-scripted by defining a sequence of Actions in the Story Editor, basically in the most un-intuitive way imaginable. For the new Drakensang, we wrote a whole new “Sequence subsystem” along with a new tool (the Sequence Editor) which gives control over cutscenes back into the hand of the artists and provides a very intuitive workflow with instant turnaround times (resulting in a dramatic quality improvement if I may say so). Here’s a screenshot of the Sequence Editor in action on a dual-monitor setup:

 

sequence_editor_0

On the left-hand side is the actual editor, on the right-hand side is the ingame-preview. Tool and game communicate through XML messages over a TCP/IP connection, changes in the tool immediately show up in the preview. The other direction works as well, for instance it is possible to set keys for the camera or objects directly in the preview window, complete with snap-to-ground and other time-savers.

Here’s a more detailed shot of the Sequence Editor:

sequence_editor_1

“Trackbar Elements” from the bottom area (Play Sound, Depth Of Field, etc…) can be drag’n’dropped into the timeline area above. Every trackbar element comes with a number of attributes, most of them can be animated over time. Trackbar attributes are displayed in the right-side column (in the screenshot, I have selected an “Ambience Bubble” element which allows to manipulate the ingame lighting, posteffect parameters, and other stuff which is important to set the visual “mood” of a scene). Animated parameters are edited in the Graph Editor which looks and feels very similar to Maya’s graph editor window:

sequence_editor_2

It’s important to note that complex character animations are not created in the Sequence Editor, instead the sequence system will usually only trigger existing character animations from the character’s animation library. How complex character animation tracks are is up to the cutscene designer. Sometimes its better to fire a lot of small, generic animations and do the path-animation in the Sequence Editor, sometimes it’s better to generate one big motion-capture animation for the entire cutscene, complete with the actual character movement.

One very cool feature of the sequence system is its extensibility. Simple trackbar elements, like “Depth Of Field” or “Camera Shake” can be implemented in under an hour by extending an XML config file which describes the attributes of the new element to the editor tool, and by writing a very simple subclass in the engine which connects the animated values of the trackbar to another subsystem (for instance the PostEffects subsystem in case of the Depth Of Field trackbar).

 

The Table Editor

The new Table Editor is aimed at finally replacing the Excel tables for game object template data. In Drakensang (or Mangalore in general) a game object’s persistent state is simply described by a collection of typed key/value-pair attributes. Different game object categories have different sets of attributes. For instance a Monster game object has a different attribute set then a Weapon game object.

Traditionally, we had one Excel table per game object category, and one line in the table per game-object template. The value of some of the attributes (instance attributes) can be set in the Maya level editor to a different value for each game object instance.

Some of the bigger game object tables became a really critical bottleneck during the production of Drakensang, since only one person could work at a table at a time. Also even though the tables were saved in XML format, both CVS and SVN are pretty much useless for merging.

Thus the idea was born to move the game data tables into a true database backend, and then create one generic “Table Editor” and later on, several smaller, specialized Editor tools which basically provide a different view into the database. This is also the very first step of moving away from Maya as a level editor towards a truly collaborative level design environment.

Here’s a screenshot of the generic Table Editor tool:

db_frontend

On first glance, this just looks like a nifty Excel replacement, but under the hood it is much more:

There’s a complete user system with login and access rights (in the screenshot above, I can see that I am currently logged in as “floh”, and that 1 other user is currently editing the Weapon-Table).

Then there’s a complete revision control system. The table basically extends into the time dimension, and it’s possible to inspect the table at any point in the past. There’s also a very detailed change-log, which not only tells me who modified the table at what time, but also all the changes made to the table:

db_editor_changelog

Of course it’s also possible to revert the content of any cell to any point in time.

When a level designer changes values in a table, it will only happen in a local sandbox (the changed values already live in the central database, but are marked as local data of the user). This allows a level designer to mess around with the tables without affecting the other users. When everything works as expected, the changes are committed into the “global domain” and the new values are visible to all.

The generic database table editor tool is very powerful, but the whole system really shines with specialized front-end editors like this:

db_special_frontend

This is basically just a different frontend to the global game database with a specialized GUI for efficiently equipping characters and chests in the game. The general idea here is that such a specialized editor tool is written for tasks where working with the generic editor is not desirable because it would be too cumbersome, un-intuitive or error-prone.

There’s also a lot of interesting work going on in our build-pipeline at the moment, but I’ll leave this to another post :)

13 Sept 2009

Workload

I’ve been playing around with getting N3 up and running in a pure web environment, running without local installation, pulling all data from a web-server instead of the local hard-disc, embedding rendering into a web-browser and so on. Works pretty well so far, but I’m shocked how arcane and downright silly writing a plug-in for Internet Explorer is. I can’t believe MS hasn’t released a simplified, specialized plug-in API for IE by now, but instead one is still required to dive right into the disgusting cesspit that is ActiveX / OLE. I pity the poor souls who had to make a living in the 90’s grinding on code for OLE or CORBA. Compared to .NET today, this really was software development hell.

On the other hand, NPAPI, the plug-in API for everything else then IE, also hails from the 90’s but it’s clear that it was designed by sane people, and to do one thing right instead of all things poorly: to let people write plug-ins for the Netscape browsers. Embedding N3 into Firefox was a matter of hours. But I already wasted 2 weekends even getting a clear idea how to do the same thing in IE, and every time I’ve finished another doc-reading-session I feel like I must wash my hands.

Gaming! If not for XBLA I would have considered to give up console gaming in the past months and return into the PC camp. Game prices for the 360 and PS3 are simply hilarious right now in Germany. 70 is the new 60 for quite a while now (and 60 Euros was already the outrage when “next-gen” started). Combined with the fact that it feels like half of the games are not even released in Germany it really doesn’t make a lot of sense to own a 360 (or PS3). The new Games On Demand service on Xbox Live just makes things worse. Of course you only get the crappy German versions of games (remember, there’s a hard IP address region check on Xbox Live), and whoever thought that 30 Euros for a 3 year old launch game is a good idea clearly lost touch with reality.

Thank god the UK exists, free haven and last stronghold of console gaming in Europe, where prices are reasonable and censorship doesn’t exist. England is probably saving the 360 in Germany right now. God Save The Queen :)

But not all is bad in the console world. XBLA has reinvented itself during the summer. Games like Battlefield 1943, Trials HD, and Shadow Complex catapulted the service to a new quality and sales numbers level. IMHO, XBLA was in dire danger to become a dump for cheap-ass retro-titles, but since Battlefield everything has changed. I’ve had more fun with Shadow Complex then with Gears 1 and 2 combined. I hope the success of SC means Gears 3 will become a bit more interesting (of course I don’t want a side-scrolling Gears, but I’d like to see more exploration and maybe some character up-leveling).

Dirt2 was a day-one for me, but at first I was terribly disappointed because I was expecting a somewhat arcady rally game like the original Dirt. Everything which I liked about Dirt was removed and more stuff was added which I clearly didn’t like. Especially the X-TREME bullshit: didn’t like the crap you’re co-pilot was spilling before the race (I’m Mister Smooth, you’re Mister Steady)? Well, now the game is completely full of this shit. I’m only halfway through Dirt2, so I’m not exactly sure, but they removed Pikes Peak (and hill-climbing all together), as well as all the amazing “pseudo real world” tracks in Europe, and replaced them with complete fantasy tracks in more X-TREME locations like China and Malaysia. I’ve been playing a bit of the original Dirt again, and the game still looks pretty darn good compared to Dirt2. The car models in Dirt2 are clearly better, the environment in Dirt2 is more detailed, but for some reason don’t look as “realistic” as in Dirt1. The European tracks in Dirt simply nailed the look of a dark German forest during a rainy day. Dirt2 looks a lot more like a typical  video game (Malaysia is a looker, though). Well, I still made my peace with Dirt2. It’s not a rally game, it’s a pure arcade racer now. It looks very good, it plays well, its fast paced, and it has a really good multiplayer mode. But the name Colin McRae does not belong any longer on Dirt2’s box.

Now that the rally-genre is completely dead on the consoles I really wish Turn10 would step in and settle the issue once and for all. Give us Forza Rallysport already. Forza’s driving model is too good for just one game :)

I gave in to the hype and am currently about halfway through Arkham Asylum. My brain hasn’t been “indoctrinated” by American comics during my childhood. As a result I find that whole super-hero thing completely silly. I never enjoyed a single Marvel-licensed game (I think my record was like 20 minutes into one of the Spiderman games), and with few exceptions, all of the movies were utter crap (especially the Batman movies, haven’t seen the last one yet though). So… I was a bit skeptical about yet another super-hero game, to say the least. Well, what can I say? The game is fucking great! It’s a bit too old-school here and there (for instance, there’s A LOT of air duct crawling in the game). Sometimes I believe there’s only one guy in the gaming industry who’s doing all the air-ducts. He’s probably started his career in Half-Life, and then went on to Splinter Cell, Riddick, MGS and probably every other stealth-shooter ever made. So that’s a bit strange, crawling around in air ducts as The Batman. There are other strong design clichees at work in the game here and there. For some strange reason, some corridors in the Asylum look like they were stripped from a space-craft (you know, one of those typical video game space ship corridors, metallic surface, a bit rusty, hexagonal profile, leaky pipes along the walls). Maybe Mister Airducts brought his brother with him, who’s specialized in corridors.

But that’s just nitpicking, and a true hardcore gamer feels right at home with all the air-ducts and spacecraft corridors… The game itself plays really, really well, especially the slick hand-to-hand combat. There’s a lot to explore, sneaking, planning, nosing around in dark corners, just my thing. At times the game feels like Bioshock, and at other times a bit like Splinter Cell, but all in all this is the best implementation of the Batman universe I have ever seen, better then the movies anyway :)

16 Aug 2009

XNAMath

With all the focus on the console platforms I didn’t notice one very cool addition to the March DirectX SDK: XNAMath. This is basically the traditional Xbox360 vector math lib, ported to the PC with SSE2 and inlining support. The N3 math classes are now running from the same code base on top of XNAMath for the PC and Xbox360 platforms. Maik has spent a few days to analyze the generated code and after some tweaking the improvements for our simple math benchmarks are absolutely dramatic, up to 4x faster on the PC side!

We had to change our memory allocation routines on the PC to always return 16-byte aligned memory, without this, XNAMath isn’t really useful since the aligned load/store functions can’t be used on vectors residing in heap buffers. Really strange that there isn’t a way to do this through the Win32 heap functions directly (or is there?).

Other then that I’m currently deep into “jobifiying” the render thread, in order to free the PS3-PPU from the mundane number-crunching tasks. Properly jobified code will also “automatically” run about 2x faster on a 2-core PC, and about 3..4x faster on the Xbox360, since even single jobs will be split and processing will be distributed to worker threads. The actual speedup may even be higher, since the data must be re-organized into small independent chunks (“slices”) of about 16..32 kByte each in order to make the best use of the SPU local memory, and this improved spatial locality is also extremely beneficial for CPU caches on the other platforms (I think I’m starting to sound like a record, but I can’t stress enough how good this data-reorganization will be for N3 on ALL platforms :)