Gamer2k4 / basinrogue

Automatically exported from code.google.com/p/basinrogue
0 stars 0 forks source link

Stopping and starting again #18

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Save/load code can take quite a bit of work to design and maintain, and I'm
thinking about some ways to reduce this.

There are two cases where we might need to save/load:

1. the server is shut down (or crashes) and we need to restart it
2. a single player quits (or their connection is lost) and they login again
later.

For case 1., we certainly need to have savegames at the server end, storing
all character information. For case 2., I am not sure. Is it a good idea to
create a savefile on disk for the individual player? Or is it better to
just keep their details in memory on the server, and when they log on
again, they can be dumped back into the dungeon?

The thing is, if we only need to save to disk for 1. above, then perhaps we
don't need to save the state of the dungeon each @ is in. We only need to
save the character information, and then the @ just reappears in town. This
would cut down on the save/load code a lot!

A. 

Original issue reported on code.google.com by antoine....@gmail.com on 19 Feb 2007 at 8:24

GoogleCodeExporter commented 9 years ago
I think the problem is much more fundamental than how to handle save/load. For
example, the basic client/server interaction needs to be discussed first.

Here are some existing models and my thoughts on them:

The usual MMORPG model (take WoW for example): All world content is stored in 
the
local machine (client). This means that the content is readily accessible and 
all the
server has to do is provide any parameters that are necessary to position or 
animate
these resources in realtime, when applicable (this is all in addition to all of 
the
usual server responsibilities, of course). This obviously results in a very 
heavy
client and makes dynamic changes to the world a little trickier to convey to the
client (something like landscape deformation or random dungeon generation). I 
don't
think this is a particularly good approach for BasinRogue since it's much too
cumbersome for the little benefit it would provide in an ASCII-based client.

That previous paragraph really isn't of much use with BasinRogue but I 
mentioned it
to set a point of reference.

A dynamic MMORL model: I have not seen this in action but I designed this for a
similar project I was working on. On the client's side is a very thin 
implementation
of ascii/sdl tiles, input, and sockets. There is no area or resource information
stored clientside (except for the tiles when applicable). The server sends the 
client
all area information in realtime as the areas are loaded. In order for this to 
work,
a cell-based model much like the one in Morrowind is employed (this is assuming 
a
seamless world design, at least on x,y):

Each "cell" or map area must be minimum half of the screen width wide and half 
of the
screen height tall (no requirements for maximums). Each player occupies one 
cell at
any one time, and that cell is "active" on the server, which means that the 
server
computes AI and other necessary cell contents. In addition, the Moore 
neighborhood of
that cell is also active (which is a fancy way of saying all 8 cells around it).

Each server tick, if the player moves within his cell, everything is calculated 
as
expected. The moment a player moves out of his cell into an adjoining cell the 
cells
"left behind" are "unloaded", and the new surrounding cells are "loaded". The
loading/unloading process works like this (I guess this is the main point of 
this issue):

A character, his active cells, and all of the relevant cell content is loaded on
memory. When a cell is loaded it is pulled from the database (more reliable than
regular disk access since it's multithreading safe), and when a cell is 
unloaded it
is stored back into the database and out of memory. Cell loading and unloading 
can be
done with a daemon thread that does not block user input. Since cells are 
loaded and
unloaded "out of the screen" any spottiness of the loading process won't be 
noticed.
It's also useful to do this with a daemon thread that sends information to the 
client
as it gets it, and only removes stuff from memory when needed for the following
reason: If a character moves in and out of the same two cells fast enough it 
will
force a minimum of 3 loads and 3 reloads on every move, with a worst case 
scenario
moving diagonally across cells for 5 loads and 5 unloads. If these 
loads/unloads are
done "whenever the server has time", it will ensure that the memory cached data 
is
still available for immediate communication to client.

Remember that these cells are loaded into memory in a "global" sense, that is 
to say
that they are available for access from all clients, so no client particularly 
"owns"
a cell or its neighborhood, but they are just pulled up from the database for
everyone to access. Any change to a cell is done in memory first, and dumped to 
the
database as necessary. The obvious consequence is that if a player moves into 
another
player's cell neighborhood (sort of "overlapping" if you will), the cell is not
loaded from the database since it's already in memory. Conversely, cells cannot 
be
unloaded if there is another player in them.

I think this addresses your concerns, Antoine: In the case of a server crash, 
the
only data lost is data that the daemon has not yet submitted (a few 
seconds/minutes
tops). In case of a player disconnect, his data needs to be submitted to the
database, and his cell neighborhood can be reclaimed by the daemon (unloaded).

Cheers!

--Ebyan "Nolithius" Alvarez-Buylla

Original comment by Nolith...@gmail.com on 27 Feb 2007 at 6:20