On Tuesday, 25 October 2011 21:44:02 UTC+3, Benoit Jacob wrote:
> I've started a stub of a wiki page, [...] to keep track of what still needs
> to be accomplished to claim that the open Web platform is 100%
> ready for gaming, [...].
That list looks quite comprehensive to me, but since we're talking 100 % here, I thought I would add my two cents. I have lately been trying to develop a moderately complex game in JavaScript and WebGL. The good news is that most difficulty has had to do with my lack of game development experience. Basic 3D was relatively easy to pick up but AI is proving to be a time sink like no other.
However, there have been some browser-related annoyances too. The ones missing from the above page are:
* Clean yet fast code *
In general, I have been very happy with JavaScript performance I have seen in Firefox and Chrome. As a representative example, I converted a simple collision-detection system from JavaScript to WebCL as an experiment. My test case was only twice as fast as a CPU-based WebCL kernel (Samsung WebKit implementation) than it was in JavaScript (Firefox, Chrome). Not optimal, because 2x performance differential might mean reducing the scope of the game to (for example) 1000 units from the 2000 possible with native code, but by no means a showstopper.
The problem is that to achieve this level of performance I have to, for example, preallocate all my temporary vectors and matrices and return the results from basic vector and matrix operations in explicit parameters. In C# or C++ I could just implement them as stack-allocated values and do away with the extra parameters. I could overload the operators to make the code cleaner still. This can make a big difference in AI code, for example.
This doesn't really mean that I'm pining for stack-allocated user-defined value types, since something like escape analysis could help here, but see below.
* Consistent arithmetic *
Some types of games, especially RTSes, depend on being able to execute code perfectly consistently on multiple machines. Floating point numbers greatly complicate this because x86 processors have an "extended precision" mode when floating point operations are performed in 80 bit internal precision even if the operands are stored externally in 64 bits.
I'm not sure if it's just too subtle for me, but even though ECMAScript 5 specification specifies the rounding mode for floating point, it doesn't seem to specify internal precision. Okay, so I'll stick to integer values and be careful not to overflow. But every time I need to divide, I'll have to remember to add | 0 after the operation and that is yet another thing that makes the code less readable.
* Predictably decent performance *
If I write a piece of well thought out C or C++ code, I can expect relatively decent baseline performance, even if my compiler isn't that good or advanced optimizations are turned off. With JavaScript, C-rivaling performance comes from VM wizardry that is:
- Vendor-specific, i.e. even though Firefox and Chrome tend achieve relatively even results, they achieve them by subtly (and not so subtly) different means.
- Underdocumented, i.e. code can get qualified for or disqualified from certain optimizations based on heuristics that are complex and fully described only in JS engine source code.
- Invisible, i.e. even though there are ways to find out how the JS engine has chosen to compile a certain piece of code, it requires a separate debug build and must be dug up from some textual dump instead of being conveniently available in Firebug.
Even if Firefox added escape analysis, I would be afraid to rely on it in my APIs because it might not exist in Chrome and Safari and there might not be any documentation to help me fully understand how it works and what the limitations are.
* Three out of three browser coverage *
I have seen a couple of cases where two out of Firefox, Chrome and Safari fully implement some spec or feature, but the remaining one is missing something important to me. So far there has always been an easy enough workaround that allows me to progress, but each such encounter tends to take one evening to resolve. Examples of these features include:
- Firefox taking long to implement DataView (bug 575688, close to done now, it seems)
- Chrome and Safari taking long to implement Function.prototype.bind
- Safari deciding to stick to hixie-76 WebSocket for now
tl;dr Building a pretty nice JavaScript-based RTS seems eminently doable, but the code can end up cruftier than my aesthetic sensibilities approve of.
The above comes with a huge disclaimer, namely that I'm not a game developer but a web developer who is occasionally working on a game for no particular reason. My opinions might not match those of people who do this for a living.
--
Aapo Laitinen