Skip to content

Commit

Permalink
improved some moves, reduced usage of CompositeMove, added documentat…
Browse files Browse the repository at this point in the history
…ion development details
  • Loading branch information
Trilarion committed Aug 23, 2018
1 parent 20fa10b commit e37b2f4
Show file tree
Hide file tree
Showing 54 changed files with 574 additions and 873 deletions.
5 changes: 3 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
Changelog
************************

The change logs for the years 2000 to 2006 are more like commit messages and are kept here for historical reasons.
From 2017 on this change log describes the publication date and changes of every released version.
.. note::
The change logs for the years 2000 to 2006 are more like commit messages and are kept here for historical reasons.
From 2017 on this change log describes the publication date and changes of every released version.

FreeRails continuation (2017-)
------------------------------
Expand Down
161 changes: 106 additions & 55 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,128 @@ Development
Brief overview of the architecture
----------------------------------

Outdated!

The model and the view are separated. The classes that make up the model, referred to as the game world, are in
the freerails.world.* packages. The view classes are in the freerails.client.* packages.
the freerails.model.* packages. The view classes are in the freerails.view.* packages.
The state of game world is stored by an instance of a class implementing the interface World.
This class is mutable - one can think of it as a specialised hashmap. All the objects that represent entities in the
world - values in the hashmap - are immutable. It follows that changes to the game world involve adding, removing or
replacing objects representing entities rather than changing their properties.

The client and server are separate. They communicate by sending objects to each other. This is done either by placing
objects on a queue or by sending serialized objects over a network connection. All objects passed between the client
and server are immutable and are instances of one of the following:

- Message2Server
- Message2Client
- MessageStatus
- PreMove
- PreMoveStatus
- Move
- MoveStatus

When a new game starts or a game is loaded, the server sends the client a copy of the World object (using an instance
of SetWorldMessage2Client) All changes to the game world that occur after the game has started, referred to as moves,
are done using the classes in the package freerails.move. Moves are either obtained from a PreMove object or constructed directly.
This class is mutable - one can think of it as a specialised hashmap. Changes to the game world involve adding, removing or
changing their properties.

Coding Guidelines
-----------------
The client and server are separate. They communicate by sending objects to each other. This is done by sending serialized
objects over a network connection.

General suggestions
+++++++++++++++++++
When a new game starts or a game is loaded, the server sends the client a copy of the World object. All changes to
the game world that occur after the game has started, referred to as moves, are done using the classes in the package
freerails.move.*.

- Package dependencies.
- Avoid circular dependencies between packages. I.e. if any classes in package A import classes from package B, then
classes in package B should not import classes from package A.
- (ii) Follow the package dependency rules.
- Some of the GUI classes have been created using the NetBeans GUI editor. The .java files for these classes have corresponding .form files.
Within the java files are protected sections of code, if you edit these files, please do not alter these sections by hand.
- Generally follow the sun java coding converions(http://java.sun.com/docs/codeconv/).
- Run all unit tests after making changes to see whether anything has broken. You can do this using the test Ant target.
- Check the javadoc Ant target runs without errors or warnings.
- Javadoc comments. Add a couple of sentences saying what the class does and the reason for its addition with a date. Also use the @author tag if you add a new class or make a significant change to an existing one.
- Use Code Formatters with care. Avoid reformatting whole files with different formatting schemes when you have only changed a few lines.
- Consider writing junit tests.
- Consider using assertions.
- Add //FIXME ..and //TODO comments if you spot possible problems in existing code.
- Use logging instead of System.out or System.err for debug messages. Each class should have its own logger, e.g.
private static final Logger logger = Logger.getLogger(SomeClass.class.getName());
Server - client communication
-----------------------------

The server is the entirety of computational processes that are concerned with evaluating the game mechanics and
distributing the game updates, which can be physically separated from the players.

The server knows logged in users and communicates with them via connections which can read and write serialized
Java objects over the internet. However, connections can get lost and reestablished, so the server needs to have
the ability to re-associate a connection to a player and the player needs the ability to re-identify itself
within a new connection.

Solution: Identity is an uuid, given by the server to the client, together with a display name, that the client chooses.
Identification is by uuid. If there is a player on the server side without connection and a new connection presents the
UUID of this player, instead of creating a new player, the connection is re-associated.

Before that connections have to send their game version id and the version id has to be equal to the version id of the
server or the connection will be closed immediately.

Furthermore: Connections not presenting a UUID within certain a timeout or presenting something else are automatically closed.

For this we need handler, that actually process messages and allow to act on the various things as well as do something
in the future. (see also Java Executors https://stackoverflow.com/a/2258082/1536976)

Proposed structure of identify: Identity (UUID id, String name)

Identified players can send commands/message to the server and may receive responses.

Examples are: chat message (are echoed to all) , chat log request (returns with the last X chat messages), display
available inbuilt scenarios, display saved games ready for loading on the server, create random scenario with options,
start hosting a game (preparation phase), start game, stop game.

- ChatMessage: String content, String author, String date (certain format)
- SimpleMessage (Request): Enum type of request (chat log request, display available scenarios, )
- ChatLog: List<ChatMessage>
- Scenario/SaveGameInformation: String title, String description, Image preview
- RandomScenarioCreationOptions:
- ...

Submitting Patches
++++++++++++++++++
The server is represented with a list of <id, message> and processes them. The first player on the server to decide to
host a game becomes the game master. He decides when to start the game, when to stop it running on the server.
However, the players can safe the game locally as well (see later)

- Small patches that fix one thing, add one feature, or clean up one aspect of the code are generally the easiest to manage.
- Check list:
Stopping the server is done externally by the local client, not through messages. The local server starts at start of
the local client and stops when the local client stops.

(A) Is there patch against the lastest code in CVS? I.e. if you do a fresh CVS checkout of the freerails module, does the patch apply correctly.
When a server stops, the current running game is stopped, all connections are closed.

(B) If you have create new files, are they included in the patch? Look at the -N option.
A game consists of a certain number of players and additional data, all contained in a model object. In a game the
players are either humans or AI. Access to a player may be restricted by password. Users can decide to use
heir uuid as password.

(C) Are binary files excluded from the diff file? Any new or modified binary files, \*.png, \*.wav etc, should be included separately.
If no passwords are stored, the scenario is said to be "pure", otherwise it is said to be "restricted".
Pure scenarios can always become restricted. Restricted scenarios can only become pure if all participating human
players agree. Passwords are part of the game model.

(D) Do the following Ant targets work without warnings or errors when the patch is applied against a fresh CVS checkout?
Client options:

(E) Does the patch have a meaningful filename? E.g. bug910902_patch1.diff.
- Internal (program version acting as option version)
- Server limited to local connections (default: on, changes are reflected on next start)
- UUID (chosen at first start, may be set)
- Default password (chosen randomly at first start, may be set)
- Use default password (otherwise the player is prompted before sending)
- Start in windowed/fullscreen mode (changes are reflected on next start)
- Music mute (immediate, default: off)
- Music volume (immediate)

- Submit patches using the patch or bug tracker on the freerails sourceforge page.
Implementation (stored as JSON as key-value pairs, or as properties maybe?)

During the game, only Chat Messages (not part of the game, chat messages not persistent when server stops) and stop
game messages (by game master).

The game has a status (running, paused). It pauses if the majority of players hit the pause button (message) or if a
player lost a connection. The game master determines the game speed (stored in the game model).

Everyone can send a Move, Moves are collected in a list in the order of arrival at the server. Every move is processed
sequentially and first tested for applicability. If so, it gets a running number (applied moves since start of game)
and is applied and sent to the client. The client then checks if the current running number is the successor of the
last received such move and applies it. If not, a Message (Invalid Move or so) is returned.

A Move should always encapsulates a single atomic game action for each player.

Move: void apply(World), Status applicable(Read-Only-World)

In case of inconsistencies every player can always send a request to obtain the whole world).

Computer controlled (AI) players
--------------------------------

Is built exactly like a client (communicates by Moves) but without UI or presenter. Lives locally on the server.
Shutdown automatically if the game ends.

Coding Guidelines
-----------------

- Follow package dependency rules (utils does only depend on java libraries, model only on utils, move only on model and utils, ..).
- Avoid circular dependencies between packages. I.e. if any classes in package A import classes from package B, then
classes in package B should not import classes from package A.
- Run all unit tests after making changes to see whether anything has broken. You can do this using the check gradle target.
- Javadoc comments. Add a couple of sentences saying what the class does and the reason for its addition.
- Use the Code Formatter with care. Avoid reformatting whole files with different formatting schemes when you have only changed a few lines.
- Consider writing junit tests.
- Consider using assertions.
- Add //TODO comments if you spot possible problems in existing code.
- Use logging instead of System.out or System.err for debug messages. Each class should have its own logger, e.g.
private static final Logger logger = Logger.getLogger(SomeClass.class.getName());

Recommended reading
+++++++++++++++++++
Reading

- Effective Java (http://java.sun.com/docs/books/effective/) (sample chapters online)
- Java Platform Performance (http://java.sun.com/docs/books/performance/) (available online)
- User Interface Design for Programmers (http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html) (available online)


Expand Down
152 changes: 37 additions & 115 deletions docs/specification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
Specification
*************

*Originally written by Luke Lindsay.*
.. toctree::
:maxdepth: 2

.. note::
This spec is incomplete and what is here will be revised several times before it is finalized.
This spec may not discuss in detail how features will be implemented.
specification_rt1
specification_rt2

This specification describes the various elements of the game and their interactions.
It may not discuss in detail how features will be implemented.

*Scenarios*
Introduction
------------

In designing software, it helps to imagine a few real life stories of how actual (stereotypical) people would use it.
We'll look at three scenarios.
Let's imagine a few real life stories of how actual (stereotypical) people would use it.

Scenario 1: Jeff.
Aged 38, splits his time between contract web development work and (real) surfing (i.e. He's an aging hippy).
Expand All @@ -30,21 +33,33 @@ Wants something to play on her computer to distract her from her research.

Realism - it's a game not a simulation.

*Not yet included*

- Customisablity
- Difficulty levels
- Advanced graphics (including animations other than movement).
- Performance
- Cheat proof: don't play it with your house-mate who keeps stealing your milk
- Prority Shipments
- Scripting events and AI using Jython
- Internet high score table
- Custom Look-and-Feel
- Undo building track
- Rate wars
- Save game compatibility between releases.
- Signals

User interface
--------------

All dialogs and screens should have a help button showing localized help. The help is just a locally stored html page.

Start screen
++++++++++++

Must enable the following actions

- change preferences (modal dialog)
- start the scenario editor (full screen)
- exit the game
- show help information (modal dialog)
- start playing a game (modal dialog)

Start playing dialog
++++++++++++++++++++

Must enable the following actions

- start a new local game
- continue a stored local game
- connect to an external server and participate in a network game hosted on that server
- host network game (and participate in it)
- close the dialog

Game Model
----------
Expand Down Expand Up @@ -805,96 +820,3 @@ profitable connection from S for moves after the first one. However, unless the
small this would likely take a long time to solve. What is more, we have not even considered what other players
may be doing, so even if we could formally solve the problem above, we would still have a lot of work to do.

Sid Meier's Railroad Tycoon (1990)
----------------------------------

This is a summary of the game model of the original Railroad Tycoon (RRT).

Start condition

- $1 million (half in equity, half as loan)

- Lay track
- Build stations
- Buy trains
- Schedule trains
- Sell, buy bonds
- Build additional industries
- Buy or sell shares

Stations

Max. 32 stations per player. First stations gets an engine shop for free. Stations can be up- or downgraded.
During an accounting period built or re-built stations pay double for freight.

- Signal Tower
- Depot (3x3 squares influence area)
- Station (4x4 squares influence area)
- Terminal (5x5 squares influence area)

Station buildings

- Engine shop
- Store
- Hotel

Trains

Max. 32 trains per player.

- Change "consist" (number and type of cars/wagons
- Types include: mail, passenger, freight

Supply and demand

Stock market

Time

- 100 years running time (starting year depends on the scenario)
- Accounting period two years long

Difficulty levels

The chosen difficulty level remains in effect for the whole duration of a game.

Levels are "Investor", "Financier", "Mogul", "Tycoon". The level of difficulty affects revenue earned by each delivery
as well as the tycoon rating at the end.

Reality levels

- "No Collision Operation/Dispatcher Operation" In the dispatcher operation, the movement of trains is controlled by block
signals and collisions are possible.
- "Friendly competition/Cut-Throat competition" In friendly competition, they do not buy your stock, attempt to take you
over or start rate wars.
- "Basic economy/Complex economy"

Economy

- Simple: Stations with two or more cities will buy everything
- Complex: Specialized rules

Other features

- If the share price of a competing railroad falls below $5 and stays there for too long, it can be dissolved and be
removed from the game
- For each bankruptcy that the player declares, the interest for selling new bonds is increased by 1%. After a certain
number of bankruptcies, the player is unable to sell any bonds.
- Each car that is placed on a train costs $5,000. When the consist changes, one is only charged if the total number of
cars increases.
- There is a Find City option


Supplied scenarios

- Western United States
- Northeast United States
- Great Britain
- Continental Europe

https://en.wikipedia.org/wiki/Railroad_Tycoon

Railroad Tycoon II (1998)
-------------------------

This is a summary of the game model of the Railroad Tycoon 2 (RRT2).
Loading

0 comments on commit e37b2f4

Please sign in to comment.