Quests & Progress
Progress tracking is a lookup-by-owner workload with a simple state flip. It shows how a declared index keeps per-player reads fast and how a command performs the write.
note
The QuestProgress table here is the same one introduced in
Build Your First Game; this page adds the GetOpenQuests
query and the CompleteQuest command on top of it.
Schema
table QuestProgress(plural: QuestProgressRows, persistence: local, capacity: 2048, type_id: 3) {
Id: int @id
PlayerId: int
QuestId: int
Completed: bool
@@index(fields: [PlayerId], name: "QuestProgress_ByPlayer", kind: lookup)
}
Query the player's open quests
query GetOpenQuests(playerId: int) -> QuestProgress[] {
from QuestProgressRows
| filter PlayerId == @playerId && Completed == false
| sort QuestId
}
The lookup index on PlayerId means this filter is a direct index probe, not a table
scan — even with thousands of rows.
Complete a quest with a command
module Quests {
command CompleteQuest(playerId: int, questId: int) -> CompleteQuestResult
kind local
{
upsert QuestProgressRows
| key { PlayerId: playerId, QuestId: questId }
| set Completed = true
return { questId: questId }
}
}
Call it from C#
using ConjureDB;
using var ctx = DbContextBuilder<GameDbContext>.Create()
.WithDataDirectory("./data")
.WithDefaultSnapshot()
.Build();
var open = ctx.GetOpenQuests(playerId: 1);
See Indexing for how to choose lookup vs sorted_set / sorted_list
vs unique indexes for each access pattern.