Adding a Script API
Using ScriptGlobal (whole-game-aware AI API) implemented in this project as a template, this describes the complete steps to add a new script API class (visible to AI and GameScript) in jrpm.
Background
- Script API classes are located in
src/script/api/:script_<name>.hpp(declaration) +script_<name>.cpp(implementation); .hppis auto-discovered by the build-timefile(GLOB script_*.hpp)and generates Squirrel bindings (ai_*.sq.hpp/gs_*.sq.hpp), no manual class registration needed;.cppmust be added to thesrc/script/api/CMakeLists.txtsource list.
1. Header File script_global.hpp
cpp
/** @file script_global.hpp Documentation comment. */
#ifndef SCRIPT_GLOBAL_HPP
#define SCRIPT_GLOBAL_HPP
#include "script_object.hpp"
#include "script_company.hpp"
/**
* Class documentation, must include @api.
* @api ai game # Exposed to both AI and GS; "game" for GS only; "-ai" excludes AI
*/
class ScriptGlobal : public ScriptObject {
public:
/** Enum will be exported as class constants (e.g., AIGlobal.VT_TRAIN). */
enum VehicleType {
VT_TRAIN = ::VehicleType::Train,
VT_AIRCRAFT = ::VehicleType::Aircraft,
};
/** @api ai game */
static bool IsGlobalAccessAllowed();
/** @api ai game */
static SQInteger GetCompanyCount();
/** @api ai game */
static std::optional<std::string> GetCompanyName(ScriptCompany::CompanyID company);
};
#endif /* SCRIPT_GLOBAL_HPP */2. Implementation script_global.cpp
cpp
#include "../../stdafx.h"
#include "script_global.hpp"
#include "../../company_base.h"
// ...
/* static */ SQInteger ScriptGlobal::GetCompanyCount()
{
if (!IsGlobalAccessAllowed()) return 0;
SQInteger count = 0;
for (const Company *c : Company::Iterate()) count++;
return count;
}Key points:
- All methods are
static, defined with/* static */prefix; - Return types use Squirrel-friendly types:
SQInteger,bool,Money,std::optional<std::string>,std::string,ScriptList*, etc.; - Access control: check
ScriptCompanyMode::IsDeity() || setting toggleinside methods, return error value if not satisfied.
3. List Class (Optional)
For returning lists of companies/items, define a ScriptList subclass:
cpp
class ScriptGlobalCompanyList : public ScriptList {
public:
#ifdef DOXYGEN_API
ScriptGlobalCompanyList();
#else
ScriptGlobalCompanyList(HSQUIRRELVM vm);
#endif
};cpp
ScriptGlobalCompanyList::ScriptGlobalCompanyList(HSQUIRRELVM vm)
{
ScriptList::FillList<Company>(vm, this);
}4. Register in Build
Add to src/script/api/CMakeLists.txt source list:
cmake
script_global.cppTIP
.hpp does not need registration (GLOB auto-discovers); but reconfigure CMake to see the bindings generated from the new .hpp.
5. Usage in Scripts
js
// AI side: class prefix AI
AIGlobal.GetCompanyCount();
AIGlobalCompanyList();
// GS side: prefix GS
GSGlobal.GetCompanyCount();Completion Checklist
- [ ]
script_<name>.hpp(with@apiannotation) - [ ]
script_<name>.cpp(implemented with/* static */) - [ ]
CMakeLists.txtadd.cpp - [ ] Reconfigure + build
- [ ] (Optional) Example script in
bin/ai/