Copyright 2012, 2013 Simon Ley alias "skarute"
This documentation is published under the GNU Free Documentation
License v1.3 or later. You can find a copy of this license in
"fdl-1.3.txt" or at <http://www.gnu.org/licenses/>.

########################################
Faunis Developers' Documentation
########################################

This documentation is still incomplete. I'm working on it. :o(

1.   Concurrency
To avoid problems with concurrency when data is accessed by multiple threads, a lot of synchronisation is needed. Sometimes, due to abstraction reasons, we even have to synchronise on an arbitrary list of objects. Therefore, I created the helper class Sync which is able to do that. To avoid deadlocks, all fields commonly accessed in a class must be synchronised on from top to bottom as their definitions appear in the class. After them, all variables not part of the class are reserved. Given such a synchronisation order, the Sync tool can even merge two lists of objects to synchronise on in that order.

2.   Code structure
In general, the classes are structured in three main packages: "clientSide" contains everything only needed by the client, "serverSide" everything only needed by the server, and "common" contains everything which is needed by both or which is exchanged during client-server communication. All exchanged communication messages are called orders and carry a prefix of two letters to better distinguish between them. The first letter indicates where the order is from (there are some few exceptions where this isn't true, though), while the second letter indicates who the recipient is. C stands for Client, B for Butler, M for MapManager.
Playable characters are represented by the Player class on the server side and by the PlayerGraphics class on the client side. Certain player data relevant for both sides is in GraphicalPlayerStatus which primarily stores information about how the character is displayed. Note that the PlayerGraphics instance can completely be produced from the GraphicalPlayerStatus object.

2.1   Client side
There is the Client class which represents the main client functionality and has the main method. The user interface is represented by the class GraphWin (basic gaming interface), GameWindow (specialised for Faunis functionality) and MenuManager (manages the menu and its functionality).

2.1.1   Animation
The more complicated part on the client side is the animation stuff: A character frame can be drawn as a whole (compact AniCompoType) or consist of separate limb images (limbed AniCompoType). The compact style is easier to create (since even if you decide to isolate the frame into single limbs, you will have to draw it as a whole anyway just to see if the limbs are proportional), but the limbed style has the advantage that later the character can keep its facial expression during animations, amongst others. The joints of the limbs are marked by specially coloured pixels.
All frames that form one animation cycle are stored in one Bone instance, which therefore is determined by character class, animation / animation state, body part and direction.
An animation can have different termination behaviour: It can simply return to the default standing animation (revert AniEndType), it can be repeated endlessly (repeat AniEndType), or it can stay in the last frame (end AniEndType).
Except for standing and walking, every animation can be triggered as an animation for now. Note that a walk command will remove any animation in progress.

The GraphicsContentManager is responsible for storing these Bones and will provide them if requested. The bones as well as the additional information like AniCompoType and AniEndType for the graphics of each character class are stored in GraphicsClassData objects. The reason why GraphicsContentManager is also used on the server side is because the server has to verify if an animation really exists, and must know its AniEndType to handle it correctly. The methods for loading the image files are actually not called on the server side.

2.1.2 Scaling
All images can be scaled, such that the raw images for a character can be drawn in a much higher resolution than how they later appear on the map. The bones cache variably scaled instances of the images. The default scale value for the map of the graphics for a character class is stored as additional information in a GraphicsClassData object.

2.1.3   Decorations
Another type of graphics managed by the GraphicsContentManager are decorations. Decorations are immobile images on the map, like a tree, a house etc. As for now, decorations are not animated. Their images are too stored in Bones. Additional information for a decoration (so far it's only the scale value) is stored in a DecorationData object.

2.1.3   Animators and Movers (= ModTimers)
Whenever a player is moving, a Mover is instantiated on both client and server side (stored in a Client resp. MapManager module). His task is to regularly adjust the player's position, thus he has an own Timer that frequently executes a TimerTask, in our case an instance of RoughMovingTask on the server side or SoftMovingTask on the client side. Reason for this differentiation is that on the server side it's enough to simply change the coordinates by one step during every task execution, but on the client side that would look too rough and we want a smooth transition between fields. That's why the SoftMovingTask also adjusts a special attribute, the so-called deltaLevel (I couldn't come up with a better name, I'm sorry). It indicates the relative position shift with relation to the recorded coordinates. The deltaLevel is only one value, though for a two-dimensional shift we'd need two, however we still have the player's direction, so it is sufficient.
Like with movement, there's a similar approach with animation: The Animator class similarly has its own timer and timerTask to increment a player's frame counter and to handle animation termination. All Animators are kept by a Client module. Since there is no need to have frame counters on the server side, there are no Animators there.

2.2   Server side
The server side main class is MainServer, where at last all data references are hold. There is a Reception class which steadily looks out for new connecting clients and redirects them to a newly created Butler.
The Butler class represents a client on the server side. Besides the reception, he is the only one directly communicating with him, checking and implementing his orders as well as returning the orders meant for him. When the client disconnects, the butler is destroyed.
For each map of the game, there exists a MapManager who manages the list of players / butlers that are currently on this map. Every player / butler who holds an active player must be registered at a mapman. Whenever something happens on the map that others should perceive, the mapman sends orders to all butlers to notify them about the change.

2.3   Common stuff
2.3.1   Archivists
Archivists represent the interface to the hard disk. (Almost) all hard disk read and write access passes through an archivist. The concrete implementation is on filesystem basis, meaning that I just use files and directories to store data. Thus, concrete archivist classes mostly start with "FS", meaning filesystem. Later implementations could be using databases for efficiency?

2.3.2   Modules
Modules were introduced to take over certain jobs from their owning classes like working off a queue of messages or managing ModTimers. Client, MapManager and Archivist are partitioned into modules.

3.   Threads
Client:
- main thread: frequently redraws the screen
- one to respond to server orders

MainServer:
- main thread: Only used for initialisation and to make the window visible

Butler:
- one to handle orders from the client side
- one to handle orders from the server side (mapman etc.)

MapManager:
- one to handle the butlers' orders

Reception:
- one to receive incoming clients

Furthermore every Animator and Mover has its own thread, and Swing has even a group of threads.

4.   What isn't implemented so far
- everything that turns a MMOG into a MMORPG: Fighting and attributes
- inventory and items
- security and encryption (minimum requirements for a stable version!), data backup
- better administration
- and much, much more...

