I've heard of an effort or two to rewrite Empire from scratch, but no
one has succeeded so far. Good luck.
Last time I remember we talked about it is archived here:
http://groups.google.de/group/rec.games.empire/browse_thread/thread/72...af961ff
Unfortunately, I forgot to remove my x-no-archive in the little
treatise on our current code's structural problems I posted then. So
I just copy it here. Enjoy! And excuse the stupid typos.
Markus
This is not an exhaustive treatise, just a few selected points.
Moreover, it's about the server, not about the game's design, which is
an entirely different can of worms. And the final caveat: it is
purely hypothetical. I feel not the slightest urge to rewrite the
server. It's too big a mouthful for me to chew in my spare time.
Before anybody gets funny ideas on what I think about the hackers who
created the server as we know it: I consider it a pretty good design
for its time (especially after Dave Pare got concurrency right in
Empire 2). It aged gracefully enough to be still in use after more
than twenty years. Quite an achievement.
Naturally, the code has its share of structural problems due to its
age. Design tradeoffs that made plenty of sense then can make less
sense now.
I don't know what kind of machine the ancients used to create the
server, but I wouldn't be surprised if they had something like a
top-of-the line VAX, 32 Meg of main memory, crunching about 6 MIPS.
Wheee! I also wouldn't be surprised if some of you now own cell
phones more powerful than that.
Now, most of the time I hear someone claim that machines got so much
faster that we can do things differently, it's just a specious excuse
for going through half a dozen levels of frameworks, class libraries,
generators and whatnot to achieve the simplest things. Maybe there
are hard problems where you need all that[*], but Empire ain't.
Empire's a *simple* problem. It must be so, or else folks couldn't
have cracked it twenty years ago on something less powerful than your
cell phone.
With that out of the way, let me present two design issues where all
that extra power we have today would lead me to different tradeoffs:
storage, and separation of domain logic and presentation.
Application are commonly split into three layers: presentation (user
interface), domain logic, and storage.
The server does a reasonable job of encapsulating storage. But
presentation and domain logic are hopelessly entangled.
That's bad because it effectively limits us to the one presentation
built into the server: a text command line UI. We can't easily move
presentation into a smart client. Instead, our smart clients kind of
undo the server's presentation: they laboriously decipher the text
output, update their own model, and then provide their own
presentation on top of that.
How come the server was written that way? Were the server coders
dumb? Not at all. When you write a program at the very limit of what
you can code and your machine can run, you keep it as simple as you
possibly can. Entangling presentation with the domain logic is as
simple as printing what happens when it happens, in plain English.
You can hardly make it simpler than that.
Putting the presentation in the server that way also allows for a
really simple client. When your players log into your beefy VAX to
run clients, and said VAX already groans under the load of the server,
a really simple client is a big, big plus. Same if you get to port it
to yet another semi-compatible variant of Unix.
I don't know whether anybody back then even thought about it. I doubt
it. You don't solve problems by thinking about issues your kids might
have with your solution twenty years down the road. You go for the
simplest solution that could possibly work.
Now let's take a closer look at storage. Empire game state is simple
enough: a bunch of records describing game objects. State change is
less simple: it generally involves updating several game objects and
sending messages to clients. Say your fortress fires at a hostile
ship. The fortress gets charged a shell (update fortress object), the
ship gets damaged (update ship object), you get a satisfying message,
and your enemy gets a less satisfying one. All of this should happen
or none of it.
This cries for transactions. Which have nothing like that. We store
everything in flat files. To stave off chaos, we group related
updates and messages together and limit concurrency so that each group
always runs alone, not in parallel to any other group. Should we
crash halfway through a group, we likely leave corrupt game state
behind.
How come the server was written that way? Were the server coders
dumb? Not at all. This is again the simplest solution that could
possibly work. Mind, if you wanted a database back then, you got to
write it yourself.
To avoid misunderstandings: the last thing Empire needs is being tied
to some bloated database software that takes an army of consultants to
set up, and then some to keep it from self-destructing. That's for
enterprises. Use something lightweight.
Such big structural problems can be intimidating. Don't let them!
They may be big, but they're not the only ones worth attacking. There
are plenty of quite tractable problems around. Inquire within
[*] I don't know. For some reason, my problems always become too
simple for all that once I invest a bit of energy to think about them.
Maybe that stuff's just needed to keep the architecture astronauts
aloft.