Not all dot products are equal

I had another interesting debugging session recently with quite an unexpected conclusion. It all started when we received a new crash report - a certain platform (and 1 platform only) was crashing in a fairly old and seemingly innocent fragment of code: someModule->GetElements(elements); std::sort(elements.begin(), elements.end(), [&origin](const Element* a, const Element* b) { return a->pos.DistSqr(origin) < b->pos.DistSqr(origin); }); Crash was fairly rare although quite consistent in a particular location in the game, release build only, crashing on access violation inside the predicate.

operator[] considered harmful

I’ve always felt conflicted about the subscription operator[] in standard containers. It makes sense for random access structures like vectors, but it gets a little bit problematic elsewhere. Consider this seemingly innocent piece of code (it’s not 1:1, but this is code you can easily find in many codebases): if(someMap[key].value < x) { someMap[key].value = x; } 2 lines of actual code, but more than 1 problem, this snippet is potentially incorrect and inefficient.

Know your assembly (part 5)

The other day I was looking at a crash dump for a friend. A discussion that followed made me realize it might be worth to write a short post explaining why sometimes 2 seemingly almost identical function calls behave very differently. Consider the following code snippet (simplified): 1struct Foo 2{ 3 __declspec(noinline) const int& GetX() const { return x; } 4 virtual const int& GetY() const { return y; } 5 6 int x, y; 7}; 8 9int Cat(int); 10int Lol(Foo* f) 11{ 12 const int& x = f->GetX(); 13 const int& y = f->GetY(); // *** 14 15 return Cat(x+y); 16}

Simple multithreading tricks

Today I’d like to share a simple multithreading trick you can use to minimize “bubbles” in your pipeline. “Simple” because it applies mostly to “oldschool” threading systems, ie. the ones with main thread concept that kicks jobs and eventually flushes them. Cool kids using proper task graphs where everything just flows beautifully should not need it. Imagine we have a simple scenario, our thread produces some work, continues with whatever it’s doing, eventually waits for the job to finish (ideally this overlaps the work from previous point, so not much to do here) and processes results.

Zig pathtracer

If you’ve been reading this blog for a bit, you might know that when I experiment with new programming languages, I like to write a simple pathtracer, to get a better “feel”. It’s very much based on smallpt (99-line pathtracer in C++), but I do not want to make it as short as possible. I am more interested in how easily I can get it to run and what language ‘features’ I can use.

A debugger barrier

I’ve recently been asked by a friend for a little help with debugging a problem he was running into. Occasionally the program would freeze while trying to process a chunk of data and never moved on to the next one. Application is heavily threaded and processing is done by thread B, while thread A does its own job and periodically checks if work has been finished. If so, it sends it for further transformations and queues more work for thread B.

Grafana for dummies

Grafana is a very popular “analytics platform” or in more professional terms - a system to create pretty graphs. It’s very popular for monitoring system metrics, but really can be used for any timeseries data. It supports plethora of data sources and there is a decent chance you can use one of the off-the-shelf solutions to do 99% of the work for you (for example for some basic system metrics, especially on Linux).

Microcorruption writeup

Microcorruption is my ongoing “distraction” – it’s an online CTF. I’m way late to the party and have been doing it on and off since… 2013. How does it work exactly? To use their own description: “tl;dr: Given a debugger and a device, find an input that unlocks it. Solve the level with that input. You’ve been given access to a device that controls a lock. Your job: defeat the lock by exploiting bugs in the device’s code.

API granularity

I’d be the first to admit I don’t have much experience designing public APIs. I typically work on code that’s fairly specific to the game we’re making and while some of it is expected to be reused, our potential user pool is very limited, we’re still talking just one team, so <40 people and definitely not thousands. I’m still successfully using some little utilities/helpers I designed/coded 10+ years ago, but every now and then I run into a situation where decisions taken back then catch up with me and force to rewrite the API.

Ranged based "for" story

Consider the following, seemingly innocent (and completely made up) fragment of code: typedef std::map<int, std::string> MyMap; void foo(const MyMap& m) { for(const std::pair<int, std::string>& i : m) { if(i.first) { printf("%s\n", i.second.c_str()); } } } Looks simple enough, right? Just iterate over all elements of the map and print the value for non-zero keys. We use range-based for construct, use references, so do not expect any copies. Let’s just quickly make sure it all works as expected and consult Compiler Explorer.

Two Stage Push & Pop

I probably mentioned this before, but SPSC (single producer, single consumer) queue is one of my favorite structures. If implemented correctly, it’s actually 100% lock-free and is also surprisingly versatile (not all problems require MPMC!). I typically use a slightly modified version of this or an unbounded version, based on code by Dmitry Vyukov. Both implementations are very simple and possibly lack some of the modern C++ bells and whistles, like emplace, but these should not be hard to add.

Circular buffers (to the rescue)

Circular buffers are one (if not the) of my favorite data structures for some quick&dirty debugging. A simple, not production ready version can be implemented in a few lines of code (not ashamed to admit, I usually just copy paste these and remove when I’m done) and they’re a great tool to “record” a history of generic events. Any time I run into a seemingly random/unpredictable issue that might take a long time to repro, they’re on my short list.

Vanishing warning

Yet another MSVC story. Visual Studio has a nice compile-time warning when trying to access a static array with invalid index - C4789. According to documentation it’s mostly meant for various ‘copy’ functions (memcpy/strcpy etc), but it seems to work on ‘simple’ accesses as well. Consider (here’s a Godbolt link): struct Tab { float tab[2]; }; void Foo(const Tab&); void Bar(float forward) { Tab tab; tab.tab[0] = forward; tab.tab[2] = forward; // OOB access!

Compilers are smart

I recently transitioned to Visual Studio 2017 and while it went relatively painless, the new and improved optimizer uncovered some subtle issues lurking in the code (to be fair, Clang/GCC has been behaving same way for a long time now). The code in question was actually quite ancient and originated from this Devmaster forum post (gone now, but found if using The Wayback Machine): Fast and accurate sine/cosine. To be more precise, it was this version with ‘fast wrapping’:

Yellowknife

Ever since I was a kid I was always fascinated by the northern lights and hoped to see them in person one day. Poland is too far south/densely populated to spot them, though, so it wasn’t a very realistic dream. In 2009 I did move to Sweden, but still, this was Stockholm area, so my chances might have been bigger, but not by much (plus only been there for a year).

Neural networks and the stock market

Machine learning and neural networks seem to be all the rage recently. I was sifting through my old drives the other day and found my master thesis. It’s actually vaguely related, subject was Neural Networks for Stock Market Forecasting. Complete thesis can be downloaded here, but comes with 2 major caveats: it’s 100% in Polish (so actual title is Sztuczne sieci neuronowe w prognozowaniu kursów giełdowych) it’s over 15 years old Sadly, I could not find an accompanying MATLAB program I wrote.

Who ate my stack

The Old New Thing is one of my favorite blogs. It’s a collection of Windows development anecdotes, but every now and then Raymond will post a gnarly debugging/crash story. I’ve recently found some of my old notes related to a crash I was chasing in a third-party library, it reminded me a little bit of The Old New Thing and I decided to try something similar. The whole thing took place a few years ago, we were using some super early versions of a certain vendor library (no sources).

Cache effects, illustrated

Few years ago I published an article about love and care for your cache. Every now and then I receive emails asking for clarification or some extra question. It seems like the basic rules are easy enought, but once you add multiple cores to the mix, it might get a little bit confusing. If we only have one core everything is fairly simple. There’s just 1 cache, which is essentially a variant of hash-table with limited number of slots.

A Halloween Story - get_temporary_buffer

A little bit late, as Halloween was yesterday, but I think std::get_temporary_buffer is scary enough to qualify. A co-worker called me today to show me an ‘interesting’ crash. It was deep in guts of the STL, more specifically in the std::_Merge method. Corresponding C++ line seemed innocent: *_Dest++ = _Move(*_First1++); Nothing very interesting, not our code and yet it was crashing with: Exception thrown at 0x01293C05 in foo.exe: 0xC0000005: Access violation reading location 0xFFFFFFFF

Digital Dragons 2017

I’ve just returned from the Digital Dragons 2017 conference. I’ve been presenting there last year and enjoyed the event so much I decided to repeat it. They changed a venue this year and I must say it was even better. Last year had a very nice ‘artsy’ feel to it, but ICE has a much better infrastructure. This year I’ve been talking about networking system. You can find the slides here - “Networking Architecture of Warframe”

Who crashed?

Last week I was investigating a crash originating somewhere in a code that looked like this (GPF in this C++ line): obj->GetFoo()->GetBar().Call(player->GetCat(), this, &MyType::SomeFunc, moreArgs We could discuss the number of indirections or the fact that if this code had been split into multiple lines it’d be obvious, but that’s not the main point here. I didn’t have this luxury, I had to find out which pointer exactly was NULL here.

My check-in procedure

A few weeks ago we had a discussion a forum discussion. Question was - what tips did we have for junior developers (not only programmers, all specialties). My #1 tip was: always diff before checking in your changes! I still stand by it, but thought I’d elaborate a little bit and give a quick overview of how I handle my commits these days. Not a rocket science for sure, but the presentation (and hints) were aimed at people just starting in the industry.

Choices and consequences (part 2)

I’ve been doing some minor refactoring recently and - once again - it got my thinking how seemingly tiny C++ changes can affect generated assembly code (and performance). It was a fairly simple scenario, had a collection of ~60 small items identified by an unique ID. ID was a 32-bit number, but realistically the range seemed to be limited to 0-5000 (although I couldn’t rely on it staying like that forever).

Dynamic initializers strike back

Back in the day I wrote about the ‘dynamic initializers’ problem. Basically, older versions of MSVC (up to 2012, not sure about 2013, seems better in 2015) had problems with static const floats that depended on other static const floats. Values were not calculated compile-time, there was actually a short function generated and it’d do it. The immediate problem is a code bloat (if our constant is placed in a global header), but the other potential issue stems from the fact that these ‘dynamic initializer’ functions respect the optimization settings (/fp:fast).

Wordpress to Hugo

I’ve been planning on converting my blog to some static site generator for a while now, but the (perceived) amount of work involved seemed scary, so I kept coming up with reasons not to do it. I really like the idea of static sites. Using gamedev jargon, this basically means we “precompute” as much as possible. Instead of retrieving posts from the database and building pages on the fly (like WP), we do it all offline and then push static HTML files online.

Elo vs Glicko

If you’ve ever done any matchmaking coding (…or played chess) you’re most likely familiar with the Elo rating system (PSA: it’s Elo, not ELO, it’s not an acronym, it’s named after a person - Arpad Elo). It’s a rating system used by most chess federations (most notably, FIDE) and has been adapted by many video games. It’s trivial to implement and get up and running, but suffers from a few issues:

DD2016 - video

A video from my DD2016 talk has been uploaded and can be viewed here:

Digital Dragons 2016

A few days ago I came back from the Digital Dragons 2016 conference. I’ve been in talks with these guys in the past years, but timing was never quite right, this time I finally could make it. Luckily for me, it was the same year they invited John Romero, David Brevik and Chris Avellone. In December 1993 my classmate brought an old floppy disc to school. He claimed it contained the best game ever.

Elixir diaries

You have probably heard about an AI algorithm defeating a human professional in a game of Go. The algorithm itself has been developed by Deep Mind, an English company that’s now owned by Google. One of the founders is Demis Hassabis. If you were playing Bullfrog games in the late 90s, the name might ring a bell, he’s one of the designers of Theme Park. Back in the day I remember reading a column in Edge magazine titled “The Elixir Diaries”.

Archeology

Recently, we’ve been collectively complaining on Twitter about going crazy in C++ (as we do every few weeks). This reminded me of my dark period around 2002 when I was really excited about templates and metaprogramming. I tried finding my old code, but turned out my previous website was completely gone. Fortunately (?), good folks from The Wayback Machine had some copies. I moved some of my articles to a new server.

Fantasy football and statistics

I’m playing in a fantasy football league with some coworkers this year. I have always liked all kinds of sports, but it’s a little bit challenging to follow NFL from Europe. There’s not too many stations that actually show it (except for the Super Bowl) and even if they do, the time difference make it difficult to watch. I still followed major news and managed to catch a game every now and then, but I was very far from expert.

Whac-A-Mole

I’ve been debugging a rare memory corruption bug recently and - as usual - it turned out to be an exercise in frustration. This time only part of that was because of the bug itself, the other was because methods I chose were not very helpful (in my defense, it’s been a while, so I was a little bit rusty). The bug itself was fairly boring - sometimes, when leaving a certain UI screen game would crash.

Know your assembly (part N)

An entertaining head-scratcher from today. Application has suddenly started crashing at launch, seemingly inside steam_api.dll. It’d be easy to blame external code, but as mentioned - it’s a new thing, so most likely related to our changes. To make things more interesting, it’s only 32-bit build that crashes, 64-bit seems fine. High-level code looks like (simplified): 1struct tester 2{ 3 virtual bool foo(); 4 virtual void bar() 5 { 6 } 7 virtual void lol() 8 { 9 if(!

C++ 11 final

I’ve been doing some micro-optimizations recently. One of the things I’ve been trying is eliminating virtual method calls in ‘leaf’ types. Consider the following snippet (simplified): 1struct Bar 2{ 3 virtual bool Func1() { return false; } 4}; 5struct Foo : public Bar 6{ 7 virtual bool Func1() 8 { 9 return true; 10 } 11 virtual void Func2() 12 { 13 if (Func1()) 14 printf("Hello"); 15 } 16}; 17 18void DoSomething(Foo& f) 19{ 20 f.

Instrumenting crash dumps

I’ve been planning to write a post about debugging multiplayer games (post-mortem) for a while now, but it keeps getting bigger and bigger, so instead of waiting until I can get enough time to finish it, I thought it’d be easier to share some quick’n’easy tricks first. I’d like to show a simple way of “instrumenting” a crash dump so that it gives us more info about the crime scene. Let’s assume we’ve received a crash from the following piece of code (it’s actually very close to a real-life scenario I encountered).

NaN memories

A nice thing about Twitter is that single tweet can bring so many memories. It all started when Fiora posted this: This reminds me of how HLSL very carefully defines "saturate" in a way that makes NaNs turn into 0: https://t.co/0tWzaa6H2K @rygorous — Fiora (@FioraAeterna) March 11, 2015 It reminded me of an old bug I encountered few years ago when working on a multi-platform (PC/X360/PS3) title. One day we started getting strange bug reports.

MESIng with cache

(Please excuse the terrible pun, couldn’t help myself). As we all know, computer cache is a touchy beast, seemingly little modifications to the code can result in major performance changes. I’ve been playing with performance monitoring counters recently (using Agner Fog’s library I mentioned before). I was mostly interested in testing how cmpxchg instruction behaves under the hood, but wanted to share some other tidbits as well. Let’s assume we’re working with a simple spinlock code.

Rust pathtracer

Last year I briefly described my adventure with writing apathtracer in the Go language. This year, I decided to give Rust a try. It’s almost exact 1:1 port of my Go version, so I’ll spare you the details, without further ado - here’s a short list of observations and comparisons. As previously, please remember this is written from position of someone who didn’t know anything about the language 2 weeks ago and still is a complete newbie (feel free to point out my mistakes!

Hidden danger of the BSF instruction

Had a very interesting debugging session recently. I’ve been investigating some of external crash reports, all I had was a crash dump related to a fairly innocent-looking piece of code. Here’s a minimal snippet demonstrating the problem: struct Tree { void* items[32]; }; #pragma intrinsic(_BitScanForward) __declspec(noinline) void* Grab(Tree* t, unsigned int n) { unsigned int j = 0; _BitScanForward((unsigned long *)&j, n); return t->items[j]; } Easy enough, right? Seemingly, nothing can go wrong here.

Z-Machine interpreter in Go

Recently, I had an inspiring discussion with fellow programmers, we were talking about interesting side projects/programs to quickly “try out” new programming language/job interview tasks. One that’s been mentioned was coding a Z-machine interpreter that’s capable of playing Zork I. The Z-machine is a virtual machine developed by Joel Berez and Marc Blank, used for numerous Infocom text adventure games, most notably the Zork series. In all honesty, I’m probably a few years too young so didn’t get to play Zork when it was big (I did play old Sierra adventures back when you actually had to type commands, though, one of the the reasons I started to learn English was Police Quest I.

A Byte Too Far

A short cautionary tale from today. I’ve been modifying some code and one of the changes I made was to use a type of Lol as a key in a map-like structure (key-pair container, uses < operator for comparisons). Structure itself looked like: 1struct Lol 2{ 3 byte tab[16]; 4 short cat; 5 bool foo; 6}; …and here’s the operator< 1bool Lol::operator<(const Lol& other) const 2{ 3 return(memcmp(this, &other, sizeof(other)) < 0); 4} The problem was - it seemed like sometimes, in seemingly random cases, we’d try to insert an instance of Lol to a container even though exactly the same element was already there.

Going deeper - addendum

There’s been some comments to my previous post wondering about C++ compilers and their capabilities. Normally, I’m all for compiler bashing, in this case I’d probably cut them some slack. It’s easy to optimize when you’re focused on a single piece of code, way more difficult when you have to handle plethora of cases. On top of that, uops handled differently on different CPUs, e.g. in my limited tests Haswell seems to care less.

Going deeper

Few weeks ago I encountered a discussion on a Polish gamedev forum – participants were wondering whether it’s faster to access stack or heap memory. I didn’t pay much attention (there should be no significant difference) until someone had posted a test case. Out of curiosity, I ran it and to my surprise discovered, it was consistently faster for buffers allocated on the stack. We’re not talking about few cycles here and there, too, the difference was almost 20% (Ivy Bridge laptop).

Patching binaries

There may come a time in game programmer’s life when he has to fix a bug in a library he doesn’t have the source code for. It doesn’t happen often, it might never happen, but it’s good to be prepared. If I remember correctly, I had to do it only two times, one was fairly recently. We were getting quite a few crash reports and were assured that fix in the third-party library was coming, but I decided to see if it’s possible to do anything about it in the meantime.

Smartness overload #2

Today’s article is brought to you by a friend of mine. He’s been doing some home experiments and noticed a particular piece of code was running faster in Debug than Release (using Visual C++ compiler). He mentioned this to me, I found this intriguing enough to ask him for this snippet and investigated it yesterday. Turned out it was a classical case of compiler trying to be too smart and shooting itself in the foot.

Delete current instruction macro

I must admit I am not as die hard fan of ProDG debugger as some other coders out there, perhaps I’ve not been using it long enough. One tiny thing I miss though was the possibility of replacing an assembly instruction under the cursor with NOP with a single keystroke. Sure, with Visual Studio you can achieve same result with memory/immediate window, but it’s much more cumbersome. Today I decided to finally bite the bullet and recreate this little feature with VB macro:

Go pathtracer

Recently I’ve been experimenting with the Go programming language a little bit. It’s my second approach actually - I gave it a half-hearted try last year, but gave up pretty quickly (I think it was some petty reason, too, probably K&R braces). This time around I actually managed to stick to it a little bit longer and learn a thing or two. I decided my test application would be a simple pathtracer.

Performance-Monitoring Events

When experimenting with some of the more esoteric features of modern CPUs it’s sometimes not immediately obvious if we’re actually taking advantage of them. Sure, you can compare cycles, but the differences are not always big enough to justify conclusions. Luckily for us, in the Pentium processor Intel introduced a set of performance-monitoring counters. They are model specific (not compatible among different processor families) and allow you to monitor just about every aspect of CPU pipeline.

Second Reality - source code

Just a quick follow-up to my previous note. As mentioned by Michal, Future Crew guys decided to celebrate the 20th anniversary of Second Reality in the best way possible - they released a full source code. Obviously, it’s more of a tidbit than anything else, but it’s still interesting to finally see how certain effects were done. Apparently Fabian is already working on a code analysis article, but in the meantime I’ll only mention two things that caught my eye so far:

Demoscene tribute - Second Reality

I know I claimed I would not write about Second Reality here, mostly because everyone knows it, but it’s a special day today… It’s been exactly 20 years since Second Reality has been shown for the first time, at Assembly 1993. I’ve seen it few months later and still remember that day. I was living in Torun at that time and have just started high school. I would often visit local computer store, just to see what’s new.

Forward that store

I know I’ve been bitching about load-hit-store (too) many times before, but it’s been one of the most annoying things we had to deal with at the previous generation consoles. LHS happens when we try to load data from the address that has been recently written to. X360/PPC CPUs were fairly simple, they could neither try to execute some other instruction (no OOE) nor retrieve the data without waiting for it to reach cache.

cmov fun

If you’ve been coding for current (prev?) gen consoles, you know your optimization guidelines - be nice to your cache, avoid LHS and branches, in general - do not stress the pipeline too much. With next (current?) generation moving back to x86, things get a little bit more blurry. With out-of-order/speculative execution, register renaming and advanced branch predictors, it’s sometimes easy to shoot yourself in the foot when trying to be smarter than compiler/CPU.

Parallel 101

With the unveiling of next gen console specifications it’s clear that multi-threaded code is here to stay (I don’t think anyone expected otherwise). If anything, it’ll be even more common, new CPUs run at relatively low frequencies (when compared to modern PCs), so we’ll definitely have to go wide to use their potential. Here’s a quick cheat sheet I’m usually following when trying to move code to a background thread. Please note: move.

MemTracer 64

It’s been a long time coming, but I finally found time to update MemTracer C# to support 64-bit applications (so 64-bit memory pointers + callstack addresses).

Choices & consequences

Spent a little bit time tweaking RDE vector class again. As I already mentioned, the container itself is not terribly fascinating, there are not too many choices here. There’s another battle going on the lower level though, it’s interesting to see how an innocent instruction like_ size()_ can be a cause of a slowdown. Typically, a vector class has 3 properties it needs to keep track of: buffer properties (pointer and size),

A world without Lucas Arts

Working in a game industry for more than few years tends to desensitize one to all the news about mass layoffs & companies going bust. Sadly, it happens so often, we’re slowly becoming used to it. I first found out about Disney shutting down Lucas Arts at work. Sure, I was surprised, it’s a big news after all, but I was busy, so didn’t think twice about it… I finished work, came home, read all the updates and then it suddenly hit me.

The undefined flag

This week I had one of the most interesting debugging sessions in a while. Here’s the minimal code snippet exhibiting the problem. It doesn’t really make much sense in itself, but I tried to remove everything not related to the bug itself (the actual case was much more convoluted): 1struct SVar 2{ 3 SVar() : m_v(23000) {} 4 void operator=(unsigned short t) 5 { 6 if(_rotr16(m_v, 1) != t) 7 { 8 m_v += t * 100; 9 } 10 } 11 unsigned short m_v; 12}; 13static const int MAX_T = 1000; 14struct Lol 15{ 16 __declspec(noinline) void Cat(int t) 17 { 18 unsigned short newT = static_cast<unsigned short>(t < MAX_T ?

x86/x64 MSVC plugins

Recently I had to write a tiny MSVC plugin to help visualizing one of our structures. It’s been a while since I’ve done it last time, so I started Googling for help. The good news is – it’s now much easier to find information/articles (mostly unofficial). The bad news – there are still many dark corners & I ran into a problem that took me a while to figure out.

Junkers

Today I was contacted by Syama Pedersen and asked about participation in an indie game project called Junkers. I don’t really have too much spare time these days, so it’s not possible, but I thought I’d at least help spreading the word, perhaps someone would be interested in joining their team. Demo reel can be found here, contact Syama if you’d like to help. Old comments Pawel W 2013-01-16 08:29:21 Pretty cool anims for ones done “by hand”.

Coding in a debugger

Recently, I spent some time debugging all kinds of crazy, once-in-a-blue-moon type of bugs, usually MP related and often happening in final/release builds only. The annoying problem with these is they tend to “hide” when you try to repro them and then pop up 5 minutes later when you’re investigating something else. That’s why it’s often crucial to catch every chance you get and try to extract as much information as possible out of every case.

Copy or move

I’ve been optimizing RDE’s vector class a little bit recently. In all honesty, it’s probably the least interesting container, there are only so many ways to do things, so it all boils down to working at the instruction level, trying to eliminate everything that’s not needed. Those few cycles don’t even matter in the grand scheme of things, but it can be an interesting learning experience at times. One of the functions I was interested in was erase.

Pointers to member functions

Pointers to member functions is one of those aspects of C++ that I use every 2 years or so. I know how they work, but I usually need some refreshing on the details (especially the syntax kills me every time, although I might actually remember it now). One of the gotchas with them is - you’re not supposed to cast it to void* (see this question for example). That’s one of those guidelines that I read long time ago, absorbed and never gave a second thought.

A Tale of 3 Characters

Had an interesting little debugging adventure recently. Few weeks ago we started getting QA reports about some of the visual effects looking all weird. I tested it locally, it all seemed fine. QA dug deeper and they discovered it only occured with disc builds (not necessarily running from a DVD, just after installing fully preprocessed build), P4 version was good. The problem with installed builds is they are very close to final, fully optimized, all assets in final version with no debug info etc, so it’s pain in the ass to debug.

Pass by reference

I’ve not been reading too many C++ books recently, but I have a foggy memory of a recommendation they include: do not pass arguments by value, unless it is a built-in type. Justification is given, probably, but it does not seem to stick and people tend to only remember the “pass by value - bad” part. There is plenty of programmers out there, who do it automatically - built-in by value, anything else - by reference.

Attach to process macro

Recently I got fed up with manually attaching to game process every time. I knew there were some macros that would search for given executable and attach automatically, I even found some of them. Sadly, it seems like API changes slightly with every release, so couldn’t get any of them to work with MSVC2010. In the end, I just hacked my own one, attaching it below (MSVC2010, probably won’t work with any other version).

A Decade

I can’t remember the exact date, but I know it was early May or the end of April, 2002. I’ve just realized I had started my gamedev adventure almost exactly 10 years ago. It seemed like a logical step, never really considered any other career choice, it was my dream job and quite natural progression after few years of demo coding. I responded to a job advertisement at the gbadev mailing list (wow, I love the Internet, I actually found this post), flew to Palermo for a weekend, survived my first job interview (even though I was still slightly hung over from the party 7th Sense guys took me the day before…) and before I knew it - I was flying to Italy again, this time for good.

Null references - addendum

My recent article turned out to be quite popular, however it seems that people focus on the problem of undefined behavior rather than optimization itself. Quick clarification then, so that we’re all on the same page. I do not advocate relying on undefined behaviors. They are… undefined (duh). I merely noticed in practice you can have ‘null references’, just as you can have null pointers. I also would be very surprised if there was any compiler that actually generates code testing against null pointer dereference.

Compressing integers

Programming games is an uphill battle. We always try to fight for more, but our resources are limited. There’s never enough RAM, the CPUs are never too powerful and obviously same thing applies to bandwidth - we could always use some more. The eternal problem of mutiplayer game is trying to send as much information as possible using as little memory as possible. One of the weapons in our arsenal is compression.

Null references

One of the most popular questions that fresh C++ programmers ask is about differences between pointers and references and which one to use. One of the differences people cite is “references can never be NULL”. That’s true in theory and according to the standard, but in practice, especially when mixing pointers and references there’s nothing preventing you from doing this:

GDC 2012/Mexico

Usually, around this time, I publish my collection of links to GDC presentations. This year however haven’t been really paying too much attention, took a week off and went to Mexico. I’ve only started to catch up… Do not despair, though, Jare has done a great job and you can find links at his blog. The trip itself was fun, although very different from our previous adventures as it was the first time we took our 10 months old daughter with us.

Darkness 2

Few days ago, we released Darkness 2, the game I’ve been working on for the past 18 months. I won’t write too much about the game itself, if you’re interested, you probably know about it already, if not - check out the demo. Usually, once the game is on the market, devs will keep on stressing how they were killing themselves in order to make the best product possible.

Resolving PS3 callstacks

Hopefully, your engine includes a crash handler. If it does not, stop reading, add one (here’s simple example) and then continue. In most cases, when something goes wrong, log files contains fully resolved callstack. However, sometimes, especially at the last stage and (semi) final builds, crash reporter might be disabled and now all we have is a list of addresses. Luckily, it’s still possible to resolve those, using Sony’s tools (that’s also what I use in PS3 version of MemTracer).

The Broken Windows Theory

The broken windows theory is a criminological theory first introduced in 1982 article by James Q. Wilson and George L. Kelling. The gist of it is given in this example: “Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it’s unoccupied, perhaps become squatters or light fires inside.

Trailer time!

Two trailers released recently. Starbreeze showed first footage of their Syndicate remake: I mostly worked on cancelled Bourne project when I was there, but lots of friends still at SBZ, so I’m glad to see their hard work is coming to fruition. Few days before, 2K released trailer for the game I’ve been working on for the last 15 months - Darkness 2: I really like it, mostly because it explains the setting/first game events a little bit.

Optimizing without fear

As you can probably tell from this blog, I spent fair chunk of my time optimizing code/thinking about optimizations. One of the main problems with optimizing code is making sure we didn’t break anything in the process. It might be tricky, especially when modifying algorithms with many edge cases, but even simple changes are dangerous, probably because people don’t test them so thoroughly. I still feel a little bit nervous upon seeing “Little optimization in XXX” in P4 changelist description (heck, I’ll be the first one to admit, I broke code as recently as last week…).

STL interface

As you are probably aware, game developers have mixed feelings about STL. Sure, it has advantages, it’s already there, doesn’t have to be coded from scratch, it’s standard. On the other hand, the guidelines are very broad, implementations can vary wildly. Performance/memory guarantees seems to be hard to enforce. Even if the interface is always the same, there’s enough wiggle room underneath to seriously break some applications. Take clear() method for example.

Hard Reset

My buddies at Flying Wild Hog have announced their first project recently. It’s a dynamic cyberpunk FPS with character progression elements. Make sure to check out the teaser: Been a long time since I’ve been to Poland so had no chance to play it, but after talking with people who did and knowing the team behind it – I expect good stuff. Old comments Branimir Karadzic 2011-07-19 18:47:27 It looks pretty cool!

Flattening trees

Trees are one of the most popular structures in game development. Your skeletal hierarchy, your attachments – all this can be represented using trees. They lend nicely to short & clean code, especially with recursive functions – you typically perform your operation on a root, then call the same function for all children. Problem is – it’s not always the most effective way of doing things. Consider the most canonic form of tree traversal:

Hidden enemy

Consider the following piece of code: void FindFrames(const S* seq, float d, UINT& outFrameA) { const UINT n= static_cast<UINT>(seq->fd.size()); outFrameA = 0; while(outFrameA + 1 < n && seq->fd[outFrameA + 1] < d) { ++outFrameA; } } Looks innocent, right? Well, it was slow enough to show up quite high in the profiler… It might seem surprising at first, but if you’ve done some console programming in the past, you can probably recognized our old foe - load-hit-store here.

Demoscene tribute - Camorra

Camorra was a Polish demoscene group. They might have not gained same level recognition as Sunflower/Pulse, but they sure were one of the best squads in the first years of Polish PC scene. Camorra actually won the first Polish PC party - General Probe 1995. Sadly, couldn’t find this winning demo (Gust) anywhere. Let’s start with Gustation then. It’s their 64k intro from CAF 1995, took 2nd place behind Why by Adrar Design:

Riddle

Normally, I try to avoid C++ bashing, so trendy nowadays. It is what it is, but we’ve to use it anyway. Today, however I encountered a funny bug that made me wonder a little bit. Consider the following snippet:

Conditional breakpoints on steroids

Imagine a situation where you’re debugging some problem and need to set a breakpoint in function that’s called very often from many points in your application (like operator[] in your array class for example). Thing is, you’re only interested in one particular codepath, as that’s where things go wrong, calls from other places are fine. If you simply set a breakpoint in line that interests you, it’ll trigger hundreds of times every frame, making it tricky to find the moment that’s interesting for us.

A little bit of fun

This recent tweet: "SomeEnum blah : 8;" Added new enum elements so max value is now >127. GUESS WHAT HAPPENS. — Fabian Giesen (@rygorous) April 1, 2011 from Ryg reminded me of another old story related to bitfields in C++. Consider the following piece of code: typedef char BOOL; ... // Some other file struct SomeStruct { BOOL m_something : 1; BOOL m_isVisible : 1; BOOL m_somethingElse : 1; BOOL m_someOtherStuff : 5; .

Cruncher - Google code project

Remember Cruncher#? That’s my little tool for extracting structure layout information from PDB files. It’s pretty much done and I rarely modify it, but from time to time something irritates me enough to force me to get back to it. Recently I’ve added simple, but useful feature. If you double click member variable, it’ll automatically jump to it’s type definition (if it can find it, it must be another UDT). Example:

GDC 2011

Not sure if it has much sense in the era of Twitter (everyone who’s interested can easily find links there), but let’s try. Some of GDC2k11 proceedings: Networking for Physics Programmers 2011, Glenn Fiedler (SCEA). PDF version here. Crash Analysis and Forensic Debugging, Elan Ruskin (Valve). Normal Offset Shadows, Daniel Holbert (High Moon Studios). Thanks, Ignacio! NVIDIA Game Technology Theater videos + some slides. Found by Guille.

vector constructor iterator

As promised, today a little bit about mysterious ‘vector constructor iterator’. Essentially, it’s a function generated by MSVC to initialize arrays of UDTs. Unfortunately, sometimes compiler gets confused and tends to spit out superflous code. Consider the following example, taken almost as-is from certain engine (names hidden/changed to protect innocent):

Attack of dynamic initializers

Recently, I’ve been looking a little bit what’s taking space in our executables and found an interesting ‘feature’ of MSVC. It has troubles with expanding floating-point constants that rely on another constants (…that rely on another constant, yes it requires 2 levels of indirection to break). Consider the following example:

Retro Pinball

As you might know, our CEO is the author of the classic Epic Pinball (coded 100% in assembler, obviously :). I’ve spent long hours playing the original, especially the Deep Sea table. Recently, our company in cooperation with Big Blue Bubble, created an Iphone/Ipad version of this game. I don’t have an Iphone, but played it a little bit at the office and it’s just as entertaining as it was, especially the ‘table feeling’ is really well preserved.

Compile time log2

Been working on some wrappers over data containers allowing to move code to SPU easier recently and found myself in need of a compile-time log2 (for shifts, so integers only). Luckily, it’s pretty straightforward to achieve using some template voodoo and boils down to using fact that log2(x) == log2(x / 2) + 1:

Reflection in C++ – metadata

About a year ago I published a few articles on my experiments with C++ reflection system. It extracts all the type information from PDB files. Nice thing - it’s all automatic and requires none to very little source code changes. One thing I didn’t like was problem with adding metadata to our types/fields. It’s mostly for editing purposes, but wouldn’t it be nice to have at least a help/description string for fields?

TMplayer to MicroDVD converter

One of my Christmas presents (that I bought myself) was WD TV Live Plus media streamer. I left my projector back in Warsaw (sniff) and I was tired of watching stuff on my 15” laptop. WD TV is a pretty neat little machine, it effortlessly plays every video I throw at it. The only problem I had was that it seemed to struggle with TMPlayer subtitle format which is very popular in Poland for some reason.

Quick iteration, insertion, look-up, removal

Wouldn’t it be nice to get all four of those with some container type? Sadly, it seems quite tricky. Vector gives the most efficient iteration and pretty good insertion (at tail), but is more problematic when it comes to look-up & removal. Intrusive linked lists are pretty good here, but pointer chasing may hurt during iteration. Hash map falls somewhere in the middle, but again - iteration will most probably be slower than vector (we have to skip over empty buckets).

DIG 2010

On Thursday/Friday we had DIG conference here in London. I was quite surprised there is something like that and even more surprise when I found out it’s actually quite big, with DE & other local companies, local universities, hordes of students and interesting lectures. I come from a country where game development is still considered exotic, not very serious career choice. It’s a refreshing change to participate in gaming event organized with so huge support from the city, with London mayor attending.

MemTracer - episode IV

(I’m seriously running out of subtitle ideas). Some years ago I started to toy with an memory tracing/debugging tool idea. First proof-of-concept implementation has been created in few days and while it worked with a very simple test app, it required major overhaul before integrating with any real-world program. Somewhere in February 2008 I had a new version, that proved itself very useful during my adventure with enhanced version of certain PC RPG (as it later turned out, it was by far the most memory stressing project’).

Declaration matching

I encountered an interesting problem today. Consider the following piece of code: namespace Test { struct Lol {}; struct Cat {}; struct Foo { virtual void Do(Lol&); virtual void Do(Cat&); }; struct Bar : public Foo { virtual void Do(Lol&); void DoSomethingElse() { Cat cat; Do(cat); } }; } Question: what happens when you execute Bar::DoSomethingElse? Answer: nothing, as trying to compile this piece of code will result in the following error: ‘Test::Bar::Do’ : cannot convert parameter 1 from ‘Test::Cat’ to ‘Test::Lol &’.

Some more benchmarks

Gave tr1::unordered_map a try, it seems to do perfectly average, nothing spectacular, nothing awful, except for predict_grow with 4 byte objects, where it’s almost 10x slower than the next implementation (that’s not an anomaly, it happens every time). I also found a bug in RDE where I overoptimized it a little bit - could result in a crash when searching for item that’s just been removed. It slowed fetch by about 3%, however later I found a way to remove some branches and sped it up by ~6% again, so final version is even faster.

EA STL released, updated benchmarks

Big weekend news were EA releasing some of their codebase source, including parts of EASTL. Given that the original EASTL document has been the main inspiration for my RDE STL experiment, I was very interested in finally seeing the code itself. First impression - it’s still big. It is leaner than STL, but it is a big library. That’s quite understandable if you remember it’s not a local, one studio thing, it’s used by the whole organization.

Debugging heap corruptions, part 2

Few years ago I wrote a short article about dealing with heap corruptions (buffer over/underruns). I mentioned that even after applying described techniques, the biggest problem with overruns is that they’re detected when memory block is freed, not when the actual corruption happens. Those two moments can be very far apart from each other, which complicates debugging. I described some workarounds, but they were not really anything I’d call a satisfying solution.

Licenses

Recently, I’ve been getting mails asking about license that applies to various code snippets published here. I never actually bothered to think about it and it seems like there is a zillion of different licenses out there. zlib seems like one of the most reasonable ones (and it’s so short I could be arsed to read it), so that seems like a good choice. It doesn’t really change anything, but I put it here (and here), just so that it’s obvious.

Process Explorer & 64-bit OS

Few years ago I mentioned a nice little program by SysInternals - Process Explorer (task manager replacement). I install it everywhere I go. Recently, I ran into weird problem, however. My work machine runs Windows 7 64-bit. PE works perfectly, the only problem is that I couldn’t make it to replace standard Task Manager. There is a menu option that should do just that, but running it didn’t change nothing.

Clash of the Thread Pools

Recently, I’ve been experimenting a little bit with different kinds of MT-safe containers. I wanted to compare a performance of various kinds of containers I’ve had lieing around. It turned out it’s more tricky than I expected, as under Windows, results vary wildly from one run to another. I’m not even speaking about container performance, just running same task can be many times slower (see this note for example). Include similar problems with managing the threads themselves (sometimes they wake up too late or not at all) and you should get the picture.

Cuba

On Sunday we’ve returned from a short vacations in Cuba. As usual, it wasn’t really a conscious choice, rather a result of having to choose some destination, as my vacation date approached. As it turned out - it worked out great. If I’d have to sum up Cuba (and especially Havana) in one word it’d be irrational. Country like that has no right to exist, yet it does. What makes it feel even more weird, it’s a mere 3 hours flight from Toronto, but it feels like a different planet or like there’s a time machine involved.

Smartness overload – addendum

In my previous note I mentioned that IDs are my favourite form of weak references. By pure coincidence, just recently Noel made one of his Inner Product articles public and it deals with very related subject. As a matter of fact Noel’s implementation of HandleManager has been a starting point for the one I use for my home projects. I use it not only for dealing with resources, but as a general ID->pointer resolver.

Smartness overload

Over the years, I’ve seen plenty of different code bases - open source projects, internal game engines, my own experiments. Some of them were just bad and buggy, but in many situations I found something that could only be described as ‘smartness overload’. An obviously skilled & experienced programmer just tried too hard. There’s a great quote attributed to Brian Kernighan: ‘Debugging is twice as hard as writing the code in the first place.

Optimization 101: ordering conditions

One of the most basic truths about optimizing existing code is: there are no low hanging fruits. Your coworkers are not stupid, it’s not like you can just add some switch or line and code will magically run two times faster (at least not often). ‘Easiest’ way nowadays is probably some form of parallalization, but it’s not always possible. Usually, it’s more a series of mundane tweaks, day after day, shaving few cycles here, few there.

Be nice to your cache

Short list of tips & guidelines that every game developer should keep in mind. No rocket science, common sense, really, but it’s still relatively rare to find codebases that apply to them. It’s especially aimed at gameplay programmers, who operate a little bit further up from the metal. With todays hardware, cache can be your biggest friend or enemy, CPUs got the the point where a few extra calculations hurt much less than a single cache miss (so LUT is not always the best option, for example).

Venice

Venice is truly one-of-a-kind city. I’ve ‘been’ there almost 8 years ago when returning from Italy by train (long story involving lost plane connection), but it was continental part then (Mestre) and only for 2 hours. For some reason I thought that the rest of the city looks the same, just with some canals here and there. Couldn’t be more wrong. Basically, it’s more of a museum than a city.

Back!

OK, I’m back. Just for a few days, though. I’m crashing at my sister’s place, as our flat is rented. There’s rather crappy internet connection here, so no Venice photos yet. I’ve updated (very roughly) my GDC note. In the meantime - GDC vault has been updated, so you can find most of the papers there. I will try to upload some photos when I get to the hotel in Canada.

GDC update

As I mentioned - I’m flying for a quick vacations tomorrow, so I will not be able to update the GDC links. This post is mainly to trigger RSS readers, as I’ve added some new stuff during last week. Feel free to add new links in the comments, I will move them to the post when I get back. In the meantime people can just dig them out from the comments section.

Ten Months in Sweden

About two weeks ago I had my last company beer/good-bye party at Starbreeze. I need to deal with lots of formal stuff in Poland now, then I’ll have a short vacation (flying to Venice next week) and then I will move to Canada to work for Digital Extremes. It really wasn’t easy decision as I had great time in Sweden and Starbreeze, but the offer was just too good to pass, one needs to take risks sometimes.

GDC 2010 proceedings

I’ll keep updating this post with links as I find them. Pål-Kristian Engstad (Naughty Dog) - Introduction to SPU Optimizations, part1 & part2 (not sure if those are official GDC2k10 papers, but have been just released and are great), Glenn Fiedler (Sony Santa Monica), Networking for Physics Programmers (slides + demo), Havok demovideos, Kent Hudson (2K) - The AI of BioShock 2: Methods for Iteration & Innovation (slides, keep an eye on Kent’s GDC page, versions with annotions to come),

Data breakpoints

Data breakpoints are one of the most helpful debugger features when trying to hunt for memory overwrites/ninja variable modifications. In majority of cases it’s enough to set them up from debugger, however, there are situations when it’s not possible. Sometimes breaking into debugger changes program behavior (I had this problem just yesterday), sometimes we don’t want to catch every variable access, just some of them (as others are legal). In situations like that we need to set data breakpoints from code.

Adding layers

Simple technique that can help in making code more future-proof and easier to modify. Applicable in most situations where two subsystems need to exchange informations. Let’s imagine the following scenario - for some reason we need to introduce ‘unlimited mana’ feature in our game. If hero is in berserker mode, his attributes increase, time slows down, he is able to cast spells even if he’s out of mana and his mana pool doesn’t deplete at all.

Playing with bits

Little challenge posted by a workmate. Good for those 5 minute breaks at work when you need to force your brain to think about something else than your current task. Recode the following piece of code so that it doesn’t use branches/multiplies: unsigned char* oldStart = 0; if (m_start + size < m_bottom) { oldStart = m_start; m_start += size; } return oldStart; Don’t read below if you want to try it yourself.

Are Movies Getting Longer?

Few weeks ago I’ve been watching The Curious Case of Benjamin Button. It is a nice movie, but also painfully long - almost 3 hours. It got me thinking - are movies getting longer & longer? I could have sworn that I have remembered them to be shorter, usually around 1.5h, now it feels like it’s closer to 2h. Obviously, this was only my impression, I had no hard data to back it up.

The Orton Technique

Another interesting photo technique (named after Michael Orton). To be perfectly honest, I’m not that big fan, it makes images a little bit ‘cheesy’. However, it should be interesting for every graphics programmer, as the idea behind it is almost exactly the same as behind fullscreen glow/bloom effect. Basically, it’s a blend of two images, the original one & overexposed/blurred layer. Sample result: Old comments Riddlemaster 2010-01-27 21:00:10 I hate bloom :) but still… it would be great if games looked like this - great picture ;)

Tilt shift photography

Been playing a little bit with tilt shift photography today. My first try here (Stockholm). Not the best source image (sky especially, technique tends to look better with whole picture ‘busy’) and perhaps a little bit too strong blur, but still kinda captures the ‘fake miniature’ look: Old comments Riddlemaster 2010-01-26 09:19:38 That’s true. It should be easy to remove this using some clone/stamp/patch tool though. admin 2010-01-27 08:47:10 Nah, I don’t want to tamper with it too much, let it stay as a record of my first tries.

Remote debugging in Visual Studio

Today I’d like to describe a relatively unknown feature of Visual Studio that can be extremely useful in certain situations - remote debugging. Remember all those situations when application work perfectly on your machine, but crashes on tester’s? ‘Old school’ way of trying to debug this problem was to add a very detailed logging, then analyze it. Fortunately, there is a more convenient method - we can simply connect to his machine and attach debugger to running application.

To assert or not to assert

(or rather: how & when to assert). Assertion is probably one of my favourite programming tools, however there are still few areas that I’m not entirely sure how to solve in an optimal way. First, let’s start with things that I’m rather convinced about, few simple guidelines for my ideal assert macro (funnily enough, during my career I’ve never seen implementation respecting all those rules at once): when it breaks into debugger make sure it stops in the same line assertion actually failed, not two hierarchy levels down (so every time it’s triggered one has to rewind first to see what’s wrong exactly)!

Reflection in C++ - Load In Place

I played a little bit with my Load-In-Place system. It used to only support vectors of PODs (stored by value). Now it handles also vectors of pointers & vectors of classes. Sample structure that’ll be saved/loaded automatically: struct IntContainer { int* pInt; }; struct SuperBar { unsigned long i; // [Hidden] float* p; bool b; signed char s; Color color; SuperBar* psb; typedef rde::vector tVec; tVec v; rde::vector<Color*> someColors; rde::vector<SuperBar*> superBars; rde::vector containers; IntContainer ic; }; [.

Reflection in C++ – part 2

In a previous note I wrote a little bit about my experimental reflection system for C++. Today, I’d like to describe a simple load-in-place mechanism I built on top of that. Basic idea behind LIP is to minimize the overhead of any processing after data is loaded from a file. Ideally, all that needs to be done is call to ‘fread’ to a memory buffer. For more detailed description of such system see Fast File Loading article by Ent/Incognita.

Reflection in C++ - a teaser

Whether we like it or no - C++ is an ancient language. It doesn’t have many features that are considered normal in some more modern languages. One of such missing features is reflection. It also never been lucky enough to get any kind of standard implementation. Over the years programmers, both main-stream & gamedev - have been patching their own systems. Today, I’d like to present yet another approach that I’ve developed.

Demoscene tribute: French 3D revolution

1996 was one of the best PC scene years in my opinion. It was also the year when some legendary Amiga/Atari ST groups released their first PC productions. It started at Saturne’96 party. It wasn’t one of the great 3 events (The Gathering/Assembly/The Party), it was local party, with French groups mostly. In 1996 however, the competition level was just crazily high. To this day I’m still not sure which one of the first two productions I like more.

Cruncher# update

I’ve read this note on Rachel’s blog and found out there’s tool similar to Cruncher, just for ELF, named pahole. It has a nifty feature of showing cacheline boundaries. Had a little bit of spare time this weekend, so decided to add it to Cruncher# as well. By default, it assumes that object’s start offset corresponds with cacheline start, but you can set ‘prefetch’ start offset from context RMB menu.

Anatomy of Duff's Device

Duff’s Device is one of the most brilliant exploits of C syntax. It’s used to unroll loops and save some cycles spent on loop ‘maintenance’. Let’s take a look at typical fill_n function: template RDE_FORCEINLINE void fill_n(T* first, size_t n, const T& val) { for (size_t i = 0; i < n; ++i) first[i] = val; } Now, assuming that element is not too expensive to copy, execution time of this function can be heavily influenced just by loop ‘maintenance’ I mentioned (counter modifications + jumps).

Vector swizzling in C++

Everyone who’s done at least some vertex/pixel shader/HLSL programming has probably encountered mechanism called “swizzling”. It’s an operation where we create new vector using arbitrarily selected components of another vector (also a little bit similiar to SSE shuffling). Code snippet is worth 100 words, so some examples: a = b.zyzx; // a.x = b.z, a.y = b.y, a.z = b.z, a.w = b.x a = b.wy; // a.x = b.

Coders at work - observations

Recently, I’ve been reading “Coders At Work” book when commuting to the office. It only takes me 15 minutes, so it’s going rather slowly. It’s a collection of interviews with some of the most famous programmers, really interesting. I’ve only read about 200 pages so far (5 interviews), but already found two intriguing points: almost everyone so far insisted on using printf for debugging. Yeah, they use some GDB, but not much.

Sleepwalker Games

Another Polish gamedev company. Founded by ex-CDPR employees, some of main forces behind The Witcher (including Lead Gameplay Designer & one of Lead Programmers). Keep an eye on those guys, you can count on interesting stuff coming from them. Good luck! Old comments Mateusz Loskot 2009-10-13 08:30:59 Hmm, it’s interesting. I’m wondering what has happened these guys moved out from CDPR. Anyway, good luck! admin 2009-10-13 08:55:04 Well, if you read some latest press news carefully/trace Linkedin etc you can probably figure it out :)

Tenerife

I’m on a short vacations these days, just got back from Tenerife. Really, really interesting place (way more than I’ve expected). Funnily, I went there by ‘accident’. Originally, we wanted to go to Madera, but I was trying to be too smart and waited for last minute offers so long that they were no longer available. I had to decide quickly on another place to go and Tenerife looked as good as anything else, so I though ‘what the hell, let’s try’.

Game Engine Architecture – review

Took me a while to dig through this one, book is over 800 pages. It has been written by Jason Gregory, who’s currently working as programmer at Naughty Dog. Jason has years of practical experience in the gamedev (Midway, EA, ND) and it really shows. There are too many books out there written by people who have never shipped anything bigger. This is not the case. When he writes how to do/don’t something, he usually backs it up with a real-world scenario.

Optimization is a full time job!

From time to time, when I have a spare moment, I like to run the game under profiler and see what’s changed since the last test. I do it every 3-4 weeks, roughly, and the basic conclusion is that code is like food - it has an expiration date, later it rots. It doesn’t really matter that just 2 weeks ago you eliminated 1000 cache misses, now they’re back, in a different place perhaps, but total number of misses per frame is almost the same again.

Crunching bytes. Harder.

Been doing some size/layout optimizations again, recently. Cruncher# proves very useful for tracking problems, however it’s not that great when I want to quickly examine the progress. I have to compile/link application again (takes time, especially if modified structure is included from many files) and reload PDB (in case of bigger projects - takes some more time). Luckily, we can force the compiler to do the work for us. It’s possible to configure MSVC to warn about all padding it adds after structure fields.

Ordering randomness

One of the things that game developers hate the most are ‘random bugs’. I’d love to get an euro for every time I got a bug report and when asked how could I reproduce it, received: ‘I don’t know, it’s random’. Thing is, it simply is not true in majority of cases. There are no truly random bugs, they are caused by certain sequence of events. Sure, sequence may be incredibly rare, very unlikely, but usually - it’s not random.

Random links, 31/08/2009

Some interesting links: Recast & Detour libraries. Recast is library that automatically generates navigation meshes from level geometry, Detour is a pathfinding library. Both created by Mikko Mononen. Demosceners may remember his Demopajaa tool (demo authoring tool) or Moppi Productions demos. Pierre Terdiman uses Recast in his Konoko Payne project, you can read about his experiences at his blog. Konoko Payne is a one-man project, Oni-meets-Max Payne game.

Demoscene tribute: Untitled/Dust

Untitled/Dust is IMHO one of the most underappreciated demos ever. Sure, it won The Party 1993, but I don’t think it later got the recognition it deserved. One reason may be that it was quite difficult to launch it on many machines (IIRC) + it required lots of conventional mem (I was lucky enough to have PC that was compatible with this demo, but it required some config.sys+autoexec.bat wizardry). Not as difficult as with Optic Nerve (great demo, as well), but still’ It may be not be the best example of flawless design (to put it mildly), but codewise - it’s amazing.

Blast from the past

I’ve found my old USB stick recently and discovered a nostalgic picture there: That’s a photo I made with my cellphone 27th of August 2007, around 5am. It could as well be titled ‘Final Days of The Witcher’ (well, there still was almost one month ahead). Can wall grew a little bit bigger, but ultimetely has been torn down. Hard to believe it’s been almost 2 years already (coincidentally, the game has just entered Steam Top 10 charts…).

If you can't beat them -- join them

I must admit I kinda agree with Charles Bloom - information is so dispersed these days. Now it seems that in order to follow you not only should read various blogs and news, but there’s lots of useful stuff going on at Twitter. Tried to defend myself from that, but it’s pointless, it really is a valuable source of info. So, from now on you can also find me here.

Assembly 2009

First, there was a NoooN (Ra only, hoped for Karl coding)+Excess+Andromeda invitation… Now, results & releases are available. So far I’ve only seen a winning demo. It’s nice, with some cool ideas and impressive fluid/smoke simulation, but I must admit I expected more from CNCD/Orange/Fairlight cooperation (then again, no Wili/Tsunami/Hoplite participated). Still worth checking out, obviously.

Siggraph 2009

You know the drill, will keep adding links here: Beyond Programmable Shading 2009, NVIDIA papers, SG 2009 paper list by Ke-Sen Huang, (both links courtesy of gamedev.pl folks), Light Propagation Volumes in CryEngine 3 (A. Kaplanyan/Crytek), Inferred Lighting: Fast dynamic lighting and shadows for opaque and transluscent objects (S. Kircher, A. Lawrance/Volition Inc.) Old comments Link Mini-Dump 08/17Jeremy Shopf 2013-08-06 02:25:30 […] Maciej Siniloâ?

Netflix company culture

Pretty interesting internal presentation on Netflix company culture. I’ve only heard about them because of their Netflix Prize contest and now I’m trying to find some more info. A company that treats its employees as grown ups, shocker. There are some pretty slogans at the beginning (company values etc… hard part is to actually obey them, not to chisel them in marble), but then it becomes rather interesting (I especially like slides 27-28 and salary review system).

Flying Wild Hog

New Polish development studio, founded mostly by Painkiller veterans, who later worked with me at CDPR for a while as well. Not much at their site yet, but keep an eye on it, those guys are cooking something really interesting. Also, they seem to be hiring, so if you’re looking for job – go for it, they’re a great, very talented bunch. I don’t think it’s very official yet, but nothing can hide from my detective powers…

(Source) code scalability

Today I’d like to write about source code scalability in its most literal form, as in true source code scalability, ie - how much one would have to type if he’d want to extend existing codebase. It’s an often forgotten, bastard sibling of ‘true’ scalability, but an interesting topic nonetheless. There are certain constructions that don’t really lend to modifications that well. I’d like to list some of them here’

Cruncher# - update

Just little fix (see original note comments for details) and one column more - padding/size ratio (lets me to find what structures waste most space, in relative terms). Same download URL as before. Old comments sconosciuta 2010-04-01 03:24:27 […] Place. Gregory on Data breakpoints. GameCoder.it L'assert, questa sconosciuta on Chromed editor …Cruncher# update | .mischief.mayhem.soap.Just little fix (see original note comments for details) and one column more - padding/size ratio […]

Random links, 02/07/2009

Dropbox - wanted to make some weekend experiments, so finally gave it a try and it really is as good as people say. Sharing files between different computers without hassle. It can either work completely in the background or you can treat it as a file server. Great piece of software. Paris Game AI Conference 2009 - report, highlights, presentations. Worth checking out even if you’re not AI programmer.

Crunching bytes

As you’re probably aware - there ain’t such thing as ‘too much memory’. It doesn’t matter how much there is, it’s never enough. Even if we fit, it still pays off to use the smallest structures possible, as they’re more cache friendly. The more we can squeeze them (without wasting too much time for depacking of course) - the better. Recently, I’ve been optimizing some X360 code and one of main problems (as usually with consoles) were related to cache-usage.

Lazy calculations considered harmful?

Actually, the trap I’m going to write about is a little more subtle and doesn’t apply only to lazy calculations, but it’s one of the most typical scenarios. Consider the following situation: 1float Rectangle::GetArea() const 2{ 3 if (m_isAreaDirty) 4 CalcArea(); // Calculates area (width * height), clears isAreaDirty flag 5 return m_area; 6} That’s rather typical (albeit very simplified, of course) example of performing calculations only when they’re really needed.

Virtual functions - an experiment

Some months ago I’ve read this article by Elan Ruskin, when he measures the overhead of virtual functions. There’s also a follow-up with test code, make sure to check it out as well. I’ve decided to extend the test application a little bit and add one more solution - direct function pointers. Instead of having global per-class vtable, we can store function pointers in each object, thus removing one level of indirection.

Sweden - what's different

OK, the weird things. Please remember, they’re weird from me, which usually means they’re simply different to what I’m used to. It may very well turn out it’s Poland/Italy/France that are weird. (you all just knew it’d come first, didn’t you) Buying alcohol. You can not buy beverages stronger than 3.5% by volume in “standard” shops. There’s a special store network called Systembolaget where you have to go (government monopoly).

Catching up (again)...

Finally got my laptop back, so let’s restart with a quick warm-up note. I’ve been in Sweden for over 1 month now. When I came here I realized it’s almost symbolic, because I started my first gamedev job in May as well. 7 years have passed and here I am again. Different country, different company, different weather, but same feeling. Sweden’s a very nice, quiet country. There are some weird things here, but in general it’s very foreigner-friendly.

Milestone

This word is usually enough to send shivers down the spine of most developers. This time, however, it’s something nicer. Check out the session program for Siggraph 2009 (bottom of the page). If I’m not mistaken it’s the first case that Polish gamedev is represented here, so it’s a kind of milestone for our small industry. My mate - Michal (we spent 5+ years at CD Projekt Red) - wrote paper together with Peter-Pike Sloan (yes, this PPS) and he’ll be presenting it.

The List

Doh, I got like 10 e-mails already asking about “The List” I mentioned… A little tired with explaining it’s just a very incomplete, totally subjective, personal list. Visit gamedevmap.com, scan Scandinavia/Netherlands area and you’ll get most of them :). Several people asked if I considered other Polish companies. I did, actually, but ultimately it doesn’t seem right now like there’s any company here able to produce game matching The Witcher scope and recognition.

..something begins

(…or continuation of this note) Damn, it seems like that laptop thing is more serious than I expected - motherboard died. They’re not sure yet if they can replace it, when or how much will it cost. I had a tiny note about virtual functions there, but cannot be arsed to code samples/write it again, so it’ll have to wait. In the meantime, other things have been cleared out, contract has been signed, so I can as well make it official.

Dead laptop

Damn, it seems like my Dell died. It just won’t start, something with power most probably (it doesn’t matter if I try with AC or battery, though). I’m going for quick vacations on Monday, so won’t have time to fix it before… Hopefully next week I should have it back. I had an article 90% ready there, but HDD should be OK, so I’ll publish it as soon as I can retrieve it.

Realtime Worlds - paid overtime

I normally don’t try to link to every interesting industry story, there are better sites for this. However, I’m gonna make an exception, because it’s worth notifying. Scottish developer - Realtime Worlds (Crackdown) has just announced they’ll be offering paid overtime for its employees. While “no overtime” would probably be ideal, it’s still very commendable move in our industry. Publishing it here, to help spread the word, they surely deserve every bit of PR.

Random links, 05/04/2009

“Almost perfect…” - story of Word Perfect (competitor of MS Word, for young readers), interesting read, Two-part blog entry from Jeff Vogel, if you’ve ever wondered on indie RPG sales - this one’s for you (Jeff’s owner of Spiderweb Software, probably the most famous indie RPG developer), Superannuation - great source of information about top-secret/canned projects. Usually data-mined from resumes, but not only. People are really careless sometimes…

GDC update

Wow, kudos to GDC folks, they’re really fast this year, many presentations can be found at the official conference site already. Even better, documents have meaningful names for a change, instead of typical s1533262.pdf. I’ve updated original post with some more links. I didn’t put separate entries for new publications that can be found on tutorial/slide page, if you’re interested – see comments, some additional links there. Old comments ed 2009-04-15 18:19:59 They just blocked access to slides.

Something ends...

OK, it seems like the initial supply of GDC papers has dried out. I’ll keep updating the original post with new links and create “fake” entries about bigger updates to activate RSS readers. In the meantime – there are big changes ahead. Soon, I’ll be leaving CD Projekt Red. I’ve spent over 5 amazing years here, so it wasn’t an easy decision. I decided it’s high time to try something else, though.

GDC 2009 proceedings

Let’s start, shall we? I’ll update this post with publications, as they become available: Jeremy Shopf (ATI): “Mixed Resolution Rendering”, Nocturnal - GDC 09 Release (Insomniac), Intel’s GDC materials +Project Offset new videos, Glenn Fiedler (Sony Santa Monica) - Networking for Physics Programmers (slides… sadly, kinda hard to figure them out without audio), Summary of Jeff Kaplan’s (aka Tigole) WOW panel - not your typical GDC stuff, but pretty interesting nonetheless (especially for all of us, (ex)WOW addicts),

DocOrganizer

GDC2009 has started, first publications should be available soon. Preparing for them, I wanted to organize my documents collection. “Standard”, filesystem organization isn’t perfect here. I usually try to categorize papers by conference or author, but it quickly gets messy. Say, I’ve paper from Siggraph2k8 by Bungie programmer. Should it go to Siggraph or Bungie directory? End result is that it always takes me too much time to find the publication I need.

Breakpoints in system libraries

I’ll just put it here, because I’m fed up with forgetting it and experimenting with syntax every time I need it. There are times when you need to put breakpoint in system function, like malloc or OutputDebugString. For example, I use the latter one sometimes, in order to intercept DirectX warnings (couldn’t find a way to make it break on warning, not only on error). Syntax for breakpoint window is (function): {,,kernel32.

Go with the flow

If you’re interested in lock-free/multicore programming, make sure to visit Charles Bloom blog and read his Low Level Threading series. Table of contents is a good start. You’ll find plenty of valuable links there, always good to have them gathered in one place (if you’re not familiar with the topic, reserve two weeks, reading all this stuff may take some time). On top of that, some Relacy-tested code (I tend to agree that code that has not been extensively tested with some automatic suite, cannot be considered safe) and many good insights.

Aligning arrays

When developing stack-based containers for RDESTL I’ve encountered the following problem - how to get block of uninitialized memory that’s aligned properly for type T. Consider fixed_vector class: template class fixed_array { ... char m_data[N * sizeof(T)]; Size is OK (we need N elements of type T), sadly alignment is invalid here. It may not be a problem for majority of cases, but try storing _m128s… Even when using 32-bit variables, they should be aligned on natural boundary (4 bytess) in order to rely on writes/reads being atomic.

Random links, 19/02/09

Some interesting stuff I’ve found recently: Intelligent Brawling - I’ve read it some months ago in Game Developer and it finally is online. Very interesting article about combat in action games. Tom basically analyzes several games, researching enemy behaviors - attack timing, combos, AI, tells and so on. Must read for every gameplay coder/designer. Gustavo Duarte blog - system/hardware articles on this blog are pure gold.

The Law of Demeter

I’ve been refactoring big pieces of legacy code recently and my work would be much easier if authors would have followed the Law of Demeter. It’s not even LoD per-se, it’s mutated version, because I’m not talking about calling methods, rather accessing fields. The general guideline is – where possible, function should only operate on a minimal required subset of data. Consider the following code snippet: float GetDistanceFromCamera(const Object& obj, const Camera& camera) { return (obj.

Single producer/single consumer bounded queue

Another little snippet. I’m a big fan of bounded containers for multithreaded environment. Sure, they’re not as flexible, but at least you don’t have to worry so much about memory allocation. Most of unbounded containers rely on some kind of list, so nodes have to be managed separately, which complicates the code and actually introduces hidden locks (unless you use your own multithreaded allocator). For specific types of applications (like games) you usually know roughly what’s maximum capacity is needed, so why shouldn’t we take advantage of this knowledge.

Demoscene tribute: the discreet charm of oldschool

A little bit late to the party, but maybe someone haven’t seen it yet and it’s definitelly something worth witnessing. Folks creating demos on “smaller” platforms (mainly C64 & Atari) just seem to refuse to acknowledge that golden years are gone. What’s cool, in many cases they manage to “bend” the reality and create stuff that simply shouldn’t be possible. Poster example is relatively fresh demo - Edge of Disgrace by Booze Design (winner of X 2008).

Rise and fall of software company

If you’re following news from gamedev/IT portals, you know that 2008 has been one tough year for the industry. Many good companies have been forced to either fire big part of their staff or even shut down completely. Reasons were probably different in every case. Sometimes it was recession, sometimes, recession could be used as an excuse to get rid of dead wood, in many situations hard times simply made internal problems more visible.

Crash handler/reporter (Win32)

Usually, I try to write about less common programming issues here, this time it may be something less “flashy”, but very useful nonetheless. To be honest, if I had to choose single most crucial feature I coded for The Witcher it would be this crash reporter/handler. It took me few hours of home-coding, but has proven invaluable in later years of development process. If you don’t have similar system in place yet and you develop for Win32 – just stop doing whatever you’re doing and implement it now, you’ll thank me later.

Launchy

Just a quick note – recently I’ve finally completed my quest for perfect desktop. I’ve found small launcher utility that lets me to execute applications that are not on my quickbar, so I don’t have to use desktop icons or “Start” menu. Instead, I just tap Alt+Space and have all my programs just few keystrokes away. Meet Launchy. It let me to remove all icons and hide taskbar, leaving my desktop totally clean.

Lock-free double ended queue (bounded)

Just a small snippet – as a title says - lock-free double ended, bounded queue in C++. Original version can be be found in Herlihy’s book, but it’s in Java. It’s not very general, it has been created specifically to be used in my work-stealing thread pool. Basically, each thread adds tasks to the bottom of it’s own pool and tries to steal from top of other threads’ pools when low on tasks.

Catching up

Few words about what I’ve been up to profesionally for past months. As you may have heard - Geralt is coming to the consoles. There’s PS3/X360 adaptation of ‘The Witcher’ in the works. It’s being developed in close cooperation with French company - Widescreen Games. They’re cool guys, basically mix of best oldschool French sceners (like Patapom/Bomb) and game developers (including Outkast programmers). Before diving head first we had to deal with re-designing many elements of the game like combat and UI.

Know your assembly, part 3

I’ve been playing with radix sort for RDESTL recently and MSVC optimizer surprised me one more time. First of all, it seems to generate much better code if my histogram array is local to function and not member (in the first case it makes better use of registers and keep less stuff in temporary variables). It costs us 4k of stack, but I can live with that. Other than that, generated code is pretty smart, sometimes almost too smart.

Shameless plug

I normally try to put here stuff that’s interesting to all kinds of readers (for carefully chosen definition of reader…) but today I’ll make an exception and post a link to Polish article. To add insult to injury, it’s an interview with myself. It has been conducted by an old demoscene mate of mine - Hollowone, known as Daniel Biesiada IRL, who runs a fairly popular IT/programming/.NET/game blog. Appearently, some of the readers of his site have been interested in finding out more about gamedev, some tales from the trenches and such.

Google interview process

What’s the best way to drive traffic to your blog these days? … Write an entry about your Google job interview. Recently I’ve found yet another one of those. This one is actually well written and quite interesting, so go read it first. Today, I wanted to focus on another issue, though – if you read comments for this article on Reddit, 90% of them seem to be from people complaining about the number of interviews he had to take.

Chromed editor

As you probably have heard - some months ago Google released its own browser - Chrome. One of it’s distinguishing features is that every tab is a separate process, so if one tab crashes, it won’t bring whole application down. I’ve read in different places about tries of applying this scheme for game editors. Imagine game (renderer) and editor being two separate processes. Should one of them crash, the other is still running, so that we can at least save our work.

Poor man’s Thread Profiler

There’s an interesting observation in Eric Steven Raymond’s essay - ‘The Cathedral and the Bazaar’ (I’ve heard about it thanks to the reference in ‘Dreaming in Code’). Eric notices: “Every good work of software starts by scratching a developer’s personal itch’. It seems to me like my problem is I’ve too many itches. When I was a young bedroom coder I’ve been basically scratching constantly. Every time I’ve learned about some new technique, I couldn’t resist and just had to try it in my code.

The Witcher - 1 million copies sold

So, it’s official now, as you can read in Edge. Pretty nice number for an Eastern Europe RPG on “dying” PC platform, I’d say ;) Old comments Aras Pranckevicius 2008-10-30 17:59:38 Congrats! Now, what’s next? :) Maciej Miasik 2008-10-30 19:14:20 Another million perhaps? :) js 2008-10-30 23:18:12 Congrats! The Witcher got a very good reception ! Miguel 2008-10-30 23:27:21 Wow, that just awesome!

Software Occlusion Culling

When I started my gamedev adventure I wanted to be a rendering/3D programmer. This was where I felt most confident. Just like 90% of demoscene coders, I didn’t have much experience with AI, physics or gameplay, it wasn’t really needed for demos. Later it turned out that other areas are very interesting as well, I ended up doing them all at one point and nowadays I don’t really code much 3D stuff.

MemTracer on steroids

If you’re familiar with MemTracer project you may be interested to know there’s a version that can be actually hooked to external application without much hassle. It has been created by Jean-Silvestre Zirani, visit project page for details. Jean contacted me some time ago, we had nice chats about issues with debugging memory related problems, I sent him latest sources and he decided to move MT to a more usable state.

RDESTL - changes

Seems like I’m mainly pimping RDESTL recently, but that’s all I’ve time/power to work on when I’m back at hotel. Quick update: latest hash_map included in Attractive Chaos benchmark (+bug fixes). It did quite well. One problem is it consumes memory like crazy, but benchmark works on a really huge set. Anyhow, memory/performance ratio can be controlled via load factor parameter. I’ve added simple stack class (built on top of other generic container, like in STL).

Warnings considered useful

As stated before, I’m a big fan of oversensitive warnings and try to compile my projects with the highest warning level (/W4) under MSVC. However, as it turns out, even at this level there are still warnings that are not enabled. For a complete list of warnings that are off by default, see here. The easiest way to enable them all is to use /Wall switch, but it’s too much even for me (mainly because of C4820, feel free to give it a try, though).

RDESTL: hash_map, another take

I’ve been reading lots of interesting stuff on hash tables recently and was trying to improve my RDESTL implementation of hash_map. At one point I had 5 different versions, but finally managed to create something that’s good enough for most applications. Granted, I exploit the fact that performance’s the most important factor, so I can live with some limitations that wouldnt fly in any more general library. I effectively “ban” two hash values (0xFFFFFFFE & 0xFFFFFFFF) for example and use it for my own purposes.

RDESTL - fixed_list

I didnt have much time to work on RDESTL recently, but I try to commit some new stuff every now and then (usually bug fixes). One rather interesting recent addition is a fixed_list class. Basically, it’s a rough equivalent of already existing fixed_vector. It never allocates any memory and works only withing given buffer. Let’s try to create linked list of integers, that can hold up to 64 elements: rde::fixed_list<int, 64> lst; lst.

Less painful prototyping in C++

Just a bunch of useful links/ideas that may help you if you need to make a quick prototype in C++ one day. I know, it may sound stupid, but sometimes it really is a good idea, especially if you’ve the engine+ compatible assets ready. Digression: of course, initally, you may try to be a smart ass and have this idea of making your prototype in C#/XNA. After all, it doesnt have to be very fast and it’s 100x more friendly with better turn-around times and so on.

Gamefest 2008 papers

XNA Gamefest 2008 papers are finally online. Get them while they’re hot. (this year with recordings, too!) Old comments Riddlemaster 2008-09-03 16:36:00 This time they are really nice. Of course much is about XNA (bleh) but the rest is very interesting. However, I’m a bit anxious that the way of DirectX development they chose is not the very best one… It seems they lack fresh ideas. Yeah, they introduce many new things but the core is still unchanged.

God of War – post mortem

Year 2005, last months of Playstation 2, next-gen consoles are coming. This is usually a good moment for ‘farewell hit’. Developers know the platform inside-out, there’s huge userbase. Sure enough, Sony Santa Monica creates God of War, game that later would be considered one of PS2’s greatest titles. I must admit I’m not that big fan of GOW’s gameplay (I suck at action games, though). Technically, however, it’s one of the most impressive games I’ve seen in the recent years.

NVScene 2008

NVScene 2008 done. Results here. If you watch only one production, make sure it’s Texas by Keyboarders, it’s damn impressive. Word of warning, though, demos may look a little pale in comparison after this, but still worth watching (make sure you’ve powerful rig!).

Distributed Processing

This year our company introduced a nice tradition - lucky folks who went to GDC referred talks they had attended to interested people. One of workmates presented Bungie’s conference - ‘Life on the Bungie Farm: Fun Things to Do with 180 Servers’. Basically, it’s an interesting talk about Bungie’s distributed build system (deals with code builds, lightmap calculations, resource packaging and some other tasks). It’s not a new concept of course, one popular commercial example of similar environment is XGE.

Real-Time Collision Detection review

I always try to take some books with me when flying for vacation, this year I finally managed to read Real-Time Collision Detection. I’ve never been a “true” physics programmer, I am not one now and I doubt I ever will, so I thought it’s not a book for me. After few pages I already knew I had been wrong. Turns out it’s book that every game programmer should read.

Random links

Just a few interesting links I’ve found recently: Visual Computing blog - a cooperation between Intel and Gamasutra. Links/articles mainly on topics of multicore/rendering, slightly focused on Intel’s technologies (TBB, Thread Profiler, Thread Checker, VTune). Worth checking out, to see what’s going on. They’re obviously people of great taste, too, as they linked to yours truly and that’s how I found about it :) Parallel Rendering with DirectX Command Buffers - Gamefest 2008 paper/source code by Vincent Scheib (of Demoscene Outreach Group fame).

Visual Scripting Languages

There’s an interesting entry on Christer’s blog about graphical shader systems. It reminded me of another issue that bothers me for some time now – visual scripting languages. They seem to be gaininig popularity recently and I am not really convinced it’s a way to go. Now, I am a programmer, so obviously, I’m biased, perhaps designers see it differently. As I understand it, main motivation for such systems is to let people, who are not familiar with programming (designers) to easily implement all their crazy ideas.

“My” Visual Studio color scheme

If you read comments to my CRC32 article, you’ll notice that the most important thing there is MSVC color scheme appearently. Some hate it, some like it, it seems to be Paris Hilton of color schemes. I also got several mails asking about my settings, so instead of replying in the comments I’ll just post here. It’s not really ‘my’ scheme, original version has been made by Oren Ellenbogen. I made some minor modifications, but they’re really miniscule, so I link to Oren’s version instead.

Simple instrumenting profiler

For every bigger project, sooner (if you’re wise) or later (if you’re, errr, not that wise) comes a moment when you need to answer yourself one very important question: ‘why the hell is it so friggin’ slow?!?’. Most common methods for determining bottlenecks in games/demos evolved with time. Back in eighties/early nineties, when we were young, restless and beautiful, the most common method was counting scanlines. Those were the times when we were not really interested in finding out how many frames per second we’re running.

Corfu

Wonderful place, reminds me of Sicily (weather, architecture, it’s much greener, though). I could easily see myself retire there. Few photos: Paleokastritsa Lakones. Pictures dont really do it a justice, perspective's distorted. Its damn high, you literally see half of the island from there. View from The Achilleion (Sissis residence on Corfu) Aah, lifes beautiful. Sitting in the shade, enjoying sip of cool beverage and view of Greek koritsis passing by.

Watchmen Trailer!

I normally dont do this, but this time my inner nerd is way too strong and…just…cant…resist… Watchmen trailer is here! (and I feel everyone should know this)…

DGTS

First, there was an essay by Joel Spolsky. Joel claims that #1 cardinal criteria your potential employee should satisfy is: Smart, and Gets Things Done. It became a popular saying, then Joel wrote a whole book on this topic. Finally, some weeks ago Steve Yegge wrote some more about it (and paraphrased to Done, and Gets Things Smart). Now, if you’re familiar with Steve’s blog, you should realize that “some more” is euphemism, basically, it’s another of those 10 page articles (although, as usually, it’s really interesting and personally, I enjoy his writing style).

Hashing made (even more) useful

One of the most basic issues in the game development is: how do we identify “things”. Thing can be, well, anything - logical object, resource, level, entity, animation etc. The most straightforward way is of course to name them and identify with strings (tags). So, you have “texture_leaves0”, “badguy_01” and so on. This solution has two advantages - it’s dead simple and contains bonus useful info. Unfortunately, it has also lots of problems.

The Final Warning

Recently I’ve been playing with SQLite for my new experiment (more about it later, when I’m done). It’s one sweet little library, integrating it and coding a quick C++ wrapper took me maybe 1 hour. As authors claim themselves - it just works. I’ve only one tiny complaint, though. As I mentioned before, all my home projects are compiled with maximum warning level and warnings treated as errors. Sadly, this seems to break roughly 50% of external libraries, including SQLite (trying to compile sqlite3.

Stupid C++ trick(s)

(idea shamelessly stolen from Jim Tilander and Power of Two Games. Not fullblown post, just random notes from time to time, as I learn/think about it) how to easily make sure all our header are self-contained? Include header as the first one in corresponding .cpp file. For example (ThreadPool class, ThreadPool.cpp file): #include "thread/ThreadPool.h" #include "thread/LockFreeMemList.h" #include "thread/LockFreeQueue.h" #include "thread/Task.h" #include "thread/TaskGroup.h"If my coding standard could only have single rule - it would be this one.

Firefox 3

Soooo, in case you haven’t noticed - Firefox 3.0 has been released recently. I gave it a try and quickly came to the conclusion it’s another proof that any software package can reach certain level after which modification can do more harm than good. Sure, version 2 had some problems with memory (see Stuart Parmenter’s blog), it probably didnt conform to standards perfectly and had some other problems, but I really liked it.

ITP – addendum

As promised, I performed some tests of my thread pool on quad-core machine. Difference between lock-based and lock-free version is bigger (than on dual core), but definitelly it’s not as significant as one could guess looking at results in Intel Thread Profiler (higher concurrency, smaller contention). The most important speed-up can be gained by letting main thread help workers when it’s waiting anyway (50 fps ‘> 61 fps), but this one is independent from other modifications and can be applied to lock-based version as well.

Intel Thread Profiler

Few days ago I decided to have closer look at my multi-threaded experiments, mainly to check if there really is any kind of difference between code based on locks and lock-free version. Downloaded evaluation version of Intel Thread Profiler and gave it a try. Especially for this experiment, I modified scenario a little bit. Mandelbrot is not the best test as tasks take relatively long time (with selected number of iterations one ‘frame’ would take over 2 seconds).

Demoscene tribute: world records

Subject is mainly an excuse to list some of my favourite productions. In general, I’ll try to talk about world firsts/world records in demos, tho. World first is just an effect that has never been done before (in realtime). Let’s start with one of the first demos I’ve seen and remember to this day. It’s from Amiga, which had a very active scene at that time. I used to visit my mate, who was swapper in Casyopea and he’d show me a demo or two sometimes.

Random thoughts (#1)

Just some random notes, that are too short for their own entry, but still rather interesting: Stack Overflow - new initiative by perhaps two biggest celebrities in the programming blogging community - Jeff Attwood and Joel Spolsky (even if he insists he’s not blogging, just writing essays). In terms of marketing it’s blogging equivalent of Marlon Brando and Jack Nicholson doing movie together. It’s also my first serious contact with podcasts.

Condition Variables under Win32

If you’ve been programming POSIX threads (or Java, C#, D…), chances are you’ve used condition variables. It’s also probable that after that you switched to Win32 and found nasty surprise - no “native” condition variables here. Of course, they can be implemented with help of other synchronization primitives, but it’s not for the faint-hearted (I’ve to read this article in small portions, like 10% at a time, otherwise my head starts exploding).

Generating subsets

I’ve been reading “The Algorithm Design Manual” (Steven S. Skiena) recently and I have to share with you one of the chapters, just because it’s too cool. In “The Witcher” we have the following problem: we’ve plenty of attack animations, most of them dynamic (ie, the character is moving forward) and not so many damage animations. Most of the attack consist of multiple hits. The problem is with synchronizing damage and attack animations (so that our opponent moves back roughly at same pace and similar distance as we move forward, playing his damage animations at the same time).

Lock free hell

For the last days (weeks) apart from playing GTA IV (mainly) I’ve been improving my thread pool class. I decided to implement system similar to the one described by Ian Lewis from Microsoft in “Getting More from Multicore” from GDC2008. Basically, it’s an extension of my system, it gives greater control over inter-task dependencies. Task cannot be started until all tasks it depends on are finished. In theory it’s rather easy, I just provide extra scheduler thread that deals with incoming tasks, if any of them is “ready” it’s put in a priority queue (priority in the most simple case is number of dependents), so that it can be processed by worker threads.

GTA IV

One of the simple measurements of game quality (popularity?) is how much do we talk about it during lunches. For a few days it’s been all about GTA IV. It hasnt yet reached level of WOW discussions few years ago (some of our mates actually threatened they would stop eating with us) but it’s close. Game’s great and at the same time it has soo many funny bugs. It’s understandable with project of this scope and freedom but still hilarious at times.

"Muckyfeet" of the world

Found an interesting article at Escapist. It’s a story of Muckyfoot, now-defunct gamedev company founded by some of the Bullfrog veterans. (Side note: the power of the original Bullfrog team is really impressive… they went on to found Lionhead, Elixir, Muckyfoot, Media Molecule (that’s ex-Lionhead, but still counts :) and some more… Think what they could achieve were they still together). As usually, when written by someone from “outside” it’s a little too poetic/melodramatic at times, but still worth reading (I love the bit where Gary Carr and Fin McGechie were told off for running in the corridors of EA… what’s that?

RDESTL - hash_map with linear reprobing

There are several approaches to implementing a hash map. Main difference is in the way we handle collisions between entries falling the the same bucket. Probably the most popular and elegant is “chaining”, where for every slot we have a linked list of entries. In case collision we just enqueue entry in list for correct bucket. Variation of this method is used for example in MSVC’s library. I implemented it in the first version for RDESTL as well, just because it was the most straightforward.

Google Tech Talks

I think I’ve already posted links to some videos from Google Tech Talks, but I’ve been catching up recently and found some other interesting movies. They all have a nice, distinct geek spirit… Where else can you find 50 minute presentation about the beauty of quicksort implemention? Three Beautiful Quicksorts (Jon Bentley) - who said sorting is boring? How To Design A Good API And Why It Matters (Joshua Blooch),

Number of array elements - addendum

OK, so how does this snippet work? There’s a function that takes array of N elements as an argument. It returns an array of N chars. Assuming sizeof(char) == 1, size of the return type for this function is N. There’s no function body, because it’s not needed, function is never called. On the other note, we’ve been hit by the Reddit Effect. Of course, in this case it wasnt a problem of breaking the server, but it screwed all my stats.

Miyamoto nominated to The 2008 TIME 100

Mario would be proud. (…they could spare this comment about fat kids, tho).

Number of array elements

(or one more reason to love C++). Problem: how to find out number of elements in a C++ array? The most popular form is probably: #define RDE_COUNT_OF(arr) (sizeof(arr)/sizeof(arr[0])) ... Foo myTab[10]; size_t numElems = RDE_COUNT_OF(myTab); assert(numElems == 10); It’s being widely used, however most people do not realize the potential danger with this small piece of code. Imagine that one day we decide to change our static array to dynamically allocated block of memory: Foo* myTab = new Foo[numNeededFoos]; size_t numElems = RDE_COUNT_OF(myTab); // Huh?

Lock-free, multi-threaded Mandelbrot

(yeah, the title is stupid) After I got a little bored with memory experiment I moved on to something more interesting - lock free containers and multi-threaded tasks/jobs. This is all rather new to me, so it seemed like an interesting stuff. What we have here is simple system for distributing independent tasks on multiple threads. Basic system was inspired by Industrial Light&Magic’s code from OpenEXR. Main difference is that attached snippet is basically lock-free (it only locks when initializing threads at the very beginning).

MemTracer strikes back

You may remember my proof-of-concept experiment - MemTracer. It started as a hobby project, but recently I had chance to test it in a real world application. It quickly turned out there’s a big difference between my simple test program and full blown game performing hundreds of memory operations per second. Below you can find list of conclusions I drew from this experience: realtime analysis is next to useless.

Console coding is hard

There’s a very interesting interview with Tim Sweeney at Team Xbox. It’s quite old, so chances are you already read it, if not - do it now. The part that caught my eye is where Tim says that programming for multicore architectures is, just, hard. What’s more, from their experience it seems that in this generation, writing an engine system designed for multicores takes about double the effort as single threaded.

Know your assembly, part 2

It’s interesting to examine code generated by C++ compilers, if only for nostalgia value. It turns out that compiler (well, MSVC) is pretty smart usually and employs same tricks we used when squeezing cycles out of software renderers years ago. For example it’ll almost always use _xor reg, reg _instead of mov reg, 0. Eons ago, on 8086 it was one cycle faster IIRC (sadly, cant find great Agner Fog’s instruction sheet anymore).

Breakpoint 2008

BP 2008 finished. Visit the official page for results and releases. The most interesting from gamedev perspective was probably a PS3 demo sponsored by Sony - Linger in Shadows. It was done by fellow Polish demosceners and judging by screenshots looks might impressive. Good job! [Edit] Movie links already at Pouet.

Know your assembly

Consider this simple code snippet, where we call copy constructor on an uninitialized piece of memory:void CopyConstruct0(int* mem, int orig) { new (mem) int(orig); } I didnt really bother with creating special version of this routine for fundamental types, after all this version: void CopyConstruct1(int* mem, int orig) { *mem = orig; } should result in same code as the one above, right? WRONG. In the first case compiler (MSVC) tests memory against null first.

RDE STL - fixed vector, first draft

Uploaded first draft of fixed_vector class to RDESTL (well, right now it’s just a different storage type, to increase code reuse). It needs some cleaning up and I’m not really satisfied with the shape of final interface for the moment, but the general idea seems to work. Basically, it’s exact equivalent of vector class, but all the memory is allocated statically on the stack. Capacity is generally fixed and shouldnt really grow (TODO: add methods to record watermarks).

Debugging heap corruptions

If I would have to choose family of bugs I hate the most (I would have to be under the gun obviously, as it’s a little bit like choosing your favourite illness) I would be inclined to go with heap corruptions. They’re silent, random, hard to reproduce and track down. Today I’ll describe my small collection of simple tips that helped me to stay sane during debugging sessions. First of all, let’s list the most obvious heap problems:

GDC 2008 notes

If you werent lucky enough to visit GDC this year, dont despair. There are already first notes from various sessions appearing. Make sure to visit Xemu’s (Rob Fermier’s) site, he has notes from most of the most interesting presentations up. Hopefully soon full proceedings will appear at GDC site. PS. Assassin’s Creed team numbers are crazy… 50 coders at the peak, 15-20 for AI alone. That’s more or less size of our entire team :) [Edit] More GDC goodies from Adam Martin (MMO focused).

Debugging file leaks - the easy way

Ever had problems with opening file that surely is present at given path? It most probably is the case of “too many open handles” problem. First of all, make sure it really is the reason, it should be easy enough with our new friend – pseudoregisters, just examine error code. The most common reason for this are file leaks (file is opened, but never closed). Files are “normal” Windows resources so you can use tools like htrace for analysis.

Pseudoregisters in MSVC - spreading the word

Very interesting article at CodeProject. Shame to admit, but I’ve been working with Visual Studio for years and it’s new to me. Good way to track down MSVC hardcore freaks in your company – see who knows about it. Old comments ed 2008-02-18 22:19:16 looks like undocumented feature to me :) fyi: recently I’ve also discovered a nice feature in debugger called “automatically expanding data”. You can edit file “autoexp.

More new/delete overriding fun.

Consider the following code snippet: struct Foo { void* operator new(size_t bytes); void operator delete(void* ptr); }; struct Bar : public Foo { void* operator new(size_t bytes); void operator delete(void* ptr); }; [...] Foo* b = new Bar(); delete b; Can you see a problem here? Yes, there’s no virtual destructor. It will not manifest itself (at least under Visual Studio) in an obvious way if you do not do anything in derived class’ destructor.

Advanced Windows Debugging - review

I bought Advanced Windows Debugging book last week. Shortest review would be: if you’re serious about developing big applications for Windows platform - just get it. There are chapters that were of less interest for me (yet?) - security or interprocess communication, but everyone will find chapters that justify every price. I found parts about heap/stack corruption, resource leaks and Vista especially valuable (visit http://advancedwindowsdebugging.com/ - I think there’s a sample available for download).

Links

Links for today: Geoff Keighley - Behind the Games - every episode feels a little bit like Dreaming in Code, just it’s set in the gamedev industry. My favourite article is about Trilobyte, but all of them are definitelly worth reading. Foxit Reader - PDF reader that basically can do everything that Acrobat can, only it takes 3MB instead of 60 and is like 100x quicker. First thing I do at every new machine is to uninstall Acrobat and get this one.

Demoscene tribute - Tran

This note is easier, because Tran has his own Wikipedia entry. I still consider him to be one of the most hardcore PC coders. My friends had a chance to meet him at Mekka/Symposium copy-party, and he actually visited Poland afterwards (he was travelling the world at that time and he had Polish roots). It felt a little weird, as he actually was one of my scene idols in times when I was only starting.

How to Damage the Morale of Your Staff

This note is a collection of posts from certain gamedev forum. I tried to select some of the more reasonable examples, so hopefully lonely manager who wanders here one day can learn something (if you’re from management - read carefully and sin no more). It’s a little sad, because most points look obvious and I didnt even put most of the creepy ones (ie, buy a new shiny Ferrari based on the royalties, the day you fire 50% of the crew) as people guilty of those: a) dont read, b) are beyond hope.

Insomniac's secret... and Dunbar's number

There’s an interesting thread at NeoGAF where folks wonder what’s the secret behind Insomniac releasing high quality product every year. It’s a very interesting read in itself (if you filter out some typical gaming forums posts), but I was especially intrugued by reference to the “magical number of 150” aka Dunbar’s number. Basically, it’s the highest number of individuals with which one can maintain stable social relationships with. More than that and you’ll most likely require more restricted rules, laws and formal structures.

Dell XPS M1530 Review

When I think of notebooks I always recall my first GDC visit. I guess it was in 2005, I went there with another programmer from CDPR. One thing we both noticed after 2 days was that we seemed like the only people there without notebooks. A little bit like poor relatives at the family dinner. It was funny at times, like watching a table with 5 Japanese folks, all typing furiously, not paying any attention to each other.

Protothreads in pure C

Now that’s some smart code. K& R would be proud.

Demoscene tribute - State of the Art

Yeah, I know, I know, I was supposed not to write about famous demos, in some cases, however, I cant help myself. State of the Art/Spaceballs is one of my favourite productions and maybe the best demo ever made. I appreciate it even more now than I used to in my scene days. I was graphics freak back then and preferred productions with hardcore code (like Rage demos mentioned previously). Problem with most of them is that they age quickly.

Walking the stack - one more way

Recently I’ve been trying to move MemTracer from experiment category to something that’s actually usable in real world scenario. It requires more work than I expected, but it’s slowly moving forward. One of the first problems I encountered was StackWalk64 function. It works nicely, but when called very often it can cause noticeable slowdowns. Walking the stack can be done manually by ESP/EBP traversing, but on Windows XP/Vista platforms it’s actually easier to use undocumented RtlCaptureStackBackTrace function.

Optimistic note

Two links for a good beginning of the week: Where The Hell is Matt? - site of Matt Harding, aka “that guy who dances”. Matt is fellow game developer, who one day decided to travel the world and… dance. He made the first video and it became popular enough to grant sponsorship for the second trip. Watch both, they’re very simple, yet amazing. You just cant help, but think that world’s a beautiful place after all.

Cheating for fun and profit

Yesterday I had one of my weirdest debugging sessions in the last few years. Background: for some time we’ve been having problems with a third party library that comes without source code, only .lib/headers (no names given to protect innocent). It seems like not all objects were deleted after deinitialization. After basic investigation it turned out to be some kind of problem with reference counting, objects couldnt be removed because they were still referenced.

Spot a bug

I’ve found an interesting bug in a very old code today. Consider the following code snippet: 1struct foo 2{ 3 void* operator new(size_t t); 4 void operator delete(void* p); 5 int i; 6}; 7[...] 8{ 9 foo* f = new foo(); 10 ::delete(f); 11} Can you spot a bug here? Read rest of the article for an answer. It all boils down to those two ‘:’ chars. It forces compiler to call global operator delete instead of this defined for class foo.

Compile-time iterator type

Something we’ve been wondering at work one day (just for kicks, but being resident template freak I couldnt resist to give it a try). Challenge: given STL collection, find a way to determine ‘compatible’ iterator type for it. Example of intended usage: std::vector v; for (ITER_TYPE(int, v)::iterator it = v.begin(); it != v.end(); ++it) ; // do something here. Do not read further if you want to try it by yourself, solution follows.

VES Awards

“The Witcher” Cinematic intro by Platige Image has been nominated to VES awards! More info at http://www.visualeffectssociety.com/. Congratulations to folks at Platige (…and pat on the back for my collegues as well, as they’ve been coordinating it).

Why Google will take over the world

It dawned on me when I’ve been trying to find a good place to upload my photos to. Most known service is probably Flickr, it may be the best even. Thing is, I hate registration process. I’m registered to 20+ different places and if I can avoid another one - I will. It turns out that if you have a Gmail account (which is worth to get, because as far as free accounts go, it’s a very good one) - you have access to virtually every service Google offers, without further fuzz.

RDESTL - string class

Copy-on-write behavior of the string class is implemented as policy now as it may or may not be desired. I’ll add “standard” storage policy as well, so it can be easily switched between. Old comments sconosciuta 2010-04-01 03:24:27 […] new products and limited editions of international brands as well as independent ones. We…RDESTL string class | .mischief.mayhem.soap.Copy-on-write behavior of the string class is implemented as policy now as it may or may not be […]

Demoscene tribute: Rage

The day has come to pay small tribute to my demoscene roots. From time to time I’ll publish short article about some of the most interesting productions/groups (in my subjective opinion of course). I’ll try to avoid the most famous demos and focus on those that may be not known to the mainstream audience (so no kkrieger, even if it’s amazing). We’ll start with Swedish group Rage. It’s one of my (if not THE) favourite PC groups, even if they hail from Amiga scene.

Five Short Video Game Industry Keynotes

Brilliant. Saves money as well, because now you dont have to go to GDC2k8 :>

'Peopleware' notes

As lead gameplay programmer, my ‘main’ responsibility is still coding (thanks God), but in the meantime I pretend to do some managing as well. I dont really feel as comfortable here as with programming, so during Xmas holiday I’ve been reading “Peopleware”, very interesting. Two most striking issues I found so far are: crunch (of course) - authors write about obvious problems with productivity and morale, but they also notice a very important thing that’s not mentioned - crunch tends to have a negative effect on team spirit in the long term.

Hail to the king, baby!

Everyone’s writing about that, so I will as well. After 6 years another teaser trailer of Duke Nukem Forever has been released! Sadly, it doesnt show much gameplay. It’s good to hear that they’re still trying to finish it…

RDESTL - SVN

Instead of uploading complete code package every time, I set up SVN repository for RDESTL. Click here for the latest version of the code. Progress will be a little slower now, that I’m back at work, but I managed to add first, very basic version of COW string class. Old comments admin 2010-05-15 20:00:29 Pavel: Personally, never used it as a whole package and sole container/algorithm library, so more of a playground.

MSVC curiosities

While developing/optimizing RDESTL I found two funny curiosities in Microsoft Visual C++ 2008 (Express). All my home projects are compiled with maximum warning level and warnings treated as errors. One of the additional warnings in this setting are unused variables. MSVC is a little bit oversensitive, though, because it doesnt treat calling a destructor as ‘using’. Example: template<typename T> void destruct(T* mem, int_to_type) { mem->~T(); } Compiler will complain about ‘mem’ not being used.

RDESTL

I’ve some days off after finishing the project, flying to warm countries for holidays soon, but in the meantime I started reinventing the wheel for n-th time. I was inspired by EASTL (Electronic Arts’ version of STL) and tried to create small subset of STL, aimed at game development. I started with stuff that I knew would be needed, I dont plan to add multiset equivalent soon :). Main goals were:

MemTracer (part 2)

Seems like I should add some more info about previous note. There are two applications: memtest.exe - C++, it acts as a server, starts and waits for connection. As soon as it’s established it starts sending info about memory operations. MemTracer - C#, client application. It connects to the server and perform all the analysis of memory allocations/frees. In real world scenario memtest would be our game, role of MemTracer stays the same as it is.

MemTracer

As we’re more or less done with The Witcher, I’ve some time (and energy) to do some hobby coding again. Recently I’ve been toying with a new approach to memory allocations tracking. “Traditional” way is to overload new/delete operators, so that they take additional arguments (file+line) then use some preprocessor magic to call them with __FILE__ + __LINE__. Best known example of this approach is probably Paul Nettle’s Memory Manager.

Tabview

Tabview must be a program with one of the best size:usefulness ratios out there. I’ve been searching for a way to examine our profiling data and it’s just perfect.

We're done!

..or so it seems. Need sleep.

Finishing...

We’ve entered the final stage with The Witcher. This means optimizing & bug fixing. Right now I’m mainly working on the optimization side. So far I’m rather happy with the way I modified our old AI update system (it was legacy code from Aurora), it saved up to 5-7ms at big levels with lots of objects (we’ve up to 200 AI controlled citizens in Wyzima for example, not even counting other types of objects here).

Finally

Someone seems to be doing MMO football game. That’s the kind of game I’ve been dreaming to play since several years. Visit: http://www.footballsuperstars.com/ for details.

WordPress database error

I’ve been getting this strange “Can’t open file: ‘wp_comments.MYI’. (errno: 144)” error in WordPress recently. The fix is pretty easy, you log in to phpMyAdmin, select wp_comments table and repair it (choose from the drop down menu).

Break

Long time since last post. This delay has been caused by an accident I had. Been hit by a car, spent almost 3 weeks in coma. Almost everything’s OK right now, tho, I’m back in work already.

Interesting links

Random collection of links I’ve found recently: Competing on the Basis of Speed - very inspiring talk by Mary Poppendieck, it made me order their (her and Tom’s) book (“Lean Software Development”). Scrum and XP from the Trenches - the best article on Scrum I’ve seen. It’s very practical, down to earth and all the examples are based on a real project, not some ideal, simplified scenario. Read it now.

Akismet

I’ve installed Akismet about one week ago, it works excellent, no more spam in comments (it started to become a real plague). Highly recommended. We’re getting into alpha phase with The Witcher, so I dont have much time these days, but I plan to write a small note about my experiences with tracking/fixing leaks and other memory related problems (as it’s what I’ve been mainly doing for past 2 weeks).

VS font/color schemes

I found this very nice font/color settings file for VS.NET at Jeff Atwood’s page. The only thing I modified was identifier color, which I made a little darker, other than that it was perfect. Give it a try if you’re bored with default settings and too lazy to create your own one from the scratch.

Atari

I can finally announce it officially - Atari will be our publisher for Europe/Asia.

IPod

It’s rather ironic, but recently I’ve been using my PSP headphones with IPod because they’re like 3 times better than those provided with the player. One would think headphones are an important part of this kind of device.

Starstruck

Get it now! Best demo I’ve seen in years, reminds me of my favourite Rage demos (Reanimator, Robotnik). Music is simply amazing… Kudos to TBL guys, great job! Old comments NeARAZ 2006-08-14 08:14:14 Well, I wouln’t think it’s the best demo on the absolute scale. For example, some Asm2006 PC demos were also great. In Starstruck, I did not like the girl part. But anyways, taking into account that it’s an Amiga - yes, massive props.

BASS2?

There’s a very interesting interview with Charles Cecil (Broken Sword) at Eurogamer. He talks about upcoming BS game, state of industry, but the most interesting for me is the bit where he says there exists a possibility of Beneath a Steel Sky sequel. BASS is one of my all time favourite games, so I really hope they’ll create BASS2 one day.

About std::for_each

Few weeks ago I promised to whine some more about std::for_each. _In many C++ books and articles it’s presented as an ultimate loop solution. Typical example is some _for _loop, which is later replaced with for_each form. Funny thing is, even there, in many cases the latter piece of code is 2-3 times longer than the original. Is it worth the hassle? Typical example, taken from here (this is randomly chosen article, no hard feelings):

Improve your build process in 5 days

5 days ago our build system was rather traditional, not to say old school. We had a one-click full build, but it was executed manually. Usually about 1 build per day, sometimes more often, sometimes more seldom, it depended on the number/importance of changes. I’ve been thinking about improving it for long time, but never really could force myself to actually try it. Finally, about one week ago I decided it’s really high time to give it a go.

A Critical View of C++ Practices

http://www.accu-usa.org/Slides/ACriticalViewOfCppPractices.pdf - very interesting paper about some modern C++ practices. I really enjoyed reading it, because I could find relations to my own “coding biography” there.When I first found out about all those nice design patterns , I started to implement them everywhere I could (if all you have is hammer…). I replaced all my global variables with Singletons and so on. Now, after few years I’m almost at the same point where I started.

comp.lang.c++.moderated

How can you not love this group? Where else can you see discussion about the perfect ‘for’ loop taking 240+ posts and counting?

Artificial Intelligence

Recently, we’ve been desigining AI system for The Witcher. It’s different from previous systems I created, because they were usually mainly focused on combat. They were rather typical state machines with patrol/attack/chase/escape/etc states. This time, we focused mainly on everyday NPC behaviours, we want the player to feel like he’s in the middle of living world. Basically, there are two extremes when it comes to modelling system like this (most of AI systems in games are somewhere inbetween).

Hello, world!

What would a programmer’s blog be without “Hello world”? Old comments NeARAZ 2006-06-04 17:16:43 Well… have you actually ever written a hello world program? Now that I think of it, I did not… admin 2006-06-04 17:47:13 It was a long time ago, but I’m pretty sure I wrote it when I was learning my first programming language (Basic on ZX) :).