

The challenges of Creating a Civilization Web Game - roschdal
http://code.google.com/p/freeciv-forever/wiki/FreecivWebClientStatusAndChallenges

======
DrJokepu
My solution: drop support for IE. No, seriously. I understand that it has a
very large "marketshare" (installation base) but I think that very often IE is
used on office desktops, that is places people wouldn't use for playing games
anyway.

While there were times when IE was a decent browser it is clearly standing in
the way of innovation at the moment. It is very easy to download a modern
alternate browser and a large number of websites using the canvas element
would force Microsoft to build a fairly good implementation of it into IE 9
(as it was I believe hinted by the IE project team leader anyway).

~~~
staunch
> _...IE is used on office desktops, that is places people wouldn't use for
> playing games anyway._

Pull the other one!

~~~
cakesy
OK some games, but I am yet to see anyone playing Civ 2 during work hours, or
Alpha Centauri. That would sure make me laugh.

~~~
ovi256
And then cry, if they are on your team. 5-10 mins of a flash game during a
break ? No problem, it will help them relax. Several hours of FreeCiv (and Civ
is a huge time-sink) ? Not during the workday, God no.

~~~
DrJokepu
But I promise I'll stop once I discover Gunpowder!

------
dood
I suggest dropping the project, since civ has cost humanity enough already -
browser civ could cripple my productivity... just a few keystrokes away when
already procrastinating. I both love and fear this project.

~~~
dave_au
I had to write a freeciv patch for my girlfriend which adds a daily move
and/or time limit to the game.

It was much appreciated, still have a couple of odd behaviours that I'd have
to iron out before letting it out into the wild.

------
lionheart
Well, the first thing I would suggest is putting all of the images into one
file then using CSS to control what portion appears.

That should cut down on both latency and issues with IE only downloading one
image at a time.

~~~
roschdal
So you are suggesting to stop using the HTML canvas element, and instead use
Javascript to render tiles which are clipped using CSS from one large image?

~~~
lars
I think you could do both. Position 96x48px divs with css sprites over the
canvas element to draw the images. I think this would be a performance win
too, because browsers are already very good at drawing things like css sprites
(although I don't know how well it combines with the canvas element).

~~~
nostrademons
What would you end up drawing on the canvas, if the images are drawn with
sprites? I can't think of anything else in Civilization that gets drawn, other
than text for city names (which should probably be done as absolutely-
positioned spans).

~~~
wlievens
I think you can do sprites _within_ canvas.

~~~
nostrademons
You can, but it's quite a bit slower. IIRC I benchmarked drawing a 32x32 image
on canvas at about 15ms, while setting the top and left properties of an img
tag or div with a background image was under 1 ms. The absolute numbers mean
nothing (it was on an old laptop under Linux), but the ratios indicate at
least an order of magnitude different in performance.

------
pohl
This is a cool project idea. My first impression is that this feels like a
natural fit for GWT. The ImageBundle mechanism would allow you to
automatically build css sprites at compile-time -- and the logic for accessing
the individual tiles from the sprites: (The gwt-canvas project is a small
wrapper that would allow you to draw instances of the Image class to the
canvas. <http://code.google.com/p/gwt-canvas/> )

It would also make it easier to move larger chunks of the FreeCiv client into
the browser in a manner that would be easier to refactor and maintain than
Javascript - and while being compiled to be as small as possible.

Java, for all its faults, is strong in refactorability, which would be
essential for keeping the code in sync with a moving target like the current C
implementation.

~~~
Keyframe
My first thought too - this also might be a perfect fit for something like
vaadin where you do everything on the server side and push it to the client
gwt for rendering.

------
GavinB
I think the real question is, where will you possibly get sufficient cleavage
to advertise it? <http://www.codinghorror.com/blog/archives/001286.html>

~~~
wlievens
God I hate those ads. They pop up everywhere. I hope that game dies.

------
Maro
Can you do some kind of differential download and local move? Eg. when the
user moves his mouse to the left 20 pixels and the world scrolls, then you
only have to discard 20xheight pixels on the left and fetch 20xheight pixels
from the server to bring in on the right and move over the entire canvas (or
whatever) by 20 pixels, without calling setpixel() for each moved but
unchanged pixel. Then add any other fluff such as a building exploding or
whatever.

~~~
nostrademons
I think that'd actually be slower if it means you have to do the drawing on
JavaScript (vs. the browser's native rendering engine). As a rule of thumb,
anything on an interpreted JS engine (not Chrome or FF3.5) runs about 1000
times slower than the equivalent C.

The way I'd do it is create a bunch of large tiles (like the size of Google
Maps) and pre-draw all the sprites onto a single tile. Put those tiles into a
single container div that is bigger than _its_ container, positioned
absolutely, and clipped with overflow:hidden. When the world scrolls, simply
change the positioning of the container. If it scrolls far enough that you
need to render another tile, drop the one off-screen and pre-render its
replacement on the other side, so if the user scrolls even more, the images
are waiting for them. Much like how G!Maps does it.

This offloads the graphics work onto the C++ rendering engine, which has been
tuned for this sort of stuff. Doing it in JS is just asking for trouble.

~~~
pyre
That might only work for the map though. I wouldn't want to have to download a
pre-rendered tile every time that I moved a unit. It would make more sense to
just pre-render the map tiles, and possibly the city tiles. Then the units
would still have to be downloaded to the client and drawn on top of the map.

The same goes for changes that occur to the map (at least changes within the
current view). Map tile improvements would be a pain if you had to download a
section of the map just to update a single tile. It would probably make sense
to have the sprites on-hand to update the currently viewed map section, and
have it automatically added to future pre-rendered tile updates. This way you
wouldn't have to download the map you already have to see the improvement, but
when you downloaded future sections (or even come back to the current section)
it will be part of the pre-rendered section.

All of this is disregarding whether or not there is a mode to show the map
without improvements on it (IIRC, there was an option like this in Civ2). Then
you might have to change these design decisions to accommodate that unless
you're ok with the user needed to re-download all map sections whenever that
options is flipped on/off.

~~~
nostrademons
Oh, by pre-rendering, I meant using DHTML, not images. Each tile is a div. On
the div, you draw a bunch of absolutely-positioned divs (sprites) with
transparent PNGs for backgrounds. The sprites themselves are layered, i.e.
you'd draw a bunch of divs with background images for terrain, then you'd draw
resources at a higher z-index, then you'd draw cities, then you'd draw units,
etc.

The reason for pre-rendering DHTML-based tiles is because a.) you have to
worry about download times for the sprite images, though hopefully you can pay
this once and have them cached forever and b.) it takes a fair bit of CPU to
create lots of DOM elements and move them to the correct positions. Less than
blitting an image to canvas, but more than just changing the top and left of a
container div.

------
nostrademons
I've put most of my comments as inline responses to other people, but here's
one more:

If AJAX is too slow, _do not_ think Comet will solve your problems. It's very
hard to get Comet to work reliably on all browsers across all types of
firewalls and proxy servers.

I did a prototype of something using the library that powers GTalk, Google
Docs, and now Wave. Even with the library all pre-built for me, it was pretty
hard to keep it from occasionally dropping connections and associated
messages, and once in a while it'd lock up my browser (much like GMail and
Docs do, occasionally. ;-)). I also peeked under the covers, and there's a lot
of subtlety in what's going on.

Comet is best for when you have stuff that _really_ needs to be real-time.
Things like stock quotes, or chat. IIRC, everything in Civilization is done in
response to user input. AJAX is fine for that.

------
cool-RR
What's the reason for not doing it in Flash?

~~~
roschdal
I might have to investigate Flash further now. Firstly, at the time I started
the project, there was no Flash plug-in available for my OS (64-bit Linux).
Secondly, I would have preferred using only open standards for this open
source project. Finally, and most imporantly, I didn't know Flash or
Actionscript.

~~~
a-priori
I recently looked into using Flex to develop a Flash interface, and found it
quite simple to get started... just beware of problems with asynchrony (that's
what tripped me up the most).

~~~
asciilifeform
> just beware of problems with asynchrony

Please elaborate. (I have also been experimenting with Flex.)

~~~
a-priori
Many operations in Flex occur asynchronously, such as when accessing remote
services. That is, they spark a remote query, and you must explicitly wait for
the response (such as by binding a function to the appropriate change event)
before you can continue a computation. Sometimes this occurs when you may not
expect it, in which case you'll see problems such as UI controls not being
updated, or exceptions from using nil values (because they are used before the
response comes back).

When you do expect it, you have three options: 1) you always wait for a
response before returning, making your function sychronous (thus maybe killing
performance), 2) you pass the responsibility to handle this behaviour to the
caller (thus creating an abstraction leak), 3) or you define a custom event
that you trigger when the response occurs (best behaviour, but needs extra
code).

Certainly not a huge issue once you get the hang of it, but something that can
definitely trip you up when you're just learning it.

~~~
cellis
It is very similar to ajax. The problem I have is when a game gets into the
2KLOC territory and above; when you have multiple files loading at different
times in the game engine in order to offer the player a better experience.
This leads to many, many handlers and a lot of chaining, and your pretty UML
will quickly become incredibly hard to see in the program flow.

For instance to save the user you can't just call User.Save and then go about
dependent routines, because there is a possibility that call fails or takes a
long time and then the player is out of sync. This is especially important if
you want to try to minimize cheating, as the longer the client goes without
syncing, the higher the probability for tampering, replays, etc.

~~~
asciilifeform
It seems that Flash doesn't even have a "yield" operator. And if you try to
busy-wait, the machine grinds to a halt, because Flash events do not preempt
code execution.

------
mryall
If redraw speed is a problem, perhaps in-browser vector graphics (SVG, VML)
would be a better solution than raster (Canvas).

There are probably a few libraries around for this sort of thing, but the one
I've had experience with is Raphael: <http://raphaeljs.com/>

It should mean less time redrawing the map because you can just reposition the
elements on the screen dynamically.

~~~
cellis
I'm going to go with no. Vector graphics are only feasible as long as the
shape bytes it would take to represent an image with nodes is less than using
pixels. Because many of the items in his games have gradients, and depth, I
think vector art would take a lot more space than simply using pngs. Of course
this is only dealing with latency; I'm not quite sure of the vector vs. raster
calculation tradeoffs but i can't imagine it being very much in vector's favor
with relatively few calculations per frame.

~~~
mryall
Fortunately, SVG and VML don't limit you to just vector graphics. You can
render, transform and scale raster graphics within the vector graphics space.
The graphic is just like a textured polygon that you can move around.

Consider how 3D engines work, where they compute all the visible surfaces
using vectors, and then transform and scale raster "textures" to apply on
these surfaces.

The XML issue isn't actually relevant either because normally the SVG/VML DOM
objects will be generated at runtime by JavaScript, rather than serialized in
the page and served up statically.

~~~
cellis
How do you describe the SVGs (i.e., the sprites) that get sent to the browser?

~~~
mryall
Here's an example of what I mean. It only works in Firefox, unfortunately, but
shows the concept of using raster sprites within SVG:

<http://www.mattryall.net/demo/civ-svg/>

SVG is by no means a solid game development platform, but it is some
interesting browser-based technology which might be useful for game developers
to investigate.

~~~
cellis
Pretty smooth demo :). I see what you mean now, but i was going on the
assumption that in a turn based game he wouldn't need to do much
transformation, hence, my suggestion to just use pngs and allow the browser to
redraw them.

------
mofey
You may want to look into how Quake Live is delivered over the web..

~~~
pistoriusp
Quake Live uses a plugin. It doesn't "run in the browser" like one might
expect something to "run in a browser."

~~~
mofey
That was part of my point. Instead of trying to do in something that was not
meant for it, consider an alternative way.

~~~
pistoriusp
This defeats the purpose of trying to create a web game.

------
Tichy
I don't understand why he is trying to use canvas, rather than positioning
images with HTML and CSS.

I haven't coded something like that myself, but I have been wondering if CSS
layers would work nicely for isometric graphics.

I am surprised how many people suggest Flash. Flash needs to die, so it is a
worthy goal to try to implement games in Javascript instead. Flash simply is
not available anywhere and causes a lot of suffering.

------
radu_floricica
Well, with this architecture it'd be a real surprise if it worked. It's a
brave attempt, but it was a long shot from the beginning.

I wonder how it would work as a java applet. Might require a jre download, but
it should be many orders of magnitude faster then javascript.

~~~
cellis
Well if we're going to bring out the big guns, the plugins, this would be a
different situation entirely. Besides, if a user can download a jre, why not
just download the whole game in C?

~~~
radu_floricica
I'm not sure you need a jre. If I were to guess I'd say no, but it's been
awhile since I played with applets on computers who didn't have it installed.

But web games are better for a host of other reasons:

\- compatibility between os-es

\- compatibility between versions of the same OS (win 95 vs xp) - much greater
lifetime

\- no hassle with installs, play instantly and from anywhere

\- easier to multiplay

\- switch from "savegames" to a "profile".

~~~
jodrellblank
_I'm not sure you need a jre._

Eh? How do you run a Java applet on a system without Java (Java Runtime
Environment)?

~~~
radu_floricica
You have a default jre installed in the browser for 10 years already. The
problem is it's not always the right version or flavor - Microsoft did a lot
of nasty stuff in this direction. But this was a long time ago, that's why I
said these days you probably don't need a separate download.

~~~
VinzO
As an up to date example, I tried a yahoo card game this week-end
(<http://games.yahoo.com/card-games>), and I couldn't launch the game in FF
without installing the latest JRE plugin. The game in question if you wanna
try is "pyramids".

------
TweedHeads
Try these options:

1\. Go with SVG and WebSockets.

or

2\. Go with pure HTML,Javascript and CSS with transformations.

I am working right now on a game based on SVG and couldn't be happier. Works
flawlessly on FX, WK & OP.

One last advice, drop support for IE and save headaches and wasted resources.

