"Units in Units" describes the concept of one (mobile) unit entering another unit. This concept is currently (2006/11/21) under development and this page aims at describing the current state.
Note that this page will NOT be kept up-to-date with the boson code. I merely try to explain the basic concepts, that I hope will remain valid for quite some time. Definite answers will be in the code only (in particular some of the diagrams I have drawn are already slightly out of date, even before the code was committed).
In a "units in units" scenario there are always at least 2 units involved:
- the "entering unit" and
- the "storing unit", also referred to as the "storage".
The entering unit can be any mobile unit and is implemented by the EnterUnitPlugin.
The storing unit must have a UnitStoragePlugin. The properties (UnitStorageProperties) of this plugin describe
- how many units can enter the storage
- how a unit can enter the unit (i.e. the enter paths)
- what kind of unit (in particular: plane/helicopter/land/ship unit) can enter the storage
Some examples of storing units:
- factories (units usually "enter" this storage only by being produced)
- possibly repair pads
- airport
- helipad
- possibly mines and refineries
- ammunition storage
- transportational units
From this list it is obvious that any implementation of "UnitsInUnits" must be pretty sophisticated if we want to cover them all. Some sample problems that should be covered:
- both sides (entering and storing units) should support animations (e.g. factory opening/closing its doors ; airport turning engines on/off)
- aircrafts must be able to change their z position when landing
- collisions between both units must obviously be allowed by the movement code
- ideally collisions between all units inside a unit should be allowed (but avoided whenever possible) too: otherwise the whole problem becomes extremely difficult: pathfinding and especially error handling specifically for UnitsInUnits would be required.
- while a unit is entering/leaving other units must not be allowed to enter/leave - at least not on the same path
- a unit leaving the storage should trigger any unit that is blocking the exit to "move away"
- alternatively, it must be able to "go trough" obstacles, until a "free" area is reached. this is required so that the leaving code will leave the unit in a usable state, not on top of a different unit, where they both might block each other forever
- a transportation unit must stop moving before a unit can enter/leave it, and it must not move while a unit is entering/leaving.
- once a unit started entering/leaving, usually it must not be possible to abort that process: think in particular of an aircraft that is currently landing or starting and by aborting may suddenly "hang in the air"
- planes must be able to enter, without having to "wait" on a certain point until the entry is free (planes can't stop moving while in the air)
- ...
The current code tries to address most or even all of these issues. Keep in mind (see above) that when you read this, the code is certainly already more up-to-date than these pages.
The code is essentially divided into two parts
This distinction has proven to be highly useful and simplifies the problem a lot.
Note that there are some limitations of the current implementation that may be difficult to overcome:
- At most one unit may enter/leave a storage at the same time. This is due to the fact that both plugins are implemented as state machines, which become much more complicated, if several units can enter/leave at the same time. This limitation might be addressed by having multiple storage plugins in a storage unit (however see also below)
- There are situations where we want multiple units to enter/leave a storage at the same time: think of e.g. airports with multiple (parallel) runways.
- Since the storage is implemented as a UnitPlugin, it can (currently) have a single instance per unit only. This is not a strict design limitation of UnitPlugin, however at the moment this limitation does exist, so having multiple units enter a single unit at the same time can't easily be implemented this way.