Skip to content

Gameplay Kit — Cheatsheet

One entry per module, added as the module ships (definition of done).

Core (M0)

// Setup: put a GameplayKitConfig asset (Create → LoLGameplayKit) in Resources/.
// Registration is automatic — each module's IServiceRegistrar is discovered by assembly scan.

// Save domains: subclass GameplayKitSaveData, DataId = "gameplaykit.<module>".
//   EVERY List<T> reachable from a save domain carries
//   [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] — the engine load
//   path populates the live instance in place and appends to top-level lists otherwise
//   (redundant-but-uniform on nested lists; mandatory on the save class itself).
// RNG: never UnityEngine.Random — IRngService streams named per GameplayKitRngStreams.
// Events: GameEvent.GetEvent<T>() → fill → eventManager.TriggerEvent(evt).
// Strings: LocString, never raw.

WorldFlags (M1)

var flags = ServiceLocator.Instance.Get<IWorldFlagService>();
flags.SetBool("quest.met_duke", true);
bool metDuke = flags.GetBool("quest.met_duke", defaultValue: false); // never throws

// React anywhere via the pooled event:
// class X : MonoBehaviour, IEventListener<WorldFlagChangedEvent>
// { void OnEnable() => this.EventStartListening<WorldFlagChangedEvent>(); ... }
// Live inspector: Tools → LoLGameplayKit → World Flags (Play Mode).

Calendar (M1)

// Needs a CalendarConfig asset (phase list) in Resources/ next to GameplayKitConfig.
var calendar = ServiceLocator.Instance.Get<ICalendarService>();
calendar.AdvancePhase();                 // next phase; rolls to a new day after the last
calendar.ScheduleInDays("quest.deadline", 3, calendar.CurrentPhaseIndex);

// React via IEventListener<CalendarScheduledDueEvent>, matching evt.ScheduleId —
// ids, never stored delegates (that's what makes schedules save-safe).
// Rollover event order: DayEnded → DayStarted → PhaseChanged → due entries.

Items (M2)

// Needs an ItemDatabase asset (items + rarities) in Resources/ next to GameplayKitConfig.
var items = ServiceLocator.Instance.Get<IItemDatabaseService>();
var sword = items.GetById("sword");                    // O(1); null if unknown — never throws
var potions = items.GetByTag("potion");
int gold = sword.BaseValue;
bool cursed = sword.GetBoolProperty("cursed", false);  // typed property bag, never throws
// Static definitions only — no save domain, no events.
// Validate: Tools → LoLGameplayKit → Validate Item Database.

Interaction (M2)

// No service/config gate — components are opt-in by usage. enableInteraction is reserved, unwired.
var interactable = worldObject.AddComponent<InteractableComponent>(); // Verb (locTable/locKey) in Inspector
var detector = player.AddComponent<InteractionDetectorComponent>();   // Range, Min Facing Dot
if (myInputAction.WasPressedThisFrame()) detector.TryInteract();      // input-agnostic — you call this

// React via IEventListener<InteractableFocusedEvent>/<Unfocused>/<InteractionPerformedEvent>,
// or the detector's local Focused/Unfocused/Interacted C# events (destroyed target ⇒ null arg).
// Selection: enabled + in range + within facing cone; nearest wins; ties → registration order.

Contracts (M3)

// Needs a ContractCatalog asset (ContractDefinitions) in Resources/ next to GameplayKitConfig.
var contracts = ServiceLocator.Instance.Get<IContractService>();
contracts.ItemCountProvider = myAdapter;              // game-supplied — no inventory module exists
var id = contracts.OfferContract("retrieve_ledger");  // "retrieve_ledger#1", deterministic
contracts.Accept(id);                                 // deadline = today + DeadlineDays (0 = none)
var result = contracts.TryComplete(id);               // result.UnmetRequirements = turn-in UI report

// Flag rewards are applied via IWorldFlagService; ITEM rewards are only EMITTED —
// grant them yourself in IEventListener<ContractCompletedEvent> (evt.ItemRewards).
// Deadline day is inclusive; expiry fires when the next day starts (Calendar-driven).

Deduction (M3)

// Needs a DeductionMatrix asset (properties + subjects) in Resources/ next to GameplayKitConfig.
var knowledge = ServiceLocator.Instance.Get<IKnowledgeService>();
knowledge.Reveal("book1", "author");
string author = knowledge.GetTruth("book1", "author");  // null until revealed, never throws

var guesses = new Dictionary<string, string> { ["author"] = "asha", ["section"] = "correspondence" };
GuessReport report = knowledge.CommitGuess("book1", guesses);  // the catalog commit-click
if (report.AllCorrect) { /* confirm moment */ }
// React via IEventListener<DeductionPropertyRevealedEvent>/<DeductionGuessCommittedEvent>.

Tooltip (M2)

var tooltips = ServiceLocator.Instance.Get<ITooltipService>();
tooltips.Show(new ItemTooltipSource(someItem));  // ItemDefinition → titled/tinted/tagged content
tooltips.Hide();                                  // Show(null) also hides
// Drag-and-drop: TooltipViewComponent on a uGUI panel + TooltipTriggerComponent on anything
// hoverable. Headless service (test without UI); the view is a dumb swappable skin.

Sample Scenes

All inside the package (GameplayKit/Samples/) and fully self-contained — each scene embeds an engine bootstrap, and the Kit's Resources catalogs ship in Samples/Content/Resources/, so the demos run in a fresh project that imports only the package.

Scene Demo
Samples/Scenes/KitShowcase.unity Flags / Calendar / Items / Contracts / Deduction + calendar HUD (TooltipSample is headless/console-only here)
Samples/Scenes/InteractionDemo.unity WASD player, facing cone, TryInteract (E)
Samples/Scenes/TooltipDemo.unity Hover slots → rarity-tinted tooltips

Rebuild: Tools → LoLGameplayKit → Build Sample Scenes.