Civ5 API Reference FAQ

From Civilization Modding Wiki
Revision as of 18:18, 19 September 2012 by DonQuich (talk | contribs)
Jump to navigationJump to search

Types terminology

  • unknown
This parameter's type could not be identified.
  • string
A Lua string.
  • int
Any integer.
  • float
Any number, integer or floating-point.
  • table
An unidentified table. Look at the code samples to figure it out by yourself.
  • table(key => value)
A table whose keys and values have the specified types.
Example: table(PlayerID => Player) players
It can be enumerated with: for playerID, player in ipairs(players) do
The following will return a Player: players[0]
  • iterator(key => value)
To be used in a for... in... loop.
Example: iterator(UnitID, Unit) Units()
It can be enumerated with: for unitID, pUnit in Units() do.
  • variant
This parameter can be assigned with different types.
Example: DB.Query(variant arg)
This function can accept a string or a table.


Object-oriented concepts in Lua

The concepts below originate from object-oriented languages. But since Lua is weakly typed, it offers richer possibilities than those languages. As a result those concepts may sometimes lack relevance and may need to be adapted or broaden. However they're still adequate since most of the API reflects the types defined in C++ by Firaxis.


Instance versus static types

  • Instance types can be instanced, such as Player.
  • Static types exist as a single global variable, such as Game.
  • Some types can be both, such as InstanceManager: a global variable exists with this name and calling its new method creates a new instance of InstanceManager.


Functions versus methods

  • We call method any function stored as a type member.
  • This is purely aesthetic: a function and a method are both called and used in the same way. We could store a method in a local variable and use it as a function.


Instance methods

  • They are methods that require the caller to be passed as the first argument.
  • The colon (:) operator implicitly passes the caller as the first argument. Those two expressions are equivalent: caller.somefunc(caller, arg) and caller:somefunc(arg)
  • When declaring methods, the caller is referenced as the self keyword. It can be explicitly defined or not, see Lua introduction for confirmed developers.


Events

  • Events in the civ5 API can be (un-)subscribed this way: Events.SomeEvent.Add(Handler) and Events.SomeEvent.Remove(Handler)
  • They can be invoked that way: Events.SomeEvent(arg1, arg2)
  • Events typically do not expect any return type. But the ones in GameEvents usually expect an integer or a boolean, see their documentations.


Reliability of the documentation

All listed functions exist.

But some of them may be malfunctioning. Ghost functions have been removed by checking the binaries strings tables.

Some functions may not be listed.

Only the methods that can be enumerated by a Lua code, the ones mentioned on the 2k wiki, and the ones used by the Lua source code from Firaxis are listed. A few additional functions found in the binaries have been added but this scan is quite superficial.

Some functions could have hidden arguments/return types.

There could be additional arguments not listed because they were never used or documented by Firaxis.

Some functions arguments could be actually optional.

Reciprocally, some of the arguments listed could be optional: Firaxis always used them.

Arguments' default values are not reliable.

They are mostly here to notify you that an argument is optional. While nil is always an acceptable value to provide in such a case, a nil for a boolean will probably be interpreted as false (but it could be true) and an integer as 0 (but it could be anything else).

The arguments' types and returned types are not always reliable.

While a lot of efforts were done to ensure the typing is reliable, this problem cannot be solved unambiguously. The balance compromise reliability and completeness is quite good but it could still be improved and, anyway, it cannot be perfect without human corrections.

Most of those types are only here for documentation purpose

The structures and identifiers are never mentioned anywhere in the API, they have been introduced for documentation purposes only. Lua and the API just treat them as tables and integers although the structure obviously have C++ counterparts. This also means there could be additional structures we forgot.


Pages generation process

The initial versions of those pages were automatically generated by a written in C# by User:DonQuich.

Here are the first steps of this bot:

  • We manually define the existing type names and their natures (identifier, structure, etc)
  • The 2kgames wiki is scanned. It is sparse, the types are rarely mentioned and the informations are sometimes incorrect or obsolete.
  • Manual fixes are applied to core functions that allow type inference cascades.
  • Two lua dumps (with and without G&K) are scanned to collect members. They have been generated by a home-brewed mod that outputs the members on all types, enumerations and their metatables.
  • The binaries are scanned again to detect additional functions for a few types. The process is rudimentary and does not collect many informations.
  • The database files are scanned, this will be used to infere types from calls to GameInfos and such in the game source code.
  • The binaries (dll and exe) are scanned to search for all the strings they contain. If a function's name does not appear in those tables, it means it no longer exists. This is the primary source to detect methods that have been removed (from the base game and/or G&K) and while simple it is very reliable.


Then we parse the Lua and UI source files from the base game, G&K and most DLC. This step produces an inference graph and assemble the code samples.

  • The inference graph is a bastardized version of a minimalist AST (abstract syntax tree) and it represents type equations. Things like: argument 0 in SomeType.SomeFunc is assigned by the third return type of OtherType.OtherFunc, and also by....
  • The inference graph is solved or order to infer all the arguments and return types. During this process we also update the arguments name, we detect unknown functions and arguments, new events, structures' fields, etc. This is the main information source and the most important step.
  • The whole process is smart and implements its custom version of the VFS to manage includes. It manages to test all the possible combinations of different file versions depending on which DLC and expansions are enabled.


Finally, the whole API is known and the type system complete.

  • We then import custom documentation patches: manually written texts to include in some of the generated pages.
  • Finally we consolidate everything and we categorize the methods according to the keywords found in their names.
  • We upload the new wiki thanks to the DotNetWikiBot library.