Introduction ============ This is the result of an effort to construct an interface for client side ai for the freeciv game. The standard ai of freeciv is build into the server. This has some disadvantage: only one ai implementation is possible, cheating, no way to distribute the usage of resources. Client side ai is an attempt to alleviate some of the problems above. It consists of the interface, an implementation of this interface and a sample client written in c. Design ====== The ai code should be freed of any stuff which is not needed. Almost every language should be usable. (C, C++, Perl, Python, GUILE, Scheme, Java,...) Allow the ai to access all data in a painless way. The ai code should be seperated into an interface to the ai logic and the ai logic itself, which should be easily exchangabe. Thus a clean interface is needed. Mind that this interface is bidirectional. While the server triggers ai actions, the ai needs (possibly restricted) access to the current environemnt. The guidelines for the design of the interface were the usual goals wrt to software design: - consistency, - simplicity and - decoupling from the network For most decisions there are not enough information in a packet from the server. It is also not feasible to ask the server about everything. The classical caching approach should help here. It is easier to do this in scripting languages but it is also not sensible that everyone implement their own cache. So the cache is provided in the general framework. Ultimately the design can be broken up as follows: - network layer - caching layer - communication layer - language adaption layer - control code layer The interface for the network and caching layer is fixed. It will be called CSAII for "Client Side Artificial Intelligence Interface" The network layer handles receiving and sending of packets. The caching layer stores information of different types (cities, units, terrain types,...) from the server for exactly one control code layer. The communication layer follows a forwarder / proxy scheme. It provides the CSAII to the upper layer and forwards all requests/function calls to the logic implementation. The communication layer can be a noop for the local case. It is also possible to forward requests per IPC/pipes/sockets using different protocols (e.g text based protocol, a binary protocol (like the one between the server and the client) or CORBA). If the control code layer is not written in C the language used may need some code to map between C functions/data and the constructs of the language. For C this layer is a noop; The control code layer is the part where the "real ai" resides. As mentioned it can be written in any language as long as a language mapper is available. It uses the CSAII to interact with the lower layer and so indirectly with the server. Big picture at runtime ====================== The control code layer starts. It loads the language adaption layer (e.g. import in Python) Then the other layers are started. After registering callbacks using CSAII the control code layer gives the control to the network layer. The control code layer will be notified from the network layer via callbacks. In such a callback the control code can make a decision and use the CSAII to inform the server. Version 0.1 =========== Like the version number suggests this version is a rough first sketch. It includes the basic part of the CSAII and the implementation thereof. It also includes a simple control code layer example. It is written in C and so lacks the language adaption layer. The client does: - starting the client and connecting to the server - game start stuff (select nation, rulesets) - build cities - move units around - research - change of government - actions to cities (buy, change, rename) So these functions are supported in the network and caching layers. There is also long list of TODOs: - complete the review of the interface and implement the missing functions to enable: * terrain improvements * spaceship * ... - implement a client in Python or Perl as simple as the one in C - better support for versions of the same control code layer which use different sets of parameter - at the time there is no build system. I don't know much about autoconf and automake. - move the main function to client.c - gets rid of "extern struct civ_game game" - is_uptodate to mark an object (unit, city) which was visible some time ago, but the data is now not accurate. (A enemy town of size 6 doesn't vanish if it get fogged) - ... Open questions ============== Is some kind of parallel execution needed? (There are at least two reasons for parallel execution: performance and up-to-date data) IMHO yes in the long run. Problem: during a longer calculation the control code layer wants the current data Possible solution: 1) the network and cachng layer update the data asynchronously. New problem: the control code sees some old and some new data. Solution: locking of every access. IMHO ugly 2) the control code layer gives execution to the network layer. If there are packets they will be handled in normal fashion. If there no more packets the call returns. The control code layer knows when something has changed. 3) more loose coupling: no shared objects. All data is got through function calls and is only a very short time valid. (How long is short time?) 4) more loose coupling2: no shared objects. The network layer send only the callback and then the control code layer copies the data No feedback problem There are situations were the client gets no feedback: the control code layer wants to move a unit. If the server code decides that the requested move is not valid there is no feedback to the client. So no callback in the control code layer can be called. This is not a problem for a human player. One solution for a client side ai: the network layer sends after the request_move packet a request_unit_info packet. Worklist and private_data Problem1: The control code layer needs to associative some private data with some objects. (city types to a city, bodyguard relationship for a unit, schedule for a ferryboat,...). The worklists are some kind of this for cities. But also units needs this, so worklists are totally excluded. The control code layer can manage its own data structures for this. But we have a cache of all objects already. So I think a data hook in every object is needed. This private_data field would be opaque for the cache. Problem2: the data has to be stored somewhere. Best place would be the savegame but this is server side. Other possibilities: control code layer or cache layer. The cache layer would need a pointer to the data and the length. Implementation ============== The network layer consists of an unchanged common/packets.[ch] The caching layer are files from common and client which are rearranged and modified. So there is not much new code. But a lot of changes were necessary to implement the CSAII. Code which got modified was taken from freeciv 0.11.0. The code depends on glib. Under impl/priv_*.h are functions and data declared which can be accessed from other priv_* code but not from the control code layer. Author ====== Raimar Falke