I’m working on a closed-source C++ application: an OpenGL-based simulation game with aircraft (friendly and enemy). I want to integrate autonomous behaviors such as Hierarchical Task Networks (HTN) to handle complex planning like:
- Assaulting an enemy.
- Following an enemy aircraft.
- Coordinating a platoon for team attacks.
I want the application to support plugins for these autonomous behaviors, enabling users to dynamically change or add new behavior without modifying the core application.
To achieve this I have tried the method below:
Aircraft Class
class Aircraft {
public:
// Constructor
Aircraft(const std::string& name, float speed, float altitude);
// Member functions to simulate behaviors
bool FollowTarget();
bool AttackTarget();
bool AvoidTarget();
// Utility functions
void setSpeed(float speed);
float getSpeed() const;
void setAltitude(float altitude);
float getAltitude() const;
const std::string& getName() const;
private:
std::string name; // Name of the aircraft
float speed; // Speed in units
float altitude; // Altitude in units
};
AircraftAPI Class
class AircraftAPI {
public:
// Exposes Aircraft's FollowTarget method
static bool FollowTarget(Aircraft* aircraft);
// Exposes Aircraft's AttackTarget method
static bool AttackTarget(Aircraft* aircraft);
// Exposes Aircraft's AvoidTarget method
static bool AvoidTarget(Aircraft* aircraft);
// Utility methods for setting and getting properties
static void SetSpeed(Aircraft* aircraft, float speed);
static float GetSpeed(Aircraft* aircraft);
static void SetAltitude(Aircraft* aircraft, float altitude);
static float GetAltitude(Aircraft* aircraft);
static const std::string& GetName(Aircraft* aircraft);
};
Plugin Interface
class IPlugin {
public:
virtual ~IPlugin() = default;
virtual bool initialize() = 0;
virtual void update(float deltaTime) = 0;
virtual void cleanup() = 0;
virtual std::string getName() const = 0;
};
AttackPlugin Class
// AttackPlugin class
class AttackPlugin : public IPlugin {
public:
AttackPlugin(Aircraft* aircraft) : aircraft(aircraft), attackCooldown(0.0f) {}
bool initialize() override {
return aircraft != nullptr;
}
void update(float deltaTime) override {
attackCooldown -= deltaTime;
if (attackCooldown <= 0.0f && aircraft) {
AircraftAPI::AttackTarget(aircraft);
attackCooldown = 3.0f;
}
}
void cleanup() override {}
std::string getName() const override {
return "AttackPlugin";
}
private:
Aircraft* aircraft;
float attackCooldown;
};
NOTE: This is not my actual code It's just for an example. My methodology is similar. How can I make my application independent of Attackplugin
I want to expose a C++ API to interact with the game, allowing users to instantiate classes, pass data, and invoke methods using native C++ objects and application characters can be controlled outside the application like inside plugin using HTN. How can I implement this in such a way that the API must keep the application closed-source.