Record Keeper
Lightweight key-value progression tracking — store and retrieve named integer records without writing a custom saver.
Categories:

Image showing the Record Keeper component with its unique variables and inherited Saver properties, as seen in the Entity Inspector.
Overview
The Record Keeper is a companion component that provides a simple key-value store for tracking progression, switch states, quest stages, or any other data that doesn’t require a complex Saver implementation. Each record is a SaveRecord — a name/value pair of recordName (string) and recordProgress (integer).
Because it extends GS_SaverComponent, the Record Keeper saves and loads automatically with the rest of the save system. No custom serialization code needed.
How It Works
- The Record Keeper lives on your Save Manager prefab entity (recommended) or any entity with save system access.
- Game systems call
SetRecord,GetRecord,HasRecord, andDeleteRecordvia theRecordKeeperIncomingEventBus. - On each call to
SetRecord, the Record Keeper broadcastsRecordChangedon theRecordKeeperOutgoingEventBusso listeners can react. - When a global save event fires (
OnSaveAll), the Record Keeper serializes all its records into the save file automatically. - On load, it deserializes its records and makes them available immediately.
SaveRecord Data Structure
struct SaveRecord
{
AZStd::string recordName; // Unique key (e.g., "quest_village_rescue", "switch_bridge_01")
AZ::s32 recordProgress; // Integer value (progression stage, state, count, etc.)
};
TypeId: {F6F4F258-819A-468A-B015-CAF51D8289BF}
Setup
- Open your Save Manager prefab in prefab edit mode.
- Add the RecordKeeperComponent to the Save Manager entity.
- Set the Record Keeper Name — this drives unique save/load identification and allows multiple Record Keepers if needed.
- Enable the Saver booleans as needed:
- Load On Activate — automatically loads records when the component activates (recommended: on).
- Save On Destroy — automatically saves records when the component is destroyed (recommended: on).
Inspector Properties
| Property | Type | Default | Description |
|---|---|---|---|
| Record Keeper Name | AZStd::string | "" | Unique identifier for this Record Keeper. Drives the save/load key. Required if using multiple Record Keepers. |
| Load On Activate | bool | true | Inherited from GS_SaverComponent. Automatically loads records from save data on activation. |
| Save On Destroy | bool | true | Inherited from GS_SaverComponent. Automatically saves records to the save system on destruction. |
API Reference
Request Bus: RecordKeeperIncomingEventBus
The primary interface for reading and writing records.
| Method | Parameters | Returns | Description |
|---|---|---|---|
HasRecord | const AZStd::string& recordName | bool | Returns true if a record with the given name exists. |
SetRecord | const AZStd::string& recordName, AZ::s32 recordProgress | void | Creates or updates a record. Broadcasts RecordChanged on success. |
GetRecord | const AZStd::string& recordName | AZ::s32 | Returns the value of the named record. Returns 0 if the record does not exist. |
DeleteRecord | const AZStd::string& recordName | void | Removes the named record from the store. |
Notification Bus: RecordKeeperOutgoingEventBus
Connect to this bus to react when records change.
| Event | Parameters | Description |
|---|---|---|
RecordChanged | const AZStd::string& recordName, AZ::s32 recordValue | Broadcast whenever SetRecord is called. Use this to update UI, trigger gameplay events, or log progression. |
Usage Examples
Setting a Progression Record
#include <GS_Core/GS_CoreBus.h>
// Mark quest stage 2 as complete
GS_Core::RecordKeeperIncomingEventBus::Broadcast(
&GS_Core::RecordKeeperIncomingEventBus::Events::SetRecord,
"quest_village_rescue",
2
);
Reading a Record
#include <GS_Core/GS_CoreBus.h>
AZ::s32 questStage = 0;
GS_Core::RecordKeeperIncomingEventBus::BroadcastResult(
questStage,
&GS_Core::RecordKeeperIncomingEventBus::Events::GetRecord,
"quest_village_rescue"
);
if (questStage >= 2)
{
// The player has completed stage 2 — unlock the bridge
}
Checking if a Record Exists
#include <GS_Core/GS_CoreBus.h>
bool exists = false;
GS_Core::RecordKeeperIncomingEventBus::BroadcastResult(
exists,
&GS_Core::RecordKeeperIncomingEventBus::Events::HasRecord,
"switch_bridge_01"
);
if (!exists)
{
// First time encountering this switch — initialize it
GS_Core::RecordKeeperIncomingEventBus::Broadcast(
&GS_Core::RecordKeeperIncomingEventBus::Events::SetRecord,
"switch_bridge_01",
0
);
}
Listening for Record Changes
#include <GS_Core/GS_CoreBus.h>
// In your component header:
class MyQuestTrackerComponent
: public AZ::Component
, protected GS_Core::RecordKeeperOutgoingEventBus::Handler
{
protected:
void Activate() override
{
GS_Core::RecordKeeperOutgoingEventBus::Handler::BusConnect();
}
void Deactivate() override
{
GS_Core::RecordKeeperOutgoingEventBus::Handler::BusDisconnect();
}
// RecordKeeperOutgoingEventBus
void RecordChanged(const AZStd::string& recordName, AZ::s32 recordValue) override
{
if (recordName == "quest_village_rescue" && recordValue >= 3)
{
// Quest complete — trigger reward
}
}
};
Extending the Record Keeper
The Record Keeper extension API is being refined for Core v2 to support proper inheritance and custom record types. For now, use the Record Keeper as-is and create custom Saver components for complex data needs.
See Also
- Save Manager — Central save/load controller
- Savers — Entity-level save handlers for complex data
- List of Savers — Pre-built saver components