patch for cost functions - by rp@win.tue.nl 1. Introduction The idea: allow costs to vary with players. Costs include the costs to build improvements (incl. wonders) and units, and the relative cost of researching techs. Costs are stored in separate objects called 'cost functions' (I can't think of a better name, 'player profile' would be reasonable). During the game, a cost function is associated with each player. Instead of being fixed (in the case of relative tech costs, all 1), the cost for a player to build a unit or improvement, or to develop a specific technology, will be looked up in the player's cost function. 2. Purpose The purpose is to allow players to be handicapped, and to allow them to assume specific characteristics. This is especially useful for AI players. For instance, there can now be militaristic AI and technology oriented AI, simply by varying the costs of military units and various techs across the races; barbarians are AI with infinite settler costs; strong humans can compete with newbies by assuming a strongly handicapped player profile; etc. The *behaviour* of the AI probably doesn't vary yet; it probably won't behave more aggressively when its aggressive units are cheaper to build. The idea to allow different AI behavours should be tackled independently. Humans too will require some time to learn how to cope with non-default costs. It would be nice if players would experiment with them for a few months; we could then set up a system of handicaps and ratings. 3. Implementation plan. Each subsection is a separate patch; this makes it easier for me to maintain the code against the changing CVS code. Every patch is against the original (source as of Dec 28, which is probably equal to 1.7.2.). 3.0 teach server always to read $HOME/.civserverrc (before -r file) Allows me to avoid having to specify -r every time. Basically unrelated, but I want it in anyway. Done (the patch has been posted to freeciv-dev, civserverrc-diff-cr). 3.1 teach server to use costfunctions based on player name This is server-side only in principle, but most of the code is actually in common/. It must work with unpatched clients! 3.1.1 introduce private cost functions into the code Every call to costs in the server is now rerouted to use a player's private cost function, if defined; this must work with unpatched clients! In order to do this I've had to make the following changes: 1) privatise common/game.c:improvement_types[] which was exported for no reason; I had to move set_building_req() to city.c and export it back; all its other uses are replaced with calls to existing access functions; 2) add an extra argument to improvement_value() (the player) 3) add common/costs.[ch] involves changes to Imakefile, Makefile.noimake, common/Makefile.am, and common/Makefile.in (to avoid clutter from rerunning automake) this makes it easier to maintain the patch against the developing CVS tree; only city.c will use it, if all is well 4) modify common/city.c to use it 5) add a new 'costs' field to struct player which is empty if no cost function is defined 6) some code cleanup to avoid misunderstandings in the future (removed get_improvement_types(), added access functions improvement_*(), renames get_improvement_name() to improvement_name()) At this point, nothing ever sets a nonempty 'costs' field, so the net effect is zero, but I need this stage for easy maintenance. Done. (Patch is available as costs-per-player-intro.diff-ur.) Only tested in one game. 3.1.2 introduce a format for costfunctions for use in .civserverrc and -r files, and teach the server to read it at startup This is based on fixed player names: everyone connecting as 'Hammurabi' will get Hammurabi's special cost function, or if none is defined, the default. After this patch, cost functions are available; all the rest is just there to improve their useability. The names of cost functions must be all alphanumeric (isalnum()). The new commands are as follows: cost in costfunc1 # declares the current cost function to be 'costfunc1'; future # cost assignments will affect this function; when first mentioned, # it is initialised with the default values cost for nouja # assigns the current cost function to the player 'nouja' cost in costfunc1 for nouja # combined statement cost musketeers 20 # sets the cost to build musketeers to 20, for the current function cost musketeers 20 in costfunc2 # id., but to an explicitly mentioned function cost musketeers 20 for nouja # invalid, costs cannot be directly assigned to player names cost barracks 90 cost barracks 90 3 # sets the cost of barracks; in the second form, their upkeep too cost monarchy 0.25 # monarchy can be discovered four times as quickly as usual In general, the allowed syntax is cost [is CF] [for PL] cost [UNIT NUM | IMP NUM [NUM]] [in CF] where CF is an alphanumeric string (a cost function name), UNIT is the name of a unit type, IMP is the name of an improvement (or wonder), NUM is a nonnegative integer, and PL is a player name (not necessarily of an existing player). Within UNIT, IMP and PL, spaces must be represented as underscores. This poses as yet unsolved problems for players with underscores in their names. In order to implement this patch, I've had to modify server/stdinhand.c:handle_stdin_input() to accept command lines with multiple arguments; I decided to do a full rewrite and also implement - comments as postfixes for valid command lines - accepting prefixes of commands (VMS style) - accepting prefixes of server variables - accepting player names with whitespace as part of commands - a 'read' command to read in commands from a file (this was 7 lines of code) This is an improvement in its own right and it should probably be issued as a separate patch. The 'cost' command has been moved into another new module: server/costcommand.[ch] There are also some additional functions to match unit and improvement types by prefix. A version of this patch has been completed that works for improvements only, and only for AI players (safeguard; the client is still assuming default costs at this point). The documentation is still absent (explain, client help). This patch is available for testing as privcosts4ai+stdinhand.diff-Nur.gz It will be extended to cover units, technologies and help, once I get some feedback from other Freeciv players. 3.2 allow the client to inspect cost functions Allows the client to obtain all cost functions defined in the server. This is (mostly) a client-side patch; it must be implemented in such a way that clients and servers remain compatible with unpatched counterparts. Not sure if a new type of packet is required. 3.3 allow the server to set options and store them to file 3.3.1 add a 'read file' command to read options when the server is running Already part of the above patch, together with some related improvements. 3.3.2 add a 'write file' command to save all options from the running server 3.3.4 add a 'autowrite file' option to automatically save options whenever a change is made 3.4 include cost functions into savefiles The server will still be able to read 'old' savefiles, but old servers won't be able to read the new format I'm afrais. 3.5 allow clients to set server options 3.5.1 allow server_info packets to go from client to server This patch must work with unpatched clients/servers. Server variables include cost functions (if 3.1.3 introduced its own packet type, they are sent separately). Info may be partial, in which case the server defaults will be left untouched. 3.5.2 patch the client UI to allow server variables to be set 3.5.3 add a 'master player' server option This server option allows the mentioned player to modify server variables, including the 'master' settings. 3.5.4 allow clients to read server options from file ? Just an idea. 3.6 (maybe sooner) Add an initial_units function that lists the player's initial bag of units. Treat it in the same way. Generalizes the 'settlers' and 'explorer' options.