![]() |
JaffarPlus
High-performance best-first search optimizer for tool-assisted speedruns
|
Abstract base class for a JaffarPlus game. More...
#include <game.hpp>
Public Types | |
| enum | stateType_t { normal = 0 , win = 1 , fail = 2 } |
| Classification of the current game state, derived from the satisfied rules. More... | |
Public Member Functions | |
| Game (std::unique_ptr< Emulator > emulator, const nlohmann::json &config) | |
| Constructs a game from an already created emulator and a configuration object. | |
| std::string | getRegisteredPropertyNames () const |
| Returns a comma-separated list of the property names registered for this game. | |
| void | initialize () |
| Initializes the game: emulator, properties, rules and the first state update. | |
| Game ()=delete | |
| Default construction is disabled; a game requires an emulator and config. | |
| void | advanceState (const InputSet::inputIndex_t input) |
| Advances the game state by applying a single input. | |
| void | serializeState (jaffarCommon::serializer::Base &serializer) const |
| Serializes the full game state. | |
| void | deserializeState (jaffarCommon::deserializer::Base &deserializer) |
| Restores the full game state previously written by serializeState. | |
| void | computeHash (MetroHash128 &hashEngine) const |
| Updates a hash engine with the current state's distinguishing data. | |
| void | printInfo () const |
| Prints the current game state to the logger. | |
| void | evaluateRules () |
| Evaluates the rule set against the current state. | |
| void | runGameSpecificRuleActions () |
| Runs the registered actions of every currently satisfied rule. | |
| void | updateGameStateType () |
| Recomputes the state type and checkpoint level from the satisfied rules. | |
| void | updateReward () |
| Recomputes the current state's reward from the satisfied rules. | |
| std::unique_ptr< Condition > | parseCondition (const nlohmann::json &conditionJs) |
| Parses a single rule condition from JSON into a typed Condition. | |
| Emulator * | getEmulator () const |
| Returns a pointer to the internal emulator. | |
| float | getFrameRate () const |
| Returns the configured frame rate. | |
| float | getReward () const |
| Returns the current state's reward. | |
| virtual std::string | getTraceLine () const |
One line of a per-step trace for player --dumpTrace (space-separated coordinates the game wants to record, e.g. | |
| virtual float | getFloorReward () const |
| Reward used for the Reference Reward Floor comparison: the un-biased progress reward, WITHOUT any eviction-only ranking penalty (e.g. | |
| stateType_t | getStateType () const |
| Returns the current state type (normal, win or fail). | |
| size_t | getCheckpointLevel () const |
| Returns the current state's checkpoint level. | |
| size_t | getCheckpointTolerance () const |
| Returns the current state's checkpoint tolerance. | |
| bool | isSaveSolution () const |
| Indicates whether the current state should trigger a save solution. | |
| ssize_t | getSaveSolutionPrevLastRuleIdx () const |
| Returns the previous last rule index that set a save solution. | |
| ssize_t | getSaveSolutionCurrentLastRuleIdx () const |
| Returns the current last rule index that set a save solution. | |
| const std::string | getSaveSolutionPath () const |
| Returns the save path of the rule that activated the current save solution. | |
| std::string | getName () const |
| Returns the game name used at runtime. | |
| bool | isInitialized () const |
| Returns whether the game has been initialized. | |
| virtual jaffarCommon::hash::hash_t | getStateInputHash () |
| Returns a hash identifying the current state for new-input discovery. | |
| virtual void | getAdditionalAllowedInputs (std::vector< InputSet::inputIndex_t > &allowedInputSet) |
| Lets a game contribute additional allowed inputs based on game-specific decisions. | |
| virtual std::set< std::string > | getAllPossibleInputs () |
| Reports all possible inputs the game might require. | |
| virtual void | playerPrintCommands () const |
| Prints the game's player-specific commands, if any. | |
| virtual bool | playerParseCommand (const int command) |
| Handles a game-specific player command. | |
| virtual jaffarCommon::hash::hash_t | getDirectStateHash () const |
| Returns the state hash directly, without going through a hashing engine. | |
Static Public Member Functions | |
| static std::unique_ptr< Game > | getGame (const nlohmann::json &emulatorConfig, const nlohmann::json &gameConfig) |
| Factory that constructs the concrete game matching the given configuration. | |
Protected Member Functions | |
| void | finalizeGameConfig () |
| Asserts that every key in the game configuration has been recognized. | |
| void * | registerGameProperty (const std::string &name, void *const pointer, const Property::datatype_t dataType, const Property::endianness_t endianness) |
| Registers a game property so it can be referenced by name in rules and printing/hashing. | |
| void | parseRules (const nlohmann::json &rulesJson) |
| Parses the full rule array, builds the rule objects and resolves cross-references. | |
| void | parseRule (Rule &rule, const nlohmann::json &ruleJs) |
| Parses a single rule's conditions, actions and "Satisfies" labels into a Rule. | |
| void | parseRuleAction (Rule &rule, const nlohmann::json &actionJs) |
| Parses a single rule action from JSON and applies it to the rule. | |
| void | satisfyRule (Rule &rule) |
| Marks a rule as satisfied, recursively satisfying the rules it satisfies first. | |
| virtual void | initializeImpl () |
| Game-specific initialization hook, called during initialize. | |
| virtual void | registerGameProperties ()=0 |
| Registers the game's properties (via registerGameProperty). | |
| virtual void | serializeStateImpl (jaffarCommon::serializer::Base &serializer) const =0 |
| Serializes game-specific state. | |
| virtual void | deserializeStateImpl (jaffarCommon::deserializer::Base &deserializer)=0 |
| Restores game-specific state previously written by serializeStateImpl. | |
| virtual float | calculateGameSpecificReward () const =0 |
| Computes the game-specific contribution to the state reward. | |
| virtual void | computeAdditionalHashing (MetroHash128 &hashEngine) const =0 |
| Adds game-specific data into the hash engine. | |
| virtual void | printInfoImpl () const =0 |
| Prints game-specific state information to the logger. | |
| virtual void | advanceStateImpl (const InputSet::inputIndex_t input)=0 |
| Advances the game state by applying the given input. | |
| virtual bool | parseRuleActionImpl (Rule &rule, const std::string &actionType, const nlohmann::json &actionJs)=0 |
| Parses and applies a game-specific rule action. | |
| virtual void | stateUpdatePreHook () |
| Optional hook run before a state update (advance/deserialize). Base does nothing. | |
| virtual void | stateUpdatePostHook () |
| Optional hook run after a state update (advance/deserialize). Base does nothing. | |
| virtual void | ruleUpdatePreHook () |
| Optional hook run before rule evaluation/restoration. Base does nothing. | |
| virtual void | ruleUpdatePostHook () |
| Optional hook run after rule evaluation/restoration. Base does nothing. | |
Protected Attributes | |
| stateType_t | _stateType = stateType_t::normal |
| Current game state type. Initialized to normal because it is read (printInfo) and serialized for the initial state before updateGameStateType() first assigns it. | |
| float | _reward = 0.0 |
| Current game state reward. | |
| size_t | _checkpointLevel = 0 |
| Current state's checkpoint level. | |
| size_t | _checkpointTolerance = 0 |
| Tolerance recorded for checkpoint states. | |
| ssize_t | _saveSolutionCurrentLastRuleIdx = -1 |
| Previous last rule index that activated a save solution (preserved to mark the state where it changes); save state activates only when a rule id exceeds it. | |
| ssize_t | _saveSolutionCurrentLastRuleId = -1 |
| Current last rule index that activated a save solution; save state activates only when a rule id is bigger than the previous one. -1 when none. | |
| const std::unique_ptr< Emulator > | _emulator |
| Underlying emulator instance. | |
| std::vector< std::unique_ptr< Rule > > | _rules |
| Game script rules, kept in a vector to preserve ordering. | |
| std::vector< uint8_t > | _rulesStatus |
| Bit vector indicating whether each rule has been satisfied. | |
| std::vector< std::string > | _printablePropertyNames |
| Parsed property names configured to be printed. | |
| std::vector< std::string > | _hashablePropertyNames |
| Parsed property names configured to be hashed. | |
| std::vector< const Property * > | _propertyHashVector |
| Properties used to hash/distinguish states, ordered. | |
| std::vector< const Property * > | _propertyPrintVector |
| Properties printed for game information, ordered. | |
| std::map< jaffarCommon::hash::hash_t, std::unique_ptr< Property > > | _propertyMap |
| All registered properties, indexed by name hash. | |
| float | _frameRate |
| Frame rate to play the game with, required for correct playback. | |
| bool | _bypassEmulatorState |
| When true, the game handles state save/load entirely, bypassing the emulator. | |
| std::string | _gameName |
| Game name (for runtime use). | |
| nlohmann::json | _rulesJs |
| Temporary storage of the rules JSON for delayed parsing. | |
| nlohmann::json | _gameConfigRemaining |
| Mutable working copy of the game config; recognized keys are popped, leftovers are unrecognized. See finalizeGameConfig(). | |
| bool | _isInitialized = false |
| Whether the game has been initialized. | |
Abstract base class for a JaffarPlus game.
A game wraps an Emulator and exposes the search-facing interface: it advances and (de)serializes state, computes state hashes, evaluates a configured rule set, and tracks the derived state type, reward, checkpoint level and save-solution information. Concrete games subclass it and implement the pure-virtual hooks (e.g. registerGameProperties, advanceStateImpl, serializeStateImpl, deserializeStateImpl, calculateGameSpecificReward, computeAdditionalHashing, printInfoImpl and parseRuleActionImpl).
|
inline |
Constructs a game from an already created emulator and a configuration object.
| emulator | The emulator instance this game takes ownership of. |
| config | Game configuration JSON, providing "Game Name", "Frame Rate", "Bypass Emulator State", "Print Properties", "Hash Properties" and "Rules". |
|
inline |
Advances the game state by applying a single input.
Runs the pre-update hook, snapshots the previous save-solution rule id, calls advanceStateImpl with the input, then runs the post-update hook.
| input | The input index to apply for this step. |
|
protectedpure virtual |
Advances the game state by applying the given input.
Must be implemented.
| input | The input index to apply for this step. |
|
protectedpure virtual |
Computes the game-specific contribution to the state reward.
Must be implemented.
|
protectedpure virtual |
Adds game-specific data into the hash engine.
Must be implemented.
| hashEngine | The hash engine to update with game-specific data. |
|
inline |
Updates a hash engine with the current state's distinguishing data.
Feeds each hashable property's bytes into the engine, then calls computeAdditionalHashing for any game-specific contribution.
| hashEngine | The hash engine to update. |
|
inline |
Restores the full game state previously written by serializeState.
Runs the pre-update hook, restores the emulator state (unless bypassed) and game-specific data via deserializeStateImpl, runs the post-update hook, then pops the reward, checkpoint level, save-solution rule ids and state type. Finally runs the pre-rule hook, restores the rule status vector, re-runs game-specific rule actions and runs the post-rule hook.
| deserializer | The deserializer to pop state from. |
|
protectedpure virtual |
Restores game-specific state previously written by serializeStateImpl.
Must be implemented.
| deserializer | The deserializer to pop game-specific state from. |
|
inline |
Evaluates the rule set against the current state.
Runs the pre-rule hook, then for each not-yet-satisfied rule evaluates its conditions and, if met, marks it satisfied via satisfyRule. Afterwards runs game-specific rule actions and the post-rule hook.
|
inlineprotected |
Asserts that every key in the game configuration has been recognized.
Call this at the END of a derived core's constructor, after it has consumed all of its own configuration keys (via the jaffarCommon::json::pop* helpers) from _gameConfigRemaining. The base ctor has already popped the common keys (Game Name, Frame Rate, Bypass Emulator State, Print Properties, Hash Properties, Rules), so anything still present is an unrecognized key (a typo or unsupported option) and is reported by name. Cores that do not call this remain lenient (opt-in strict validation).
|
inlinevirtual |
|
inlinevirtual |
|
inline |
|
inline |
|
inlinevirtual |
|
inline |
|
inlinevirtual |
Reward used for the Reference Reward Floor comparison: the un-biased progress reward, WITHOUT any eviction-only ranking penalty (e.g.
a trace magnet). Defaults to the full reward; a game that subtracts a ranking-only bias from its reward overrides this to add that bias back, so the floor measures true progress (position) and never false-cancels a position-correct-but-biased state.
|
inline |
|
static |
Factory that constructs the concrete game matching the given configuration.
| emulatorConfig | The emulator configuration JSON. |
| gameConfig | The game configuration JSON. |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inlinevirtual |
|
inline |
|
inlinevirtual |
|
inline |
Initializes the game: emulator, properties, rules and the first state update.
Initializes the emulator if needed, calls registerGameProperties, resolves the configured printable and hashable property names to property pointers, parses the rules, runs the pre-/post-update hooks around initializeImpl, and marks the game as initialized.
| A | logic error if the game was already initialized, or if a configured printable or hashable property name is not registered. |
|
inlineprotectedvirtual |
Game-specific initialization hook, called during initialize.
Base implementation does nothing; games may override it.
|
inline |
|
inline |
|
inline |
Parses a single rule condition from JSON into a typed Condition.
Resolves the "Op" operator and the "Property" first operand (which must be registered), then interprets "Value": a number or boolean becomes an immediate second operand, while a string is treated as the name of a second registered property. The condition is instantiated as a _vCondition specialized to the first property's datatype.
| conditionJs | The condition JSON object, expected to contain "Op", "Property" and "Value". |
| A | logic error if the operator is unknown, a referenced property is not declared, the "Value" key is missing, or its format/type is invalid. |
|
inlineprotected |
Parses a single rule's conditions, actions and "Satisfies" labels into a Rule.
Reads the "Conditions", "Actions" and "Satisfies" arrays: each condition is parsed via parseCondition and added to the rule, each action via parseRuleAction, and each satisfies entry (which must be a number) is added as a satisfy-rule label.
| rule | The rule to populate. |
| ruleJs | The rule JSON object. |
| A | logic error if a "Satisfies" entry is not a number (and from the called parsers). |
|
inlineprotected |
Parses a single rule action from JSON and applies it to the rule.
Recognizes the built-in action types "Add Reward", "Trigger Fail", "Trigger Win", "Trigger Checkpoint" (with "Tolerance") and "Trigger Save Solution" (with "Path"). Any other action type is delegated to the game-specific parseRuleActionImpl.
| rule | The rule to apply the action to. |
| actionJs | The action JSON object, expected to contain "Type". |
| A | logic error if the action type is not recognized by either the built-ins or the game-specific parser. |
|
protectedpure virtual |
Parses and applies a game-specific rule action.
Must be implemented.
| rule | The rule to apply the action to. |
| actionType | The action type string that was not matched by the built-in actions. |
| actionJs | The action JSON object. |
|
inlineprotected |
Parses the full rule array, builds the rule objects and resolves cross-references.
Clears any existing rules, then for each JSON entry creates a Rule with its label and parses it via parseRule. Afterwards it resolves each rule's "Satisfies" labels into pointers to the referenced rules, and sizes/clears the rule status bit vector.
| rulesJson | The array of rule JSON objects. |
| A | logic error if a rule entry is not an object, or if a referenced "Satisfies" label does not exist. |
|
inlinevirtual |
|
inlinevirtual |
|
inline |
Prints the current game state to the logger.
Logs the state type, reward, per-rule satisfaction bits, and each printable property's value (formatted by datatype), then calls printInfoImpl for game-specific output.
|
protectedpure virtual |
Prints game-specific state information to the logger.
Must be implemented.
|
protectedpure virtual |
Registers the game's properties (via registerGameProperty).
Must be implemented.
|
inlineprotected |
Registers a game property so it can be referenced by name in rules and printing/hashing.
| name | The property name (used to compute the indexing hash). |
| pointer | Pointer to the underlying memory the property reads/writes. |
| dataType | The property's datatype. |
| endianness | The property's byte endianness. |
pointer that was passed in (returned as a convenience).
|
inlineprotectedvirtual |
|
inlineprotectedvirtual |
|
inline |
|
inlineprotected |
Marks a rule as satisfied, recursively satisfying the rules it satisfies first.
For each sub-rule in this rule's satisfy list that is not yet satisfied, recurses into satisfyRule, then sets this rule's status bit to satisfied.
| rule | The rule to mark as satisfied. |
|
inline |
Serializes the full game state.
Serializes the emulator state (unless emulator state is bypassed), then game-specific data via serializeStateImpl, followed by the reward, checkpoint level, save-solution rule ids, state type and rule status vector.
| serializer | The serializer to push state into. |
|
protectedpure virtual |
Serializes game-specific state.
Must be implemented.
| serializer | The serializer to push game-specific state into. |
|
inlineprotectedvirtual |
|
inlineprotectedvirtual |
|
inline |
Recomputes the state type and checkpoint level from the satisfied rules.
Resets the state type to normal and the checkpoint level to zero, then iterates the satisfied rules: checkpoint rules increment the checkpoint level and record their tolerance, save-solution rules update the current save-solution rule id when their index exceeds the previous one, win rules set the state type to win, and fail rules set it to fail.
|
inline |
Recomputes the current state's reward from the satisfied rules.
Resets the reward to zero, sums the reward of every satisfied rule, and adds the game-specific reward from calculateGameSpecificReward.
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
Mutable working copy of the game config; recognized keys are popped, leftovers are unrecognized. See finalizeGameConfig().
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
Current game state type. Initialized to normal because it is read (printInfo) and serialized for the initial state before updateGameStateType() first assigns it.