April 12th, 2008
Ok, I gave up and joined Facebook. If I know you and we’re not connected yet, poke me!
(”Poke”? … sounds like BASIC. Oh dear I’m such a geek.)
April 12th, 2008
Ok, I gave up and joined Facebook. If I know you and we’re not connected yet, poke me!
(”Poke”? … sounds like BASIC. Oh dear I’m such a geek.)
April 7th, 2008
Some people have had troubles with the previously posted SAP code, claiming that it was crashing when deleting objects. As it turned out, they were incorrectly using the library. So I updated the small test coming with the lib. The new version is here. If you define TEST_REMOVAL in the main source file, objects will be removed as soon as they collide.
Note that the SAP code didn’t change a bit - just the test case using the library. If you didn’t have troubles using the library before, there’s no need to download this new archive.
I kept both archives: the old one uses VC7, this one VC8.
April 6th, 2008
EDIT: I just fixed a crash & some bugs and re-uploaded the file below. You may want to download it again if you grabbed the previous version.
—————————————-
Here’s a quick Konoko Payne update. This thing has no end and I may have bitten off more than I can chew. But I’m still chewing.
Notable fixes for this release, for what it’s worth:
Other than that, I worked a bit on a state machine editor. There’s a first version available, you can access it this way:
You can then select a character, edit its “motion cells”, and the “transitions” between them. There are a lot of parameters, and each character has hundreds of motions and thousands of transitions. I was previously editing this manually in the compiler’s IDE… It worked up to a point, but it became increasingly painful over the years. So I finally decided to bite the bullet, and then started a small editor for this. To be honest I’m not sure I will actually use it. So far it looks like directly editing a text file is just as fast. I’m not sure how people deal with that in “real” companies. I’ve seen some of them using text / XML files, either edited by animators or by gameplay programmers (I think it’s an animator’s job rather than a gameplay programmer’s job, but some animators are very reluctant when it comes to defining those transitions). I also saw a couple of other companies using home-made editors, visual or not. I’m not sure what the usual packages like Granny provide here. It seems a bit difficult to use a middleware to define those transitions and blending parameters, since a lot of things not directly related to character animation, like sound and visual effects, should also be linked to specific animation or transition frames - and hence, ideally edited in the same tool as the motion’s blends. A generic trigger mechanism (user callbacks) might help, but then the middleware’s editor can only edit those generic, blind triggers - without giving a proper pre-visualization of the result, since it doesn’t know anything about the engine’s special effects those triggers are linked to.
Anyway, my next immediate problem is the throw system, which uses the same animation & transitions as normal moves, but also requires extra parameters - currently not supported by the editor. So the state machine exported by the editor currently lacks this information.
Better, later…
Link: the fallacy of premature optimization
April 4th, 2008
http://www.acm.org/ubiquity/views/v7i24_fallacy.html
Kind of old but I feel like posting it anyway.
March 12th, 2008
There was a thread on the ODE mailing list recently, where I wrote some notes about exceptions and the problems that come with them:
- Bigger exe size, by simply turning exceptions on.
- Performance hit (often tiny, sometimes significant), by simply turning exceptions on.
- Uncontrollable cost, depends on compiler. Even if you check the assembly on PC / msvc, there’s no guarantee the cost is the same on PC / gcc or on PS3. Not using them at all provides peace of mind here.
- Dubious support on consoles. If you have to drop exceptions on platform X, you probably need a workaround/alternative for it. So why not using the alternative all the time? Or do you drop all error messages / checks on platform X ? Or do you maintain two codepaths, one with exceptions, one with the alternative?
- Writing “proper” exception code is not trivial. The more people in your team, the more chances one of them is going to screw up.
A lot of people don’t see why they should pay this price for something that is not even supposed to happen under normal circumstances.
And then I suddenly realized I never really profiled the cost of exceptions in ICE. There’s a simple reason for this: I have a check preventing me from compiling with exceptions enabled. It has been there for years, to make sure I never forgot to turn them off. Removing them at the time was more like a hunch, and a good practice back in 1999 (exceptions were not supported on Dreamcast and we got bitten once when porting a PC engine to this console).
Anyway, out of curiosity I removed the check and compiled Konoko Payne with exceptions turned on (using VC7). As expected the size of DLLs became bigger (numbers are sizes without & with exceptions):
IceCharacter.dll 94208 98304
IceCore.dll 286720 299008
IceDX9Renderer.dll 180224 184320
IceImageWork.dll 102400 114688
IceMaths.dll 225280 245760
IcePhysics.dll 217088 249856
IcePrelighter.dll 37376 43008
IceRenderer.dll 327680 344064
IceRenderManager.dll 937984 1028096
IceTerrain.dll 37376 39936
KonokoPayne.dll 589824 684032
Meshmerizer.dll 307200 364544
Opcode.dll 454656 499712
SystemPlugs.dll 139264 163840
————————————–
Total 3937280 4358656
So the difference is 421376 bytes, or 9.66 % of the total. Almost 10% ! That’s huge.
But wait. There’s more. The biggest surprise was the performance impact. I just ran the game and checked the framerate immediately when it starts, not moving the camera or anything.
FPS without exceptions enabled: ~85
FPS with exceptions enabled: ~67
Oops. That’s a drop of 18 FPS here?! I admit I didn’t expect this. I never saw exceptions having such a big impact on framerate. Last time I checked this, in the NovodeX SDK, the difference between the builds with or without exceptions was around 5 FPS only IIRC. But then again, I was only recompiling the physics engine, not a complete game… This might explain why I never recorded such a huge performance impact.
This sort of confirms to me something I’ve been suspecting for a long time: optimizations matter. All of them. Conventional wisdom says that “premature optimization” is bad, and that you should only optimize your bottlenecks until you get a “flat profile”. Fair enough. But what if you would have optimized all your code all the time instead? What if you wouldn’t have skipped “small” optimizations that could have been performed everywhere? Disabling exceptions for a single function doesn’t save much, but disabling them everywhere in the code adds up to a 18 FPS gain! What if the same was true about other things…? What if you could gain the same or more by writing optimized code “all the time”? This is something I’ve suspected for a while, and seen in practice a few times.
I remember when I first joined Novodex and started optimizing the SDK. There was no clear bottleneck, it was usually a fifty-fifty story between collision detection and the solver. However the code was literally full of small nasty things that could have been written in a better way. I spent weeks and weeks rewriting those, removing templated arrays from critical areas, inlining (or actually __forceinlining) things instead of trusting the compiler for this, replacing divisions with multiplications by the inverse, moving the code around so that called functions are closer to callers (ideally in the same compilation unit - closer in the CPP usually means closer in memory after compilation), replacing for loops with while loops, replacing qsort with radix, removing conditionals in the solver, replacing some virtual calls with C-style function pointers, saving a few bytes here and there in data structures, ordering data members in classes by size to minimize losses in padding, etc, etc, etc. The core algorithms never changed: just the way the code was written. Just details. It was all about details. But everywhere. Did it pay off? I sure think it did. I will always remember a comment made by Dennis from Meqon, visiting us in Zürich, when we were still friendly competitors. He said something like: “I noticed a big speed increase between the previous release and the one you worked on. Did you rewrite things using SSE code?”. No, I hadn’t been playing with SSE. I just micro-optimized the damn thing absolutely everywhere, for weeks. I’m sorry but details still matter. The devil lies there, making your code slow.
In that respect, the optimization process is not much different from what it was on Atari ST, where we “saved one NOP” at a time in inner loops . (We counted time in NOPs, not in cycles). One NOP didn’t matter much! But saving one NOP every day for two weeks certainly did.
March 11th, 2008
This is kind of cool:
float Lifetime = FLT_MAX; // Use FLT_MAX for “infinite lifetime”
Lifetime -= 1.0f; // Or elapsed time or whatever, small value
=> the IEEE float machinery is such that “Lifetime” doesn’t change in this case. So an infinite lifetime is really infinite, automagically
March 9th, 2008
- Some restaurants in Napoli have very weird names. It means “Kill me tonight” in french.
- An old friend from school, Laurent Houdard, plays in a very cool band those days: Shine. Check it out!
- You can see me on the cover of “Espaces Naturels” issue 15, a french magazine about… nature. Yes I know, that’s the last place where you would expect a coder to appear. The world is a weird place, what can I say? They liked the Blue Lagoon picture and re-used it for their cover.
March 1st, 2008
After the last Konoko Payne update I got a complaint about the Furies’ voices in the game. Apparently Oni plays all those samples 1.14 times faster, and the coefficient is stored somewhere in the binary raw file, probably as meta-data for the particular wav files. Since I only replay the wavefiles as-is in KP, they appear to be slower than the original. And fans complain.
And so I started thinking: hmmm, I would have to assign some more parameters to each sound file, update the parsing code, and… and…
…and then I realized it was bullshit. Don’t touch the script files or the parsing code: just change the damn pitch in Audacity or something for whatever files are used by Furies. End of story.