Update to 1.10.0-beta1

This commit is contained in:
dP
2019-10-31 22:24:28 +03:00
parent b84a475e14
commit 599ccf0c2b
1470 changed files with 354219 additions and 16795 deletions

235
docs/admin_network.md Normal file
View File

@@ -0,0 +1,235 @@
# OpenTTD's admin network
Last updated: 2011-01-20
## Table of contents
- 1.0) [Preface](#10-preface)
- 2.0) [Joining the network](#20-joining-the-network)
- 3.0) [Asking for updates](#30-asking-for-updates)
- 3.1) [Polling manually](#31-polling-manually)
- 4.0) [Sending rcon commands](#40-sending-rcon-commands)
- 5.0) [Sending chat](#50-sending-chat)
- 5.1) [Receiving chat](#51-receiving-chat)
- 6.0) [Disconnecting](#60-disconnecting)
- 7.0) [Certain packet information](#70-certain-packet-information)
## 1.0) Preface
The admin network provides a dedicated network protocol designed for other
applications to communicate with OpenTTD. Connected applications can execute
console commands remotely (rcon commands) with no further authentication.
Furthermore information about clients and companies can be provided.
Admin applications remain connected when starting a new game or loading a saved
game in contrast to normal OpenTTD clients that get disconnected.
This document describes the admin network and its protocol.
Please refer to the mentioned enums in `src/network/core/tcp_admin.h`
Please also note that further improvements to the admin protocol can mean that
more packet types will be sent by the server. For forward compatibility it is
therefore wise to ignore unknown packets. Future improvements might also add
additional data to packets. This data should be ignored. Data will never be
removed from packets in later versions, except the possibility that complete
packets are dropped in favour of a new packet.
This though will be reflected in the protocol version as announced in the
`ADMIN_PACKET_SERVER_PROTOCOL` in section 2.0).
A reference implementation in Java for a client connecting to the admin interface
can be found at: [http://dev.openttdcoop.org/projects/joan](http://dev.openttdcoop.org/projects/joan)
## 2.0) Joining the network
Create a TCP connection to the server on port 3977. The application is
expected to authenticate within 10 seconds.
To authenticate send a `ADMIN_PACKET_ADMIN_JOIN` packet.
The server will reply with `ADMIN_PACKET_SERVER_PROTOCOL` followed directly by
`ADMIN_PACKET_SERVER_WELCOME`.
`ADMIN_PACKET_SERVER_PROTOCOL` contains details about the protocol version.
It is the job of your application to check this number and decide whether
it will remain connected or not.
Furthermore, this packet holds details on every `AdminUpdateType` and the
supported `AdminFrequencyTypes` (bitwise representation).
`ADMIN_PACKET_SERVER_WELCOME` contains details on the server and the map,
e.g. if the server is dedicated, its NetworkLanguage, size of the Map, etc.
Once you have received `ADMIN_PACKET_SERVER_WELCOME` you are connected and
authorized to do your thing.
The server will not provide any game related updates unless you ask for them.
There are four packets the server will none the less send, if applicable:
- ADMIN_PACKET_SERVER_ERROR
- ADMIN_PACKET_SERVER_WELCOME
- ADMIN_PACKET_SERVER_NEWGAME
- ADMIN_PACKET_SERVER_SHUTDOWN
However, `ADMIN_PACKET_SERVER_WELCOME` only after a `ADMIN_PACKET_SERVER_NEWGAME`
## 3.0) Asking for updates
Asking for updates is done with `ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY`.
With this packet you define which update you wish to receive at which
frequency.
Note: not every update type supports every frequency. If in doubt, you can
verify against the data received in `ADMIN_PACKET_SERVER_PROTOCOL`.
The server will not confirm your registered update. However, asking for an
invalid `AdminUpdateType` or a not supported `AdminUpdateFrequency` you will be
disconnected from the server with `NETWORK_ERROR_ILLEGAL_PACKET`.
Additional debug information can be found with a debug level of `net=3`.
`ADMIN_UPDATE_DATE` results in the server sending:
- ADMIN_PACKET_SERVER_DATE
`ADMIN_UPDATE_CLIENT_INFO` results in the server sending:
- ADMIN_PACKET_SERVER_CLIENT_JOIN
- ADMIN_PACKET_SERVER_CLIENT_INFO
- ADMIN_PACKET_SERVER_CLIENT_UPDATE
- ADMIN_PACKET_SERVER_CLIENT_QUIT
- ADMIN_PACKET_SERVER_CLIENT_ERROR
`ADMIN_UPDATE_COMPANY_INFO` results in the server sending:
- ADMIN_PACKET_SERVER_COMPANY_NEW
- ADMIN_PACKET_SERVER_COMPANY_INFO
- ADMIN_PACKET_SERVER_COMPANY_UPDATE
- ADMIN_PACKET_SERVER_COMPANY_REMOVE
`ADMIN_UPDATE_COMPANY_ECONOMY` results in the server sending:
- ADMIN_PACKET_SERVER_COMPANY_ECONOMY
`ADMIN_UPDATE_COMPANY_STATS` results in the server sending:
- ADMIN_PACKET_SERVER_COMPANY_STATS
`ADMIN_UPDATE_CHAT` results in the server sending:
- ADMIN_PACKET_SERVER_CHAT
`ADMIN_UPDATE_CONSOLE` results in the server sending:
- ADMIN_PACKET_SERVER_CONSOLE
`ADMIN_UPDATE_CMD_LOGGING` results in the server sending:
- ADMIN_PACKET_SERVER_CMD_LOGGING
## 3.1) Polling manually
Certain `AdminUpdateTypes` can also be polled:
- ADMIN_UPDATE_DATE
- ADMIN_UPDATE_CLIENT_INFO
- ADMIN_UPDATE_COMPANY_INFO
- ADMIN_UPDATE_COMPANY_ECONOMY
- ADMIN_UPDATE_COMPANY_STATS
- ADMIN_UPDATE_CMD_NAMES
`ADMIN_UPDATE_CLIENT_INFO` and `ADMIN_UPDATE_COMPANY_INFO` accept an additional
parameter. This parameter is used to specify a certain client or company.
Setting this parameter to `UINT32_MAX (0xFFFFFFFF)` will tell the server you
want to receive updates for all clients or companies.
Not supported `AdminUpdateType` in the poll will result in the server
disconnecting the application with `NETWORK_ERROR_ILLEGAL_PACKET`.
Additional debug information can be found with a debug level of `net=3`.
## 4.0) Sending rcon commands
Rcon runs separate from the `ADMIN_UPDATE_CONSOLE` `AdminUpdateType`. Requesting
the execution of a remote console command is done with the packet
`ADMIN_PACKET_ADMIN_RCON`.
Note: No additional authentication is required for rcon commands.
The server will reply with one or more `ADMIN_PACKET_SERVER_RCON` packets.
Finally an `ADMIN_PACKET_ADMIN_RCON_END` packet will be sent. Applications
will not receive the answer twice if they have asked for the `AdminUpdateType`
`ADMIN_UPDATE_CONSOLE`, as the result is not printed on the servers console
(just like clients rcon commands).
Furthermore, sending a `say` command (or any similar command) will not
be sent back into the admin network.
Chat from the server itself will only be sent to the admin network when it
was not sent from the admin network.
Note that when content is queried or updated via rcon, the processing
happens asynchronously. But the `ADMIN_PACKET_ADMIN_RCON_END` packet is sent
already right after the content is requested as there's no immediate output.
Thus other packages and the output of content rcon command may be sent at
an arbitrary later time, mixing into the output of other console activity,
e.g. also of possible subsequent other rcon commands sent.
## 5.0) Sending chat
Sending a `ADMIN_PACKET_ADMIN_CHAT` results in chat originating from the server.
Currently four types of chat are supported:
- NETWORK_ACTION_CHAT
- NETWORK_ACTION_CHAT_CLIENT
- NETWORK_ACTION_CHAT_COMPANY
- NETWORK_ACTION_SERVER_MESSAGE
`NETWORK_ACTION_SERVER_MESSAGE` can be sent to a single client or company
using the respective `DestType` and ID.
This is a message prefixed with the 3 stars, e.g. `*** foo has joined the game`
## 5.1) Receiving chat
Register `ADMIN_UPDATE_CHAT` at `ADMIN_FREQUENCY_AUTOMATIC` to receive chat.
The application will be able to receive all chat the server can see.
The configuration option `network.server_admin_chat` specifies whether
private chat for to the server is distributed into the admin network.
## 6.0) Disconnecting
It is a kind thing to say good bye before leaving. Do this by sending the
`ADMIN_PACKET_ADMIN_QUIT` packet.
## 7.0) Certain packet information
All `ADMIN_PACKET_SERVER_*` packets have an enum value greater 100.
`ADMIN_PACKET_SERVER_WELCOME`
Either directly follows `ADMIN_PACKET_SERVER_PROTOCOL` or is sent
after a new game has been started or a map loaded, i.e. also
after ADMIN_PACKET_SERVER_NEWGAME.
`ADMIN_PACKET_SERVER_CLIENT_JOIN` and `ADMIN_PACKET_SERVER_COMPANY_NEW`
These packets directly follow their respective INFO packets. If you receive
a CLIENT_JOIN / COMPANY_NEW packet without having received the INFO packet
it may be a good idea to POLL for the specific ID.
`ADMIN_PACKET_SERVER_CMD_NAMES` and `ADMIN_PACKET_SERVER_CMD_LOGGING`
Data provided with these packets is not stable and will not be
treated as such. Do not rely on IDs or names to be constant
across different versions / revisions of OpenTTD.
Data provided in this packet is for logging purposes only.

View File

@@ -0,0 +1,69 @@
# How to compile lang files (OpenTTD and strgen)
Last updated: 2009-06-30
## strgen usage
This guide is only interesting for people who want to alter something
themselves without access to [translator.openttd.org](https://translator.openttd.org/).
Please note that your compiled language file will only be compatible with the OpenTTD version
you have downloaded `english.txt`, the master language file, for. While this is
not always true, namely when changes in the code have not touched language
files, your safest bet is to assume this 'limitation'.
As a first step you need to compile strgen. This is as easy as typing
`'make strgen'`. You can download the precompile strgen from:
[http://www.openttd.org/download-strgen](http://www.openttd.org/download-strgen)
strgen takes as argument a txt file and translates it to a lng file, allowing
it to be used inside OpenTTD. strgen needs the master language file
`english.txt` to work. Below are some examples of strgen usage.
## Examples
### Example 1
If you are in the root of your working copy (git repository), you should type
`./strgen/strgen -s lang lang/english.txt`
to compile `english.txt` into `english.lng`. It will be placed in the lang dir.
### Example 2
You only have the strgen executable (no working copy) and you want to compile
a txt file in the same directory. You should type
`./strgen english.txt`
and you will get and `english.lng` in the same dir.
### Example 3
You have strgen somewhere, `english.txt` in `/usr/openttd/lang` and you want the
resulting language file to go to /tmp. Use
`./strgen -s /usr/openttd/lang -d /tmp english.txt`
You can interchange `english.txt` to whichever language you want to generate a
.lng file for.
## strgen command switches
`-v | --version`
strgen will tell what git revision it was last modified
`-t | --todo`
strgen will add <TODO> to any untranslated/missing strings and use the english
strings while compiling the language file
`-w | --warning`
strgen will print any missing strings or wrongly translated (bad format)
to standard error output(stderr)
`-h | --help | -?`
Print out a summarized help message explaining these switches
`-s | --source_dir`
strgen will search for the master file english.txt in the directory specified
by this switch instead of the current directory
`-d | --dest_dir`
strgen will put <language>.lng in the directory specified by this switch; if
no dest_dir is given, output is the same as source_dir

267
docs/desync.md Normal file
View File

@@ -0,0 +1,267 @@
# Some explanations about Desyncs
Last updated: 2014-02-23
## Table of contents
- 1.0) Desync theory
- 1.1) [OpenTTD multiplayer architecture](#11-openttd-multiplayer-architecture)
- 1.2) [What is a Desync and how is it detected](#12-what-is-a-desync-and-how-is-it-detected)
- 1.3) [Typical causes of Desyncs](#13-typical-causes-of-desyncs)
- 2.0) What to do in case of a Desync
- 2.1) [Cache debugging](#21-cache-debugging)
- 2.2) [Desync recording](#22-desync-recording)
- 3.0) Evaluating the Desync records
- 3.1) [Replaying](#31-replaying)
- 3.2) [Evaluation of the replay](#32-evaluation-of-the-replay)
- 3.3) [Comparing savegames](#33-comparing-savegames)
## 1.1) OpenTTD multiplayer architecture
OpenTTD has a huge gamestate, which changes all of the time.
The savegame contains the complete gamestate at a specific point
in time. But this state changes completely each tick: Vehicles move
and trees grow.
However, most of these changes in the gamestate are deterministic:
Without a player interfering a vehicle follows its orders always
in the same way, and trees always grow the same.
In OpenTTD multiplayer synchronisation works by creating a savegame
when clients join, and then transferring that savegame to the client,
so it has the complete gamestate at a fixed point in time.
Afterwards clients only receive 'commands', that is: Stuff which is
not predictable, like
- player actions
- AI actions
- GameScript actions
- Admin Port command
- rcon commands
- ...
These commands contain the information on how to execute the command,
and when to execute it. Time is measured in 'network frames'.
Mind that network frames to not match ingame time. Network frames
also run while the game is paused, to give a defined behaviour to
stuff that is executing while the game is paused.
The deterministic part of the gamestate is run by the clients on
their own. All they get from the server is the instruction to
run the gamestate up to a certain network time, which basically
says that there are no commands scheduled in that time.
When a client (which includes the server itself) wants to execute
a command (i.e. a non-predictable action), it does this by
- calling DoCommandP resp. DoCommandPInternal
- These functions first do a local test-run of the command to
check simple preconditions. (Just to give the client an
immediate response without bothering the server and waiting for
the response.) The test-run may not actually change the
gamestate, all changes must be discarded.
- If the local test-run succeeds the command is sent to the server.
- The server inserts the command into the command queue, which
assigns a network frame to the commands, i.e. when it shall be
executed on all clients.
- Enhanced with this specific timestamp, the command is send to all
clients, which execute the command simultaneously in the same
network frame in the same order.
## 1.2) What is a Desync and how is it detected
In the ideal case all clients have the same gamestate as the server
and run in sync. That is, vehicle movement is the same on all
clients, and commands are executed the same everywhere and
have the same results.
When a Desync happens, it means that the gamestates on the clients
(including the server) are no longer the same. Just imagine
that a vehicle picks the left line instead of the right line at
a junction on one client.
The important thing here is, that no one notices when a Desync
occurs. The desync client will continue to simulate the gamestate
and execute commands from the server. Once the gamestate differs
it will increasingly spiral out of control: If a vehicle picks a
different route, it will arrive at a different time at a station,
which will load different cargo, which causes other vehicles to
load other stuff, which causes industries to notice different
servicing, which causes industries to change production, ...
the client could run all day in a different universe.
To limit how long a Desync can remain unnoticed, the server
transfers some checksums every now and then for the gamestate.
Currently this checksum is the state of the random number
generator of the game logic. A lot of things in OpenTTD depend
on the RNG, and if the gamestate differs, it is likely that the
RNG is called at different times, and the state differs when
checked.
The clients compare this 'checksum' with the checksum of their
own gamestate at the specific network frame. If they differ,
the client disconnects with a Desync error.
The important thing here is: The detection of the Desync is
only an ultimate failure detection. It does not give any
indication on when the Desync happened. The Desync may after
all have occurred long ago, and just did not affect the checksum
up to now. The checksum may have matched 10 times or more
since the Desync happened, and only now the Desync has spiraled
enough to finally affect the checksum. (There was once a desync
which was only noticed by the checksum after 20 game years.)
## 1.3) Typical causes of Desyncs
Desyncs can be caused by the following scenarios:
- The savegame does not describe the complete gamestate.
- Some information which affects the progression of the
gamestate is not saved in the savegame.
- Some information which affects the progression of the
gamestate is not loaded from the savegame.
This includes the case that something is not completely
reset before loading the savegame, so data from the
previous game is carried over to the new one.
- The gamestate does not behave deterministic.
- Cache mismatch: The game logic depends on some cached
values, which are not invalidated properly. This is
the usual case for NewGRF-specific Desyncs.
- Undefined behaviour: The game logic performs multiple
things in an undefined order or with an undefined
result. E.g. when sorting something with a key while
some keys are equal. Or some computation that depends
on the CPU architecture (32/64 bit, little/big endian).
- The gamestate is modified when it shall not be modified.
- The test-run of a command alters the gamestate.
- The gamestate is altered by a player or script without
using commands.
## 2.1) Cache debugging
Desyncs which are caused by improper cache validation can
often be found by enabling cache validation:
- Start OpenTTD with '-d desync=2'.
- This will enable validation of caches every tick.
That is, cached values are recomputed every tick and compared
to the cached value.
- Differences are logged to 'commands-out.log' in the autosave
folder.
Mind that this type of debugging can also be done in singleplayer.
## 2.2) Desync recording
If you have a server, which happens to encounter Desyncs often,
you can enable recording of the gamestate alterations. This
will later allow the replay the gamestate and locate the Desync
cause.
There are two levels of Desync recording, which are enabled
via '-d desync=2' resp. '-d desync=3'. Both will record all
commands to a file 'commands-out.log' in the autosave folder.
If you have the savegame from the start of the server, and
this command log you can replay the whole game. (see Section 3.1)
If you do not start the server from a savegame, there will
also be a savegame created just after a map has been generated.
The savegame will be named 'dmp_cmds_*.sav' and be put into
the autosave folder.
In addition to that '-d desync=3' also creates regular savegames
at defined spots in network time. (more defined than regular
autosaves). These will be created in the autosave folder
and will also be named 'dmp_cmds_*.sav'.
These saves allow comparing the gamestate with the original
gamestate during replaying, and thus greatly help debugging.
However, they also take a lot of disk space.
## 3.1) Replaying
To replay a Desync recording, you need these files:
- The savegame from when the server was started, resp.
the automatically created savegame from when the map
was generated.
- The 'commands-out.log' file.
- Optionally the 'dmp_cmds_*.sav'.
Put these files into a safe spot. (Not your autosave folder!)
Next, prepare your OpenTTD for replaying:
- Get the same version of OpenTTD as the original server was running.
- Uncomment/enable the define 'DEBUG_DUMP_COMMANDS' in
'src/network/network_func.h'.
(DEBUG_FAILED_DUMP_COMMANDS is explained later)
- Put the 'commands-out.log' into the root save folder, and rename
it to 'commands.log'.
- Run 'openttd -D -d desync=3 -g startsavegame.sav'.
This replays the server log and creates new 'commands-out.log'
and 'dmp_cmds_*.sav' in your autosave folder.
## 3.2) Evaluation of the replay
The replaying will also compare the checksums which are part of
the 'commands-out.log' with the replayed gamestate.
If they differ, it will trigger a 'NOT_REACHED'.
If the replay succeeds without mismatch, that is the replay reproduces
the original server state:
- Repeat the replay starting from incrementally later 'dmp_cmds_*.sav'
while truncating the 'commands.log' at the beginning appropriately.
The 'dmp_cmds_*.sav' can be your own ones from the first reply, or
the ones from the original server (if you have them).
(This simulates the view of joining clients during the game.)
- If one of those replays fails, you have located the Desync between
the last dmp_cmds that reproduces the replay and the first one
that fails.
If the replay does not succeed without mismatch, you can check the logs
whether there were failed commands. Then you may try to replay with
DEBUG_FAILED_DUMP_COMMANDS enabled. If the replay then fails, the
command test-run of the failed command modified the game state.
If you have the original 'dmp_cmds_*.sav', you can also compare those
savegames with your own ones from the replay. You can also comment/disable
the 'NOT_REACHED' mentioned above, to get another 'dmp_cmds_*.sav' from
the replay after the mismatch has already been detected.
See Section 3.2 on how to compare savegames.
If the saves differ you have located the Desync between the last dmp_cmds
that match and the first one that does not. The difference of the saves
may point you in the direction of what causes it.
If the replay succeeds without mismatch, and you do not have any
'dmp_cmd_*.sav' from the original server, it is a lost case.
Enable creation of the 'dmp_cmd_*.sav' on the server, and wait for the
next Desync.
Finally, you can also compare the 'commands-out.log' from the original
server with the one from the replay. They will differ in stuff like
dates, and the original log will contain the chat, but otherwise they
should match.
## 3.3) Comparing savegames
The binary form of the savegames from the original server and from
your replay will always differ:
- The savegame contains paths to used NewGRF files.
- The gamelog will log your loading of the savegame.
- The savegame data of AIs and the Gamescript will differ.
Scripts are not run during the replay, only their recorded commands
are replayed. Their internal state will thus not change in the
replay and will differ.
To compare savegame more semantically, there exist some ugly hackish
tools at:
http://devs.openttd.org/~frosch/texts/zpipe.c
http://devs.openttd.org/~frosch/texts/printhunk.c
The first one decompresses OpenTTD savegames. The second one creates
a textual representation of an uncompressed savegame, by parsing hunks
and arrays and such. With both tools you need to be a bit careful
since they work on stdin and stdout, which may not deal well with
binary data.
If you have the textual representation of the savegames, you can
compare them with regular diff tools.

View File

@@ -16,7 +16,7 @@
<a href="landscape_grid.html">Landscape grid</a> page.
</p>
<p>Nine attributes (counting &quot;<span style="font-weight: bold;">type</span>&quot; and
&quot;<span style="font-weight: bold;">height</span>&quot;) hold the informations about a tile.<BR>
&quot;<span style="font-weight: bold;">height</span>&quot;) hold the information about a tile.<BR>
These attributes are referred to as
&quot;<span style="font-weight: bold;">type</span>",
&quot;<span style="font-weight: bold;">height</span>",
@@ -61,7 +61,7 @@
<a name="tropic_zone"></a>
Bits 1..0:
<table border="1" style="width: 30em;">
<tr bgcolor="#CCCCCC"><td colspan="2">Only meaningfull in tropic climate. It contains the definition of the available zones</td></tr>
<tr bgcolor="#CCCCCC"><td colspan="2">Only meaningful in tropic climate. It contains the definition of the available zones</td></tr>
<tr><td style="width: 5em;"><tt>00</tt></td><td>normal</td></tr>
<tr><td><tt>01</tt></td><td>desert</td></tr>
<tr><td><tt>02</tt></td><td>rain forest</td></tr>
@@ -98,6 +98,32 @@
</li>
</ul>
</li>
<li><span style="font-weight: bold;">m4:</span><br>
<a name="RoadType"></a>
Road roadtype. Used for all tiles with road (road, station, tunnelbridge).
<ul>
<li>
Bits 5..0: Road roadtype, 0x3F for no road.
</li>
</ul>
</li>
<li><span style="font-weight: bold;">m8:</span><br>
<a name="TramType"></a>
Tram roadtype. Used for all tiles with road (road, station, tunnelbridge).
<ul>
<li>
Bits 11..6: Tram roadtype, 0x3F for no tram.
</li>
</ul>
</li>
<li><span style="font-weight: bold;">m8:</span><br>
<ul>
<li>
<a name="RailType"></a>
Bits 5..0: Railtype. Used for all tiles with rail (road, rail, station, tunnelbridge).
</li>
</ul>
</li>
<li><span style="font-weight: bold;">m7:</span><br>
Animation frame/state. Used for houses, industries, objects and stations.
</li>
@@ -108,7 +134,7 @@
<table border=1 cellpadding=3>
<tr bgcolor="#0099FF">
<th align=left><font color="#FFFFFF">Class</font></th>
<th align=left><font color="#FFFFFF">Meaning & details of encoding</font></th>
<th align=left><font color="#FFFFFF">Meaning &amp; details of encoding</font></th>
</tr>
<tr bgcolor="#CCCCCC">
<td align=left><strong><a name="Class0"><tt> 0 </tt></a></strong></td>
@@ -223,6 +249,7 @@
<td valign=top nowrap>&nbsp;</td>
<td>
<ul>
<li>m1 bit 7: Ship docking tile status (for half-tile with water)</li>
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a> of the tile</li>
<li>m2: see signals</li>
<li>m3 bits 7..4: see signals</li>
@@ -535,21 +562,10 @@
<td>
<ul>
<li>m2: Index into the array of towns (owning town for town roads; closest town otherwise, INVALID_TOWN if there is no town or we are creating a town)</li>
<li>m7 bit 5 set = on snow or desert</li>
<li>m7 bits 7..6: present road types
<table>
<tr>
<td>bit 0&nbsp; </td>
<td>normal road</td>
</tr>
<tr>
<td>bit 1&nbsp; </td>
<td>tram</td>
</tr>
</table>
</li>
<li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of road type 1 (tram); OWNER_NONE (<tt>10</tt>) is stored as OWNER_TOWN (<tt>0F</tt>)
<li>m4 bits 5..0: <a href="#RoadType">Roadtype</a></li>
<li>m7 bit 5 set = on snow or desert</li>
<li>m8 bits 11..6: <a href="#TramType">Tramtype</a></li>
<li>m5 bits 7 clear: road or level-crossing
<ul>
<li>m6 bits 5..3:
@@ -744,7 +760,7 @@
</ul>
</li>
</ul>
<small><a name="newhouses"></a>Newhouses is the name englobing a newGRF feature developped by TTDPatch devs (mainly Csaboka).<br>
<small><a name="newhouses"></a>Newhouses is the name englobing a newGRF feature developed by TTDPatch devs (mainly Csaboka).<br>
It allows the replacement of the properties as well as the graphics of houses in the game.<br>
To distinguish between the standard behaviour and the newGRF one, HouseID (m4 + m3[6]) is tested for anything above 110.<br>
110 is the count of standard houses. So above 110 means there is a new definition of at least one house</small>
@@ -856,12 +872,14 @@
<td valign=top nowrap>&nbsp;</td>
<td>
<ul>
<li>m1 bit 7: Ship docking tile status (for buoys)</li>
<li>m1 bits 6..5: water class for buoys, water part of docks and for airport tiles</li>
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a> of the station</li>
<li>m2: index into the array of stations</li>
<li>m3 bits 7..4: persistent random data for railway stations/waypoints and airports)</li>
<li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of tram tracks (road stop)</li>
<li>m4: custom station id; 0 means standard graphics</li>
<li>m4: <a href="#RoadType">Roadtype</a> for road stops</li>
<li>m5: graphics index (range from 0..255 for each station type):
<table>
<tr>
@@ -977,8 +995,8 @@
<li>m6 bit 2: pbs reservation state for railway stations/waypoints</li>
<li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road (road stops)</li>
<li>m7 bits 7..6: present road types (road stops)</li>
<li>m7: animation frame (railway stations/waypoints, airports)</li>
<li>m8 bits 11..6: <a href="#TramType">Tramtype</a></li>
<li>m8 bits 5..0: <a href="#TrackType">track type</a> for railway stations/waypoints</li>
</ul>
</td>
@@ -992,6 +1010,7 @@
<td valign=top nowrap>&nbsp;</td>
<td>
<ul>
<li>m1 bit 7: Ship docking tile status</li>
<li>m1 bits 6..5 : Water class (sea, canal or river)
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a> (for sea, rivers, and coasts normally <tt>11</tt>)</li>
<li>m2: Depot index (for depots only)</li>
@@ -1443,8 +1462,10 @@
<td valign=top nowrap>&nbsp;</td>
<td>
<ul>
<li>m1 bit 7: Ship docking tile status (for aqueducts)</li>
<li>m1 bits 4..0: <a href="#OwnershipInfo">owner</a></li>
<li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of tram</li>
<li>m4: <a href="#RoadType">Roadtype</a></li>
<li>m5 bit 4: pbs reservation state for railway</li>
<li>m5 bits 7 clear: tunnel entrance/exit</li>
<li>m5 bit 7 set: bridge ramp
@@ -1581,7 +1602,7 @@
</li>
<li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road</li>
<li>m7 bit 5 set = on snow or desert</li>
<li>m7 bits 7..6: present road types for road</li>
<li>m8 bits 11..6: <a href="#TramType">Tramtype</a></li>
<li>m8 bits 5..0: <a href="#TrackType">track type</a> for railway</li>
</ul>
</td>

View File

@@ -100,7 +100,7 @@ the array so you can quickly see what is used and what is not.
<td class="caption">rail</td>
<td class="bits">XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOO</span>X XXXX</td>
<td class="bits">X<span class="free">OO</span>X XXXX</td>
<td class="bits"><span class="free">OOOO</span> XXXX <span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO</span> XXXX</td>
@@ -143,11 +143,11 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="free">OOO</span>X XXXX</td>
<td class="bits">XXXX XXXX XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OO</span>XX X<span class="free">OOO</span></td>
<td class="bits">XXX<span class="free">O</span> XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OO</span>X<span class="free">O</span> XXXX</td>
<td class="bits"><span class="free">OOOO</span> XXXX XX<span class="free">OO OOOO</span></td>
</tr>
<tr>
<td class="caption">level crossing</td>
@@ -159,8 +159,8 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">XXXX <span class="free">OOO</span>X</td>
<td class="bits"><span class="free">OO</span>XX X<span class="free">OOO</span></td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OO</span>XX XXXX</td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
<td class="bits"><span class="free">OOOO</span> XXXX XXXX XXXX</td>
</tr>
<tr>
<td class="caption">road depot</td>
@@ -169,11 +169,11 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits">XXXX <span class="free">OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">-inherit-</td>
<td class="bits">XX<span class="free">OO OO</span>XX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">XXX<span class="free">O</span> XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OO</span>X<span class="free">O</span> XXXX</td>
<td class="bits">-inherit-</td>
</tr>
<tr>
<td>3</td>
@@ -208,7 +208,7 @@ the array so you can quickly see what is used and what is not.
<td class="caption">rail station</td>
<td class="bits">XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">O</span>XXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits">XXXX XXXX XXXX XXXX</td>
<td class="bits">XXXX <span class="free">OOOO</span></td>
<td class="bits">XXXX XXXX</td>
@@ -237,11 +237,11 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits">XXXX <span class="free">OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
<td class="bits"><span class="option">~~~~ ~</span>XXX</td>
<td class="bits"><span class="free">OO</span>XX X<span class="free">OOO</span></td>
<td class="bits">XX<span class="free">O</span>X XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OOO</span>X XXXX</td>
<td class="bits"><span class="free">OOOO</span> XXXX XX<span class="free">OO OOOO</span></td>
</tr>
<tr>
<td class="caption">dock</td>
@@ -300,7 +300,7 @@ the array so you can quickly see what is used and what is not.
<td class="caption">sea, shore</td>
<td class="bits">XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">O</span>XXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
@@ -354,14 +354,14 @@ the array so you can quickly see what is used and what is not.
<td class="caption">tunnel entrance</td>
<td class="bits">XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOO</span>X XXXX</td>
<td class="bits">X<span class="free">OO</span>X XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits">XXXX <span class="free">OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
<td class="bits">X<span class="free">OO</span>X XXXX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OO</span>XX XXXX</td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
<td class="bits"><span class="free">OOOO</span> XXXX XXXX XXXX</td>
</tr>
<tr>
<td>bridge ramp</td>
@@ -370,7 +370,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits"><span class="free">OO</span>XX XX<span class="free">OO</span></td>
<td class="bits">-inherit-</td>

30
docs/linkgraph.md Normal file
View File

@@ -0,0 +1,30 @@
# Some clarifications about the link graph
`InitializeLinkGraphs` joins all threads, so if the game is abandoned
with some threads still running, they're joined as soon as the next game
(possibly the title game) is started. See also `InitializeGame`.
The MCF (multi-commodity flow) algorithm can be quite CPU-hungry as it's
NP-hard and takes exponential time (though with a very small constant
factor) in the number of nodes.
This is why it is run in a separate thread where possible. However after
some time the thread is joined and if it hasn't finished by then the game
will hang. This problem gets worse if we are running on a platform without
threads. However, as those are usually the ones with less CPU power I
assume the contention for the CPU would make the game hard to play even
with threads or even without cargodist (autosave ...). I might be wrong,
but I won't put any work into this before someone shows me some problem.
You can configure the link graph recalculation time. A link graph
recalculation time of X days means that each link graph job has X days
to run before it is joined. The downside is that the flow stats won't be
updated before the job is finished and thus a high value means less
updates and longer times until changes in capacities are accounted for.
If you play a very large map with a complicated link graph you may want to
raise the time setting to avoid lags. The same holds for systems with slow
CPUs.
Another option to avoid excessive lags is to reduce the accuracy of link
graph calculations. Generally the accuracy is inversely correlated to the
CPU requirements of the MCF algorithm.

213
docs/multiplayer.md Normal file
View File

@@ -0,0 +1,213 @@
# Multiplayer manual for OpenTTD
Last updated: 2011-02-16
## Table of contents
- 1.0) [Starting a server](#10-starting-a-server)
- 2.0) [Connecting to a server](#20-connecting-to-a-server)
- 2.1) [Connecting to a server over the console](#21-connecting-to-a-server-over-the-console)
- 3.0) [Playing internet games](#30-playing-internet-games)
- 4.0) [Tips for servers](#40-tips-for-servers)
- 4.1)[Imposing landscaping limits](#41-imposing-landscaping-limits)
- 5.0) [Some useful things](#50-some-useful-things)
- 6.0) [Troubleshooting](#60-troubleshooting)
## 1.0) Starting a server
- Make sure that you have your firewall of the computer as well as possible
routers or modems of the server configured such that:
- port 3979 is free for both UDP and TCP connections in- and outgoing
- port 3978 is free outbound for UDP in order to advertise with the master
server (if desired). Otherwise you'll have to tell players your IP.
- port 3977 if use of the admin interface is desired (see admin_network.txt)
- Click "multiplayer" on the startup screen
- Click "start server"
- Type in a game name
- Select the type of game ('LAN/Internet' or 'Internet (advertise)'. With the
last one other people are able to see you online. Else they need your IP and
port to join)
- Click "start game", "load game" or "load scenario"
- Start playing
## 2.0) Connecting to a server
- Click "multiplayer" on the startup screen
- If you want to connect to any network game in your LAN click on 'LAN', then
on 'Find Server'
- If you want to see which servers all online on the Internet, click on
'Internet' and 'Find Server'
- If there were more than one server
- select one in the list below the buttons
- click on 'join game'
- If you want to play and you have the ip or hostname of the game server you
want connect to.
- click add server
- type in the ip address or hostname
- if you want to add a port use :<port>
- Now you can select a company and press: "Join company", to help that company
- Or you can press "Spectate game", to spectate the game
- Or you can press "New company", and start your own company (if there are
slots free)
- You see a progressbar how far you are with joining the server.
- Happy playing
## 2.1) Connecting to a server over the console
- Open the console and type in the following command:
connect `<ip/host>:<port>#<company-no>`
## 3.0) Playing internet games
- Servers with a red dot behind it have a different version then you have. You
will not be able to join those servers.
- Servers with a yellow dot behind it have NewGRFs that you do not have. You
will not be able to join those servers. However, via "NewGRF Settings" and
"Find missing content online" you might be able to download the needed
NewGRFs after which you can join the server.
- It can happen that a connection is that slow, or you have that many clients
connected to your server, that your clients start to loose their connection.
Some things you can do about it:
- [network] frame_freq:
change it in console with: 'set network.frame_freq <number>'
the number should be between the 0 and 10, not much higher. It indicates
the delay between clicking and showing up. The higher, the more you notice
it, but the less bandwidth you use.
A good value for Internet-games is 2 or 3.
- [network] sync_freq:
change it in console with: 'set network.sync_freq <number>'
the number should be between the 50 and 1000, not much lower, not much
higher. It indicates the time between sync-frames. A sync-frame is a frame
which checks if all clients are still in sync. When the value it too high,
clients can desync in 1960, but the server detects it in 1970. Not really
handy. The lower the value, the more bandwidth it uses.
NB: changing frame_freq has more effect on the bandwidth then sync_freq.
## 4.0) Tips for servers
- You can launch a dedicated server by adding -D as parameter.
- In UNIX like systems, you can fork your dedicated server by adding -f as
parameter.
- You can automatically clean companies that do not have a client connected to
them, for, let's say, 3 years. You can do this via: 'set autoclean_companies'
and 'set autoclean_protected' and 'set autoclean_unprotected'. Unprotected
removes a password from a company when it is not used for more then the
defined amount of months. 'set autoclean_novehicles' can be used to remove
companies without any vehicles quickly.
- You can also do this manually via the console: 'reset_company'.
- You can let your server automatically restart a map when, let's say, year 2030
is reached. See 'set restart_game_date' for detail.
- If you want to be on the server-list, enable Advertising. To do this, select
'Internet (advertise)' in the Start Server menu, or type in console:
'set server_advertise 1'.
- You can protect your server with a password via the console: 'set server_pw',
or via the Start Server menu.
- When you have many clients connected to your server via Internet, watch your
bandwidth (if you have any limit on it, set by your ISP). One client uses
about 1.5 kilobytes per second up and down. To decrease this amount, setting
'frame_freq' to 1 will reduce it to roughly 1 kilobyte per second per client.
- OpenTTD's default settings for maximum number of clients, and amount of data
from clients to process are chosen to not influence the normal playing of
people, but to prevent or at least make it less likely that someone can
perform a (distributed) denial-of-service attack on your server by causing
an out-of-memory event by flooding the server with data to send to all
clients. The major factor in this is the maximum number of clients; with
32 clients "only" sending one chat message causes 1024 messages to be
distributed in total, with 64 clients that already quadruples to 4096. Given
that upstream bandwidth is usually the limiting factor, a queue of packets
that need to be sent will be created.
To prevent clients from exploiting this "explosion" of packets to send we
limit the number of incoming data, resulting in effectively limiting the
amount of data that OpenTTD will send to the clients. Even with the default
limits it is possible to generate about 70.000 packets per second, or about
7 megabit per second of traffic.
Given that OpenTTD kicks clients after they have not reacted within about 9
seconds from sending a frame update packet it would be possible that OpenTTD
keeps about 600.000 packets in memory, using about 50 megabytes of memory.
Given that OpenTTD allows short bursts of packets, you can have slightly
more packets in memory in case of a distributed denial of service attack.
When increasing the amount of incoming data, or the maximum number of
clients the amount of memory OpenTTD needs in case of a distributed denial
of service attack is linearly related to the amount of incoming data and
quadratic to the amount of clients. In short, a rule of thumb for, the
maximum memory usage for packets is:
#max_clients * #max_clients * bytes_per_frame * 10 KiB.
### 4.1) Imposing landscaping limits
- You can impose limits on companies by the following 4 settings:
- terraform_per_64k_frames
- terraform_frame_burst
- clear_per_64k_frames
- clear_frame_burst
- Explaining 'per_64K_frames' and 'burst'
- 'burst' defines 3 things, the maximum limit, the limit of a single action,
and the initial value for the limit assigned to a new company.
This setting is fairly simple and requires no math.
A value of 1 means a single tile can be affected by a single action.
This results in having to click 400 times when wanting to cover an area
of 20 x 20 tiles.
The default value 4096 covers an area of 64 x 64 tiles.
- 'per_64k_frames' defines the number of tiles added to each companies limit
per frame (however not past the possible maximum value,the 'burst').
64k rather resembles the exact number of 65536 frames. So setting this
variable to 65536 means: 65536 / 65536 = 1 tile per frame.
As a day consists of 74 frames, a company's limit is increased by 74
tiles during the course of a single day (2.22 seconds).
To achieve a 1 tile per day increase the following calculation is needed:
1 / 74 (frames per day) * 65536 (per_64k_frames) = 885.62...
after rounding: a value of 886 means adding a bit over 1 tile per day.
There is still enough space to scale this value downwards:
decreasing this value to 127 results in a bit over 1 tile added to the
allowance per week (7 days).
To create a setup in which a company gets an initial allowance only,
set the value to 0 - no increase of the allowance per frame.
- Even though construction actions include a clear tile action, they are not
affected by the above settings.
## 5.0) Some useful things
- You can protect your company so nobody else can join uninvited. To do this,
set a password in your Company Screen
- You can give other players some money via the ClientList (under the 'head'
in the mainbar).
- You can chat with other players via ENTER or via SHIFT+T or via the ClientList
- Servers can now kick players, so don't make them use it!
## 6.0) Troubleshooting
- My advertising server does not show up in list at servers.openttd.org
Run openttd with the '-d net=2' parameter. That will show which incoming
communication is received, whether the replies from the master server or
communication from an admin tool reach the programme. See section 1
'Starting a server' further up for the ports and protocols used by OpenTTD.
The ports can be configured in the config file.