app/personality.h

named opponents, backed by engine option presets.

A “personality” is data, not code (docs/gui-docs/PLAN.md §4): an avatar + blurb + approximate rating paired with a specific engine configuration. Every behavioral knob is already a UCI option, so a personality is just a named preset of EngineOptions + a per-move SearchLimits budget, plus the display metadata the Version-Select screen renders. Personalities load from JSON files so users can add opponents without recompiling; three builtins (Easy / Medium / Hard) ship with the app so the feature has content on day one.

namespace kirin
struct Personality
#include <personality.h>

Public Functions

inline bool usesBuiltinEngine() const

Public Members

std::string id
std::string displayName
std::string avatar
std::string blurb
int estimatedElo = 0
std::string engine = "builtin"
EngineOptions options
SearchLimits limits
class PersonalityRegistry
#include <personality.h>

Public Functions

PersonalityRegistry() = default
void loadBuiltins()
int loadDirectory(const std::string &dir, std::vector<std::string> *errors = nullptr)
inline const std::vector<Personality> &all() const
inline size_t size() const
inline bool empty() const
const Personality *find(const std::string &id) const

Public Static Functions

static bool parseJson(const std::string &text, Personality &out, std::string &error)
static NewGameConfig toNewGameConfig(const Personality &p, bool humanPlaysWhite)

Private Functions

void upsert(Personality p)

Private Members

std::vector<Personality> personalities_