Description
Template-generated quest definitions are ephemeral — they exist only in memory and are recovered after restart from the generated_definition JSON column on the BoardOffering row. The offering row is the sole durable copy of the definition. If the offering row is deleted (database cleanup, manual purge of old rotations, or cascade from rotation table maintenance) while the quest instance is still active, the definition is unrecoverable on next restart and the quest becomes inert.
Expected Behavior
The generated definition JSON should be protected from loss while its quest instance is active. Options include:
- Option A: Store
generated_definition JSON on the quest instance row itself (in mcrpg_quest_instances), eliminating the dependency on the offering row surviving. The offering row would still store it for board display purposes, but the instance row becomes the authoritative copy for recovery.
- Option B: Add a foreign key or application-level guard that prevents offering rows from being deleted while any
IN_PROGRESS or NOT_STARTED quest instance references them.
- Option C: Copy the JSON to a dedicated
mcrpg_ephemeral_definitions table keyed by definition key, with cleanup tied to deregisterEphemeralDefinition.
Actual Behavior
recoverEphemeralDefinition loads the offering via BoardOfferingDAO.loadOfferingByQuestInstanceUUID. If the offering row is gone, it logs a warning and returns false. The quest instance loads into Tier 1 but has no definition, rendering it permanently inert.
Context
In normal operation this is unlikely — offering rows are not actively purged while quests are in progress. But there is no structural guarantee. A server owner running manual SQL cleanup on old board data could inadvertently orphan active quests. The single-point-of-failure design is fragile for a column that serves as the disaster recovery mechanism for the entire definition layer of template-generated quests.
Relevant Code
QuestManager.recoverEphemeralDefinition() — recovery path dependent on offering row
BoardOfferingDAO.loadOfferingByQuestInstanceUUID() — the lookup that fails if the row is gone
QuestBoardTerminator.deregisterEphemeralDefinition() — cleanup on quest terminal state
GeneratedQuestDefinitionSerializer — the serializer/deserializer for the JSON
Description
Template-generated quest definitions are ephemeral — they exist only in memory and are recovered after restart from the
generated_definitionJSON column on theBoardOfferingrow. The offering row is the sole durable copy of the definition. If the offering row is deleted (database cleanup, manual purge of old rotations, or cascade from rotation table maintenance) while the quest instance is still active, the definition is unrecoverable on next restart and the quest becomes inert.Expected Behavior
The generated definition JSON should be protected from loss while its quest instance is active. Options include:
generated_definitionJSON on the quest instance row itself (inmcrpg_quest_instances), eliminating the dependency on the offering row surviving. The offering row would still store it for board display purposes, but the instance row becomes the authoritative copy for recovery.IN_PROGRESSorNOT_STARTEDquest instance references them.mcrpg_ephemeral_definitionstable keyed by definition key, with cleanup tied toderegisterEphemeralDefinition.Actual Behavior
recoverEphemeralDefinitionloads the offering viaBoardOfferingDAO.loadOfferingByQuestInstanceUUID. If the offering row is gone, it logs a warning and returns false. The quest instance loads into Tier 1 but has no definition, rendering it permanently inert.Context
In normal operation this is unlikely — offering rows are not actively purged while quests are in progress. But there is no structural guarantee. A server owner running manual SQL cleanup on old board data could inadvertently orphan active quests. The single-point-of-failure design is fragile for a column that serves as the disaster recovery mechanism for the entire definition layer of template-generated quests.
Relevant Code
QuestManager.recoverEphemeralDefinition()— recovery path dependent on offering rowBoardOfferingDAO.loadOfferingByQuestInstanceUUID()— the lookup that fails if the row is goneQuestBoardTerminator.deregisterEphemeralDefinition()— cleanup on quest terminal stateGeneratedQuestDefinitionSerializer— the serializer/deserializer for the JSON