Enumerating Content
Basic Concepts
Extensions want to add new content like planes or scenarios. These must be enumerated to UAW: the extension must make UAW aware of whatever content it can provide. UAW will present choices to the user and may eventually come back to the extension with the wish to actually instantiate some of this content.
Rationale
Forcing extensions to be passive avoids a common problem with one mod taking over
the whole game.
Rationale
This declarative way makes on-demand loading possible.
Enumeration takes place when UAW loads an extension. It is the primary function of the UAW_API_Extension interface that an extension receives during loading.
Extensions should keep their initialization work to a bare minimum. They should stick to enumerating content instead of actually loading it. We acknowledge that this may not always be possible, so heavy initialization work is not forbidden per se. Please be reasonable!
Rationale
Extensions may not always have full control over their data layout, especially when they form bridges to other games. It may be necessary to search folders or to extract archives just to get a glimpse of what content can be provided. That’s unfortunate, but it’s the reality.
Rationale
It is always better to load resources on-demand. If your extension adds ten planes to the game, then it is very unlikely that the player will fly all of them in every session. Any work on loading them will likely be wasted.
Any useless work during initialization will delay the start of the game and frustrate the user!
Extensions are isolated from one another. While extensions can enumerate scenarios containing their own planes, they cannot force their planes into scenarios enumerated by other extensions.
Rationale
There is no other sane way to avoid conflicts.
UAW will, however, offer users a choice to mix content.
Rationale
Otherwise, users could not fly a plane from an extensions unless this extension also provided a scenario to fly it in.
Rationale
The interfaces and protocols in this API provide enough abstraction to make this possible.
Rationale
It’s fun!
Identifiers
When extensions refer to content like planes or scenarios, they must do so via IDs.
IDs are 32-bit numbers.
Rationale
Every programming language supports them.
Rationale
Numbers are superior to strings or globally-unique identifiers by an order of magnitude in both speed and memory.
It is fully up to the extension to decide numeric values of IDs. The ID of a plane could be 0, 0xf22, or 4294967295. UAW does not care.
Rationale
Drastic complexity reduction in extensions: all IDs can be constants instead of opaque numbers, as handles or pointers would be.
IDs are used for different things:
- UAW_Extension_StringID
- See Strings.
- UAW_Extension_CartridgeModelID
- Identifies a kind of cartride (e.g.
5.56×45mm NATO
).
- UAW_Extension_CannonModelID
- Identifies a kind of cannon (e.g.
M61 Vulcan
).
- UAW_Extension_EngineModelID
- Identifies a kind of engine (e.g.
F119-100
).
- UAW_Extension_VehicleModelID
- Identifies a kind of vehicle (e.g.
Lada Niva
or Starfighter
).
- UAW_Extension_TerrainID
- Identifies a terrain.
- UAW_Extension_ParticleEffectID
- Identifies a kind of particle effect (e.g.
big explosion with glowing fragments
).
- UAW_Extension_ScenarioID
- Identifies a scenario.
All these kinds of IDs must be unique within an extension and within their current domain, but they do not need to be globally unique.
I.e. two extensions could both use the ID 16 for one of their planes. UAW knows which extension it is talking to and has no problems telling them apart.
Rationale
Drastic reduction in design complexity for extensions.
Rationale
Makes conflicts with other extensions impossible.
An extension could use the ID 0 for a string as well as a vehicle or a terrain. UAW can tell them apart from context.
Rationale
Drastic reduction in design complexity for extensions.
Rationale
Enables to easily use lookup tables.
The UAW_API_Extension Interface
The main function of an extension receives a parameter struct UAW_API_Extension * api (see Creating a Dynamic Library). This is the context-dependent interface for extension initialization. It offers the following methods:
- int newParticleEffect(UAW_ParticleEffectSpecs const *)
- int newJetEngineModel(UAW_JetEngineModelSpecs const *)
- int newCartridgeModel(UAW_CartridgeModelSpecs const *)
- int newCannonModel(UAW_CannonModelSpecs const *)
- int newVehicleModel(UAW_VehicleModelSpecs const *)
- int newTerrain(UAW_AvailableLevel const *)
- int newScenario(UAW_AvailableScenario const *)
All of these methods expect a pointer to a data structure describing the respective resource, and they return a non-zero value if successful.
In order to initialize a particle effect, an extension would:
- instantiate the UAW_ParticleEffectSpecs structure;
- fill id with a numeric value of its choice (as long as it’s unique among particle effects in this extension and all later references use the same value);
- fill name with a string ID that returns the name of the effect when passed to the extension’s string callback;
- fill duration with the maximal duration of the particle effect (in seconds);
- fill in callbacks (if needed);
- call newParticleEffect() on this structure.
All but the last step can be done statically during compilation of your program (given that you don’t have to search any files to find the particle effect).