Project

General

Profile

Feature #315 ยป 0033-HACKING-Remove-double-spaces.patch

Marko Lindqvist, 03/17/2024 09:03 PM

View differences:

doc/HACKING
ai: the ai, later linked into the server
tools: freeciv support executables
Freeciv is written in C. Header files should be compatible with C++ so
Freeciv is written in C. Header files should be compatible with C++ so
that C++ add-ons (particularly new clients) are possible. See the
CodingStyle file for more.
......
handle_remove_unit(), and finally the unit is disbanded.
Notice that the two packets (PACKET_UNIT_DISBAND and
PACKET_REMOVE_UNIT) were generic packets. That means the packet
structures involved, are used by various requests. The
packet_unit_request() is for example also used for the packets
PACKET_REMOVE_UNIT) were generic packets. That means the packet
structures involved, are used by various requests.
The packet_unit_request() is for example also used for the packets
PACKET_UNIT_BUILD_CITY and PACKET_UNIT_CHANGE_HOMECITY.
When adding a new packet type, check to see if you can reuse some of the
......
- the data send to a reconnecting player
- the end turn activities
The GTK+ client uses gdk_input_add() to tell gtk to call the callback
The GTK client uses gdk_input_add() to tell gtk to call the callback
functions, when something happens on the client socket.
=========================================================================
......
may be readable by some clients).
If you alter the graphics, then make sure that the background remains
transparent. Failing to do this means the mask-pixmaps will not be
transparent. Failing to do this means the mask-pixmaps will not be
generated properly, which will certainly not give any good results.
Each terrain tile is drawn in 16 versions, all the combinations with
......
forests and rivers are treated in special cases.
Isometric tilesets are drawn in a similar way to how civ2 draws (that's
why civ2 graphics are compatible). For each base terrain type there
exists one tile sprite for that terrain. The tile is blended with
nearby tiles to get a nice-looking boundary. This is erronously called
why civ2 graphics are compatible). For each base terrain type there
exists one tile sprite for that terrain. The tile is blended with
nearby tiles to get a nice-looking boundary. This is erronously called
"dither" in the code.
Non-isometric tilesets draw the tiles in the "original" freeciv way,
which is both harder and less pretty. There are multiple copies of
which is both harder and less pretty. There are multiple copies of
each tile, so that a different copy can be drawn depending the terrain
type of the adjacent tiles. It may eventually be worthwhile to convert
type of the adjacent tiles. It may eventually be worthwhile to convert
this to the civ2 system.
=========================================================================
......
Different types of map topology
=========================================================================
Originally Freeciv supports only a simple rectangular map. For instance
Originally Freeciv supports only a simple rectangular map. For instance
a 5x3 map would be conceptualized as
<- XXXXX ->
......
<- XXXXX ->
and it looks just like that under "overhead" (non-isometric) view (the
arrows represent an east-west wrapping). But under an isometric-view
arrows represent an east-west wrapping). But under an isometric-view
client, the same map will look like
X
......
X X
x
where "north" is to the upper-right and "south" to the lower-left. This
makes for a mediocre interface.
where "north" is to the upper-right and "south" to the lower-left.
This makes for a mediocre interface.
An isometric-view client will behave better with an isometric map. This is
what Civ2, SMAC, Civ3, etc. all use. A rectangular isometric map can be
An isometric-view client will behave better with an isometric map. This is
what Civ2, SMAC, Civ3, etc. all use. A rectangular isometric map can be
conceptualized as
<- X X X X X ->
......
Of course under an overhead-view client it will again turn out badly.
Both types of maps can easily wrap in either direction: north-south or
east-west. Thus there are four types of wrapping: flat-earth, vertical
cylinder, horizontal cylinder, and torus. Traditionally Freeciv only wraps
east-west. Thus there are four types of wrapping: flat-earth, vertical
cylinder, horizontal cylinder, and torus. Traditionally Freeciv only wraps
in the east-west direction.
=========================================================================
......
=========================================================================
In Freeciv, we have the general concept of a "position" or "tile". A tile
can be referred to in any of several coordinate systems. The distinction
can be referred to in any of several coordinate systems. The distinction
becomes important when we start to use non-standard maps (see above).
Here is a diagram of coordinate conversions for a classical map.
......
- Map (or "standard") coordinates.
All of the code examples above are in map coordinates. These preserve
All of the code examples above are in map coordinates. These preserve
the local geometry of square tiles, but do not represent the global map
geometry well. In map coordinates, you are guaranteed (so long as we use
geometry well. In map coordinates, you are guaranteed (so long as we use
square tiles) that the tile adjacency rules
(map_x-1, map_y-1) (map_x, map_y-1) (map_x+1, map_y-1)
......
- Natural coordinates.
Natural coordinates preserve the geometry of map coordinates, but also have
the rectangular property of native coordinates. They are unwieldy for
the rectangular property of native coordinates. They are unwieldy for
most operations because of their sparseness - they may not have the same
scale as map coordinates and, in the iso case, there are gaps in the
natural representation of a map.
......
is needed.
Native coordinates compress the map into a continuous rectangle; the
dimensions are defined as map.xsize x map.ysize. For instance the
dimensions are defined as map.xsize x map.ysize. For instance the
above iso-rectangular map is represented in native coordinates by
compressing the natural representation in the X axis to get the
3x3 iso-rectangle of
......
GHI (0,2) (1,2) (3,2)
The resulting coordinate system is much easier to use than map
coordinates for some operations. These include most internal topology
coordinates for some operations. These include most internal topology
operations (e.g., normalize_map_pos, whole_map_iterate) as well as
storage (in map.tiles and savegames, for instance).
......
- Index coordinates.
Index coordinates simply reorder the map into a continuous (filled-in)
one-dimensional system. This coordinate system is closely tied to
one-dimensional system. This coordinate system is closely tied to
the ordering of the tiles in native coordinates, and is slightly
easier to use for some operations (like storage) because it is
one-dimensional. In general you can't assume anything about the ordering
one-dimensional. In general you can't assume anything about the ordering
of the positions within the system.
Indexes can be easily converted to native coordinates using
......
An map index can tested using the CHECK_INDEX macro.
With a classical rectangular map, the first three coordinate systems are
equivalent. When we introduce isometric maps, the distinction becomes
important, as demonstrated above. Many places in the code have
equivalent. When we introduce isometric maps, the distinction becomes
important, as demonstrated above. Many places in the code have
introduced "map_x/map_y" or "nat_x/nat_y" to help distinguish whether
map or native coordinates are being used. Other places are not yet
map or native coordinates are being used. Other places are not yet
rigorous in keeping them apart, and will often just name their variables
"x" and "y". The latter can usually be assumed to be map coordinates.
"x" and "y". The latter can usually be assumed to be map coordinates.
Note that if you don't need to do some abstract geometry exploit, you
will mostly use tile pointers, and give to map.[ch] tools the ability
......
=========================================================================
An isometric map is defined by the operation that converts between map
(user) coordinates and native (internal) ones. In native coordinates, an
isometric map behaves exactly the same way as a standard one. (See
"native coordinates", above.
(user) coordinates and native (internal) ones. In native coordinates, an
isometric map behaves exactly the same way as a standard one.
(See "native coordinates", above.)
Converting from map to native coordinates involves a pi/2 rotation (which
scales in each dimension by sqrt(2)) followed by a compression in the X
direction by a factor of 2. Then a translation is required since the
direction by a factor of 2. Then a translation is required since the
"normal set" of native coordinates is defined as
{(x, y) | x: [0..map.xsize) and y: [0..map.ysize)}
while the normal set of map coordinates must satisfy x >= 0 and y >= 0.
......
TILE_KNOWN_UNSEEN is a tile of which the user knows the terrain,
but not recent cities, roads, etc.
TILE_UNKNOWN tiles never are (nor should be) sent to the client. In the
TILE_UNKNOWN tiles never are (nor should be) sent to the client. In the
past, UNKNOWN tiles that were adjacent to UNSEEN or SEEN were sent to make
the drawing process easier, but this has now been removed. This means
the drawing process easier, but this has now been removed. This means
exploring new land may sometimes change the appearance of existing land (but
this is not fundamentally different from what might happen when you
transform land). Sending the extra info, however, not only confused the
transform land). Sending the extra info, however, not only confused the
goto code but allowed cheating.
Fog of war is the fact that even when you have seen a tile once you are
......
and
void fog_area(struct player *pplayer, int x, int y, int len)
functions. "int len" is the radius of the area that should be
fogged/unfogged, i.e. a len of 1 is a normal unit. In addition to keeping
fogged/unfogged, i.e., a len of 1 is a normal unit. In addition to keeping
track of fog of war, these functions also make sure to reveal TILE_UNKNOWN
tiles you get near, and send info about TILE_UNKNOWN tiles near that the
client needs for drawing. They then send the tiles to
......
Player-related entities in Freeciv - by Reinier Post <reinpost@win.tue.nl>
+ by dwp@mso.anu.edu.au
Freeciv is confused about the meaning of 'player'. As a participant in
Freeciv is confused about the meaning of 'player'. As a participant in
Freeciv games, you'll notice that the participants are called 'players'.
At the same time, players seem to be identified with civilizations.
On the other hand, civilizations seem to be identified by 'nation':
......
+ connection
Records a client connection; like a user, but disappears when the user
disconnects, whereas for real users we may want to remember them between
connections. See Connections section below.
connections. See Connections section below.
Where do these entities exist?
Nations aren't actually used for anything that matters; for them,
so the question isn't very interesting.
Players (more aptly named, 'civilizations'), exist in games. Except in
the context of a running game, the entity makes no sense. Players and
their status are part of savefiles. A game can be saved and restarted
Players (more aptly named, 'civilizations'), exist in games. Except in
the context of a running game, the entity makes no sense. Players and
their status are part of savefiles. A game can be saved and restarted
on a different server; the players will be the same. A new game will
have new players. Players exist in common/ (even games do) but a
have new players. Players exist in common/ (even games do) but a
client only has one instantiated player.
The reason to introduce users is client-side server commands. It must
The reason to introduce users is client-side server commands. It must
be possible to assign different levels of access to commands to different
users. Attaching it to players is not good enough: the information must
users. Attaching it to players is not good enough: the information must
survive the addition and removal of other players, the start or restart
of a game, reconnections by the same user even from different computers,
or transferral of the game to a different server. However, a user
or transferral of the game to a different server. However, a user
may have different levels of access in different games.
While they last, connections are sufficient identification for users.
......
Ideally, users would be identified with unique global ids, handed out
by a 'registry service' similar to the metaserver, but this would be
too cumbersome in practice. So the plan is to make users persist in
too cumbersome in practice. So the plan is to make users persist in
a server session (even whan a game is started, or restarted when that
option is added) and make them persist across games (when a saved
game is loaded in a different server session).
Users will be created when they first connect to a server, remembered by
the running server and in savefiles. Upon connecting, the client will
the running server and in savefiles. Upon connecting, the client will
be sent a unique session id, generated when the server started, plus a
fresh user id; it will store them in a ~/.civcookie file, and send it
back when trying to reconnect. This will allow the identity of users
to be protected. 'Protected' players will only allow the same user to
back when trying to reconnect. This will allow the identity of users
to be protected. 'Protected' players will only allow the same user to
reconnect; 'unprotected' ones allow anyone to connect; server commands
and probably client options will be available to control this.
......
----
THE PRESENT IMPLEMENTATION:
Currently access levels are stored in the connection struct. This allows
Currently access levels are stored in the connection struct. This allows
access levels to be assigned to each individual connected player, which
would not be the case if they were directly assigned to the player struct
(due to the fact that the players array changes when players are added or
......
But that's it.
Players are still created before the game is started, and player names
still belong to players. Access levels exist in client and server,
but only the server uses them. User ids are not yet implemented;
still belong to players. Access levels exist in client and server,
but only the server uses them. User ids are not yet implemented;
Server ids do not exist at all.
Commands to protect/unprotect users do not yet exist; they would serve
......
'player' means a civilization, see above), where each connection may
be either an "observer" or "controller".
This discussion is mostly about connection in the server. The client
This discussion is mostly about connection in the server. The client
only has one real connection (client.conn) -- its connection to the
server -- though it does use some other connection structs (currently
pplayer->conn) to store information about other connected clients
......
In the old paradigm, server code would usually send information to a
single player, or to all connected players (usually represented by
destination being a NULL player pointer). With multiple connections
per player things become more complicated. Sometimes information
destination being a NULL player pointer). With multiple connections
per player things become more complicated. Sometimes information
should be sent to a single connection, or to all connections for a
single player, or to all (established) connections, etc. To handle
single player, or to all (established) connections, etc. To handle
this, "destinations" should now be specified as a pointer to a struct
conn_list (list of connections). For convenience the following
conn_list (list of connections). For convenience the following
commonly applicable lists are maintained:
game.all_connections - all connections
game.est_connections - established connections
......
pplayer->connections - connections for specific player
pconn->self - single connection (as list)
Connections can be classified as follows: (first match applies)
Connections can be classified as follows: (first match applies)
1. (pconn->used == 0) Not a real connection (closed/unused), should
not exist in any list of have any information sent to it.
......
2. (pconn->established == 0) TCP connection has been made, but initial
Freeciv packets have not yet been negotiated (join_game etc).
Exists in game.all_connections only. Should not be sent any
Exists in game.all_connections only. Should not be sent any
information except directly as result of join_game etc packets,
or server shutdown, or connection close, etc.
(All following cases exist in game.est_connections.)
3. (pconn->player == NULL) Connection has been established, but is not
yet associated with a player. Currently this is not possible, but
yet associated with a player. Currently this is not possible, but
the plan is to allow this in future, so clients can connect and
then see list of players to choose from, or just control the server
or observe etc. Two subcases:
3a. (pconn->observer == 0) Not observing the game. Should receive
3a. (pconn->observer == 0) Not observing the game. Should receive
information about other clients, game status etc, but not map,
units, cities, etc.
(All following cases exist in game.game_connections.)
3b. (pconn->observer == 1) Observing the game. Exists in
game.game_connections. Should receive game information about
3b. (pconn->observer == 1) Observing the game. Exists in
game.game_connections. Should receive game information about
map, units, cities, etc.
4. (pconn->player != NULL) Connected to specific player, either as
"observer" or "controller". (But observers not yet implemented.)
"observer" or "controller". (But observers not yet implemented.)
Exists in game.game_connections, and in pconn->player->connections.
......
Macros and inline functions
===========================================================================
For a long time Freeciv had no inline functions, only macros. With the
For a long time Freeciv had no inline functions, only macros. With the
use of other C99 features and some new requirements by the code, this has
changed. Now both macros and inline functions are used.
changed. Now both macros and inline functions are used.
This causes problems because one coder may prefer to use a macro while
another prefers an inline function. Of course there was always some
another prefers an inline function. Of course there was always some
discretion to the author about whether to use a function or a macro; all
we've done is add even more choices.
Therefore the following guidelines should be followed:
- Functions should only be put into header files when doing so makes a
measurable impact on speed. Functions should not be turned into macros or
measurable impact on speed. Functions should not be turned into macros or
inlined unless there is a reason to do so.
- Macros that take function-like parameters should evaluate each parameter
exactly once. Any macro that doesn't follow this convention should be
exactly once. Any macro that doesn't follow this convention should be
named in all upper-case letters as a MACRO.
- Iterator macros should respect "break".
......
The data_encoding is used in all data files and network transactions.
This is UTF-8.
The internal_encoding is used internally within freeciv. This is always
UTF-8 at the server, but can be configured by the GUI client. (When your
The internal_encoding is used internally within freeciv. This is always
UTF-8 at the server, but can be configured by the GUI client. (When your
charset is the same as your GUI library, GUI writing is easier.)
The local_encoding is the one supported on the command line. This is not
The local_encoding is the one supported on the command line. This is not
under our control, and all output to the command line must be converted.
===========================================================================
    (1-1/1)