Some preliminary ideas on how to have more sophisticated "events"[]
Background[]
Civ2 had a simple scripting system for putting events into scenarios. One possible goal would be to emulate the civ2 event system, perhaps even to make civ2 scenarios compatible with Freeciv.
We have events, actions, and triggers[]
- An event is already defined in freeciv. See events.h. However this will have to be improved so that each event is more clearly defined.
- An action is something that can be triggered by an event. We must have a well-defined list of actions with support in server and client. The simplest possible action might be to pop up a window with a message (just as events do now!).
- A trigger is something that the scenario (either the savegame or events.ruleset or both) uses to connect events to actions with some conditional. A trigger says "if this event happens and meets these conditions, trigger this action".
Terminology between civ2 and Freeciv differs. This will certainly cause confusion, as same words are used in different meanings.
- Freeciv Event is what civ2 people call Trigger
- Action seems to have same meaning in both worlds
- Closest equivalent to Freeciv Trigger in civ2 world is Event
Events[]
- For a list of the events we have now, see events.h.
- WANTED: A list of events in civ2.
Actions[]
- WANTED: A list of actions in civ2.
Triggers[]
- WANTED: A list of triggers in civ2.
Problems[]
- Long-term, the biggest problem is making the AI deal with triggers and actions. As long as the actions are simple ("display a message") there is no problem. But if there is a "Victory" action then the AI needs to know about it and understand what will trigger it.
- [Technical] There is a problem with resolving triggered actions. Often an event happens deep inside the code, inside nested iterators, and doing some drastic action there may screw up the lists. So we need to defer actions until we have returned to the top level code.
A possibly good solution[]
Using an effects ruleset like format would make things really ugly for the event file writer. It is too rigid and verbose in the sequence of actions allowed.
You want to at least allow if nesting in it, otherwise things get messy real soon if you want to do something a bit more complex. You also want to have a way to get data from the event.
The best event system I have seen is something similar to how GTK+ works. Each event type has a list of functions associated. Each function receives data parameters describing the event, a possible return type and has a sequence of instructions of a more well formed language. Which for GTK+ means C.
The code for a good event system is something like this: When an event happens, it doesn't actually get executed. It gets put into an event queue.
Eventually the code goes back into the main event loop and executes the events in order.
We should use Lua, for several reasons already discussed in the list. Angband also uses Lua for events, like we intend to, you can see an example of that here.
Here is an example of a possible notation for the event callbacks mentioned before:
Lua[]
-- the 'unit' argument has data for the unit entering the hut. function unitHutCallback(unit) createUnit(unit.tile, "Hut") end
function cityHutCallback(unit) createCity(unit.tile) end
function specialHutCallback(unit) owner = unit.owner if math.random(0, 100) < 20 then if hasTech(owner, "Industrialization") and not hasBuilding(owner, "Michelangelo's Chapel") then getGold(owner, 50) getTech(owner, "The Wheel") getTech(owner) end end end
You can find a work in progress specification of the user-side API for events in Events specification.
Another suggestion from Warcraft III[]
You should take a look at the Warcraft III trigger editor, which is part of the World Editor. Most of the principles apply to Freeciv as well. It is much more usable than any scripting-language will ever be.
Each trigger function is devided into Events, Conditions, and Actions, and they can be customized easily using the Trigger Editor.
Greetings, Andreas R.
Use for natural disasters[]
If the Freeciv engine implemented events that had triggers depending on terrain and a random trigger, we could implement natural disasters. The original Civilisation board game had these. If we added a tile_special_type of S_DANGEROUS, we could have some tiles that were particularly dangerous to be near. For example, a Mountain marked as S_DANGEROUS could indicate a volcano.