Please note that this document is outdated. Most of the functions have already
been implemented, are done a bit differently or something like this.



Author	: Ulf Lorenz, Michael Bartl
Version	: 0.0.2
Date	: 2001-09-25

1. Why this document

Currently, Freelords is not designed as it should be in the final state, but
rather patched together bit by bit around a basic core (this is a bit hard, 
but I currently have this impression when planning to add code).
It doesn't include any analysis or design yet.

To become a full-grown game, we need to do some large changes (multiplayer
concept, campaigns etc.) which need a rewrite of large parts of the
code (in fact, smaller parts, but there are many dependencies...). So why not
rewrite large parts of the code and place it on a new foundation?

This document is just the starting point to order my thoughts, so I don't get
lost in TODO's. It describes, how Freelords _should_ work in my eyes. Targets
are: minimizing dependencies between objects (i.e. the single objects should not
interfere with each other when doing the same thing; separate different actions)
, increasing the extendability and separating "logical units" from each other.
Although many things remain or won't be implemented very soon, there are some
severe design differences between Freelords now and the outline here.
For the very beginning, we should only implement the game type
"load random-map/scenario=>play it=>exit", but this design is hopefully good
enough to allow easy extensions (e.g. load/save).

There will be a UML diagramm based on this document, and an interface definition
based on this UML diagram soon, which will then be the foundation of the code
changes.


2. Starting up the game

When starting up the game, the program first queries the resolutions (to check
if it should run at all) and other dependencies (memory etc., can be added 
later). Resolutions should be at least 800x600 (to have a normally-sized bigmap)
with optional increases as well as choice for fullscreen mode.

Then it initializes a PG_Application instance and fires up the 
SplashScreen. This screen offers you the following possibilities:

	New Campaign
	New Scenario
	New Multiplayer
	Load Game
	Quit

2.1. New Campaign

When the player clicks on the first button, a dialogue queries the campaign.
Then, a Campaign object is created and reads it's corresponding source file
(preferably XML). A Campaign description gives information about the single
scenarios and the links (=story, dependencies) between the scenarios. A
Campaign object is completely independent. Once it is created and launched,
it takes over the control of the game (SplashScreen hides in the meantime)
and later passes it to the links or the GameScenario.

2.2. New Scenario

The Player is asked if he wishes to play a scenario or on a random map.

2.2.1 New Scenario
The Player is presented a list of available scenarios and selects one. A 
GameScenario object is created, sources the corresponding file and completely(!)
takes over the control.

2.2.2. Random Map
The SplashScreen fires up one or more dialogues asking for parametres (players
etc.) It then creates a factory object (!!) and feeds it with the data. The 
factory object then creates a random Scenario from the data and passes it back
in a standardized way (i.e. it looks like a regular scenario (XML)). This could
be done by storing the scenario temporarily in a file on the disk (since it is
read and deleted some milliseconds later, it shouldn't actually be written on
the disk, but be cached). Then, the SplashScreen creates a GameScenario, too,
and has it source the scenario data. It then passes control to the GameScenario.


2.3. Load Game

A saved game consists of two parts: The campaign and the scenario part. The 
campaign part (if there is none, it is a standalone game) has previously been
written by the campaign object and informs about the progress within the 
campaign. The scenario part is divided in the part for the GameScenario object,
which contains a normal scenario description and can thus be sourced like a 
normal scenario, and the save part with details about how many turns have
passed, possibly statistics etc.
The SplashScreen now looks if there is a campaign part. If so, it creates a 
campaign object, tells him it has been loaded and passes him the file. The 
campaign object then takes care of starting up the game scenario.
If there is no campaign part (or it is empty or so) it creates a GameScenario
and tells him it has been loaded. the GameScenario loads and takes over control.


2.4. Multiplayer Game

A Multiplayer Game has to be a bit different. With normal scenarios we can 
already allow "Hot Seat" (several players sharing one computer) without
limitatons, but if you want to play by network, the situation is a bit 
different. I suppose the following solution:

We take a client-server-approach with the freelords instances being the clients.
It is the simplest one and there are already good lib projects who would love to
have another game on board :). When clicking on multiplayer, the player is asked
for a server location. It connects, and as soon as it gets a "Hello" it creates
a GameScenario, tells him it is a multiplayer game and hands over control as
always. The GameScenario now gets its data file from the server and sources it.
The only difference to normal scenarios then is the fact, that all other players
except the human one are remote players (the AI players, too; they are 
calculated on the server (imagine, you have a stripped down version of freelords
on the server, which runs the AI players; the design should be so that this is
possible, as this version simply doesn't start with a SplashScreen, but with a
sourcing GameScenario (just an idea)))

3. The Game

The central core of the game control is GameScenario. It sources the scenario
file, sets up the various lists and initializes the graphical interface, and 
always is given back the control for special actions (next turn, save etc.) 


3.1. "Common" Classes

The classes here are roughly ordered from smallest changes to largest changes.

3.1.1. Temple
This design stays mainly the same, but temples will be largely improved, so 
heroes can get quests and are rewarded upon completion.	 For more information
on quest see section 5.1 Quest.

3.1.2. Ruin
This also stays the same. The search function could later be extended (explore
the ruin with your hero), but that should 
a) be quite easy
b) not be a problem of the Ruin class (see the player section further down)

3.1.3. Citylist
Not much functionality, so we don't change it.

3.1.4. Army, Armyset, Armyset_army, Armysetlist
The current implementation is 100% corresponding to the UML
Diagram, so we declare this part to be done.

3.1.5 Path
Done.

3.1.6. Stack, Stacklist
This also has almost its final shape with one exception: The whole actions
part (attack/move etc.) is moved to the player class, i.e. Stacklist is now only
another list with some added functionality.

3.1.7. Mapdef
The function of Mapdef is changed completely. See under the section graphic 
objects for more details. For now, mapdef loses almost all its current 
functionality apart from name, info, and the map.

3.1.8. Mapset_tile/Mapset_tile_list	(the name should be changed :))
mapset_tile stays the same, but Mapset_tile_list is new. It is modelled like the
armysetlist, i.e. it cares for loading/deleting the mapsets (that's where one 
half of Mapdef's lost functionality goes to).

3.1.9. GameScenario
GameScenario is another class to be radically cut. It doesn't provide direct
access to the scenario details (game_type, map_type etc.) any longer, but only 
accepts XML files as input: either scenarios (formerly created) or saved games.
Furthermore it saves games and cares for all the things the "super user" has to
do on special occasions (e.g. heal stacks of player at beginning of new turn,
i.e. on next_turn, trigger some event if this should be implemented later).

3.1.10 AI
We also add a new AI class. The AI implementation is generic. We take a virtual
base class AI_base which contains the important stuff for all AIs (who is the
player they control; think of something more when necessary) and one important
method named, let's say, do_turn. This is later called when it's the AI's turn
and has the AI make its move. The second class we need for the beginning is a
dummy AI which simply does nothing. This is the AI for the neutral player 
(later when we have further AIs we can change that, but for now it enables us
to handle the neutral player just as a normal (computer) player, so we don't
need those silly workarounds (e.g. "load player's armysets _and_ the default
armyset, since the neutral player needs it")).

3.1.11 Player/Playerlist
Among the classes which change most is the player class. Up to now, it only 
holds the player's information. Now, it becomes the center for the player's 
interaction with the game. For each possible player action (this refers to
direct actions like "search the temple" as well as implicit actions like "move
stack one step"), the player class provides the interface, i.e. a function which
cares for the execution of the action. This has two reasons: First, you bundle
this "logical unit" (the player's actions) in one class. The second point 
describes the other major change: The player class stores each action in a list.
This list needs to have a protocol which itself needs to be defined later on. 
The player class has two methods to hand out this action list and source an 
action list (i.e. execute its actions). The first method is queried by the 
GameScenario in a multiplayer game when it sends this action list to the game
server, or in single player game when the player wants to see the moves of the
other players in a turn summary. The second method is solely used in multiplayer
to keep the local copy of the game data up to date.

3.1.12 Fight
This class is used for the calculations done when a fight occurs. FightDialog
calls the next_fight function until a round has ended, then starts a new
round with new_round and again calls next_fight. This is done until the
fight has finished by Won, Lost or Draw. The return value of next_fight is the
result of the fight.

3.2. Graphical Classes

These classes are also roughly ordered from smallest to largest changes.

3.2.1. Smallmap
Smallmap stays the same apart from some performance or color changes.

3.2.2. Bigmap
Bigmap also stays mainly the same, only the drawing function is changed, so it
simply blits the appropriate section of the map to its surface instead of 
calculating it (see mapdef below).

3.2.3. W_Main/W_Edit
These also don't change much, W_Edit only passes all its next_turn stuff etc. to
other classes and solely cares for graphic interactions (e.g. select/deselect a
unit), all other actions (e.g. defend) are passed to the player class.

3.2.4. Army-/Stackinfo
Nothing to be changed here.

3.2.5 *Reports, Cityinfo, 
Instances of these classes are only created in a close context, so there is not
much to change here: Give away player actions (esp. the cityinfo class).

3.2.6. City, Maptile
no changes intended

3.2.7. Mapdef
To have something to change at the graphical section, we rewrite the mapdef 
interface. Currently, we have one problem, you'll easily recognize. Move the
mouse on the Smallmap, press the button and move it around, and you'll see what
I mean. You can get 100% processing with almost every CPU. the bad guy here is
bigmap. It recalculates it's appearance with every MSG_SMALLMAP_MOVED_VIEWRECT,
i.e. searches every list, draws each piece etc. The new Mapdef class wants to 
solve the problem. It internally has a SDL_Surface of the _complete_ map.
Furthermore, it features graphical functions for every important action apart
from selecting/deselecting (this can stay as a property of bigmap), i.e. if
you move an army from position (x1,y1) to (x2,y2), mapdef recalculates the tiles
at both positions and emits a message. If bigmap now wants to update or redraw
its content, it doesn't need to calculate it, but simply blits the appropriate 
rectangle to its surface.
Anothe change is that the map size should become dynamic, which is not such a 
big deal.

3.2.8 D_Fight
This class has to be seperated into a calculating class and a graphical
representation of the results. D_Fight stands for Dialog_Fight (to be better
seperated from the Fight class)

4. further changes

Some other changes which don't fit in the 3rd section are "file access", 
"options", "xml parsing"

4.1. file access
We create a new namespace "file", which contains functions for accessing all
possible files. This bundles the file functions in one place, allowing us to 
change the file access in a centralistic manner. As a first implementation, we 
can stay with the current one, but later it should be extended, so that
a) we can add a "make install" target in the Makefile
b) we can port to Windows (which has a completely different writing; "\" instead
of "/" (is this one right?), stupid drive identifiers at the beginning of the
path, paths possibly unknown at compile time)

The namespace also contains an init function which can be empty on Unix systems
but needs to load the source directory from the registry on Windows. Init is 
called on startup.

4.2. options
Another namespace is options. It contains an init function and several 
variables. Although we don't need it now, it can become necessary to add some
convenience options later.

4.2. xml
I propose to change the underlying xml library. In order to reduce the 
dependencies of our game, we should migrate to Expat, as Paragui will depend on
this xml parser in the final version.

5. Definitions

Each of the following subsections describes a certain part of FreeLords.
This shall help the developers to have the same idea of what they should
implement.

5.1 Quests

A quest is an important part of a heroes life. Only heroes can go on quests.
They are obtained from temples and on successful execution of the quest the
hero will be rewarded by the quest spell. 

A hero goes into a temple and asks the priest for a quest. The priests
have always some tasks that need to be accomplished ranging from killing another
hero, search a specific ruin, burn a specific city and killing a complete race
(player party). The hero is assigned a specific task. This is done
by casting a quest spell on the hero and on fullfilling of this task
by this hero (important) the spell activates itself and randomly rewards the hero.

There shall be a specific icon displayed on the hero stack when the hero has a quest!
One player can have as many quest as he has heroes (one for each)!

Implementation: (this shall after the review be incorporated into the class Quest in Section 3)

The class Stack will have an additional Data Quest* quest! On each of the possible
actions that are needed to fullfill a quest we call quest->is_finished()!
No quest information is stored in locations, this is only Stack and Quest relevant.

