From 8861bdc5eb0135398eee50486bd4245a8f6ea0cd Mon Sep 17 00:00:00 2001 From: Sebastian Bularca Date: Sun, 19 Apr 2026 12:46:44 +0200 Subject: [PATCH] added encounter system --- .../AssetGroups/Common_Assets.asset | 5 + .../GameState/PlayModes/AdventurePlayMode.cs | 4 +- .../Code/GameState/PlayModes/Encounters.meta | 3 + .../PlayModes/Encounters/EncounterHandler.cs | 7 + .../Encounters/EncounterHandler.cs.meta | 3 + .../PlayModes/Encounters/EncounterView.cs | 19 + .../Encounters/EncounterView.cs.meta | 3 + Assets/Database/Encounters.meta | 8 + .../Encounters/EncounterRegistry.asset | 16 + .../Encounters/EncounterRegistry.asset.meta | 8 + .../Database/Encounters/EncounterTables.meta | 8 + .../Encounters/EncounterTables/Dialogs.meta | 8 + .../Dialogs/DialogLineLibrary.asset | 22 + .../Dialogs/DialogLineLibrary.asset.meta | 8 + .../Dialogs/Dialog_Set_0.asset | 29 ++ .../Dialogs/Dialog_Set_0.asset.meta | 8 + .../Dialogs/Dialog_Set_1.asset | 38 ++ .../Dialogs/Dialog_Set_1.asset.meta | 8 + .../EncounterTables/TestEncounterTable.asset | 57 +++ .../TestEncounterTable.asset.meta | 8 + Assets/Database/Encounters/Rewards.meta | 8 + .../Database/Encounters/Rewards/Reward.asset | 26 ++ .../Encounters/Rewards/Reward.asset.meta | 8 + .../Encounters/TestEncountersCollection.asset | 16 + .../TestEncountersCollection.asset.meta | 8 + CLAUDE.md | 17 + .../com.jovian.encounter-system/Editor.meta | 8 + .../Editor/DialogLineRefDrawer.cs | 106 +++++ .../Editor/DialogLineRefDrawer.cs.meta | 2 + .../Editor/EncounterBrowserWindow.cs | 394 ++++++++++++++++++ .../Editor/EncounterBrowserWindow.cs.meta | 2 + .../Editor/EncounterDialogOptionDrawer.cs | 76 ++++ .../EncounterDialogOptionDrawer.cs.meta | 2 + .../Editor/EncounterDrawer.cs | 77 ++++ .../Editor/EncounterDrawer.cs.meta | 2 + .../Editor/EncounterLinkDrawer.cs | 82 ++++ .../Editor/EncounterLinkDrawer.cs.meta | 2 + .../Editor/EncounterValidator.cs | 296 +++++++++++++ .../Editor/EncounterValidator.cs.meta | 2 + .../Jovian.EncounterSystem.Editor.asmdef | 18 + .../Jovian.EncounterSystem.Editor.asmdef.meta | 7 + .../Editor/SubclassSelectorDrawer.cs | 148 +++++++ .../Editor/SubclassSelectorDrawer.cs.meta | 2 + Packages/com.jovian.encounter-system/LICENSE | 21 + .../com.jovian.encounter-system/LICENSE.meta | 7 + .../com.jovian.encounter-system/README.md | 186 +++++++++ .../README.md.meta | 7 + .../com.jovian.encounter-system/Runtime.meta | 8 + .../Runtime/DialogLineLibrary.cs | 55 +++ .../Runtime/DialogLineLibrary.cs.meta | 2 + .../Runtime/DialogLineRef.cs | 21 + .../Runtime/DialogLineRef.cs.meta | 2 + .../Runtime/EncounterContext.cs | 10 + .../Runtime/EncounterContext.cs.meta | 2 + .../Runtime/EncounterDialogOptionSet.cs | 42 ++ .../Runtime/EncounterDialogOptionSet.cs.meta | 3 + .../Runtime/EncounterLink.cs | 24 ++ .../Runtime/EncounterLink.cs.meta | 2 + .../Runtime/EncounterReference.cs | 14 + .../Runtime/EncounterReference.cs.meta | 3 + .../Runtime/EncounterRegistry.cs | 51 +++ .../Runtime/EncounterRegistry.cs.meta | 3 + .../Runtime/EncounterResolver.cs | 35 ++ .../Runtime/EncounterResolver.cs.meta | 2 + .../Runtime/EncounterTable.cs | 46 ++ .../Runtime/EncounterTable.cs.meta | 3 + .../Runtime/EncountersCollection.cs | 8 + .../Runtime/EncountersCollection.cs.meta | 3 + .../Runtime/IEncounter.cs | 56 +++ .../Runtime/IEncounter.cs.meta | 3 + .../Runtime/IEncounterEvent.cs | 27 ++ .../Runtime/IEncounterEvent.cs.meta | 2 + .../Runtime/IEncounterKind.cs | 52 +++ .../Runtime/IEncounterKind.cs.meta | 2 + .../Runtime/IRewardKind.cs | 33 ++ .../Runtime/IRewardKind.cs.meta | 2 + .../Runtime/Jovian.EncounterSystem.asmdef | 19 + .../Jovian.EncounterSystem.asmdef.meta | 7 + .../Runtime/QuestLog.cs | 63 +++ .../Runtime/QuestLog.cs.meta | 2 + .../Runtime/QuestProgress.cs | 103 +++++ .../Runtime/QuestProgress.cs.meta | 2 + .../Runtime/Reward.cs | 13 + .../Runtime/Reward.cs.meta | 2 + .../Runtime/SubclassSelectorAttribute.cs | 9 + .../Runtime/SubclassSelectorAttribute.cs.meta | 2 + .../com.jovian.encounter-system/package.json | 19 + .../package.json.meta | 7 + .../Editor/ZoneEditorSettings.cs | 4 +- .../Editor/ZoneEditorWindow.cs | 2 +- Packages/com.jovian.zonesystem/README.md | 12 +- .../Runtime/Jovian.ZoneSystem.asmdef | 2 +- Packages/packages-lock.json | 8 + ProjectSettings/PackageSyncSettings.json | 2 +- 94 files changed, 2581 insertions(+), 13 deletions(-) create mode 100644 Assets/Code/GameState/PlayModes/Encounters.meta create mode 100644 Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs create mode 100644 Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs.meta create mode 100644 Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs create mode 100644 Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs.meta create mode 100644 Assets/Database/Encounters.meta create mode 100644 Assets/Database/Encounters/EncounterRegistry.asset create mode 100644 Assets/Database/Encounters/EncounterRegistry.asset.meta create mode 100644 Assets/Database/Encounters/EncounterTables.meta create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs.meta create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset.meta create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset.meta create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset create mode 100644 Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset.meta create mode 100644 Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset create mode 100644 Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset.meta create mode 100644 Assets/Database/Encounters/Rewards.meta create mode 100644 Assets/Database/Encounters/Rewards/Reward.asset create mode 100644 Assets/Database/Encounters/Rewards/Reward.asset.meta create mode 100644 Assets/Database/Encounters/TestEncountersCollection.asset create mode 100644 Assets/Database/Encounters/TestEncountersCollection.asset.meta create mode 100644 Packages/com.jovian.encounter-system/Editor.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterBrowserWindow.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterBrowserWindow.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterDialogOptionDrawer.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterDialogOptionDrawer.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterDrawer.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterDrawer.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterLinkDrawer.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterLinkDrawer.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterValidator.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/EncounterValidator.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/Jovian.EncounterSystem.Editor.asmdef create mode 100644 Packages/com.jovian.encounter-system/Editor/Jovian.EncounterSystem.Editor.asmdef.meta create mode 100644 Packages/com.jovian.encounter-system/Editor/SubclassSelectorDrawer.cs create mode 100644 Packages/com.jovian.encounter-system/Editor/SubclassSelectorDrawer.cs.meta create mode 100644 Packages/com.jovian.encounter-system/LICENSE create mode 100644 Packages/com.jovian.encounter-system/LICENSE.meta create mode 100644 Packages/com.jovian.encounter-system/README.md create mode 100644 Packages/com.jovian.encounter-system/README.md.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/DialogLineLibrary.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/DialogLineLibrary.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/DialogLineRef.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/DialogLineRef.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterContext.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterContext.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterDialogOptionSet.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterDialogOptionSet.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterLink.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterLink.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterReference.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterReference.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterRegistry.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterRegistry.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterResolver.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterResolver.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterTable.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncounterTable.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncountersCollection.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/EncountersCollection.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounter.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounter.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounterEvent.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounterEvent.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounterKind.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/IEncounterKind.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/IRewardKind.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/IRewardKind.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/Jovian.EncounterSystem.asmdef create mode 100644 Packages/com.jovian.encounter-system/Runtime/Jovian.EncounterSystem.asmdef.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/QuestLog.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/QuestLog.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/QuestProgress.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/QuestProgress.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/Reward.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/Reward.cs.meta create mode 100644 Packages/com.jovian.encounter-system/Runtime/SubclassSelectorAttribute.cs create mode 100644 Packages/com.jovian.encounter-system/Runtime/SubclassSelectorAttribute.cs.meta create mode 100644 Packages/com.jovian.encounter-system/package.json create mode 100644 Packages/com.jovian.encounter-system/package.json.meta diff --git a/Assets/AddressableAssetsData/AssetGroups/Common_Assets.asset b/Assets/AddressableAssetsData/AssetGroups/Common_Assets.asset index f390a68..4687ca1 100644 --- a/Assets/AddressableAssetsData/AssetGroups/Common_Assets.asset +++ b/Assets/AddressableAssetsData/AssetGroups/Common_Assets.asset @@ -115,6 +115,11 @@ MonoBehaviour: m_ReadOnly: 0 m_SerializedLabels: [] FlaggedDuringContentUpdateRestriction: 0 + - m_GUID: 7a17d50d1abe3764695c6cd9598487ca + m_Address: EncounterRegistry + m_ReadOnly: 0 + m_SerializedLabels: [] + FlaggedDuringContentUpdateRestriction: 0 - m_GUID: 7b5e9961dadecea4bba3be6de61909f3 m_Address: CalendarSettings m_ReadOnly: 0 diff --git a/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs b/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs index da841b3..e727a67 100644 --- a/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs +++ b/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs @@ -26,7 +26,8 @@ namespace Nox.Game { private readonly PlayModeSettings bootstrapSettings; private readonly GameDataState gameDataState; private readonly ISaveSystem saveSystem; - private PartyDefinition partyDefinition; + private readonly PartyDefinition partyDefinition; + private readonly AdventureSettings adventureSettings; private AdventureData adventureData; private AdventureModePrefabs scenePrefabs; private ICameraController cameraController; @@ -38,7 +39,6 @@ namespace Nox.Game { private AdventureView adventureView; private ZoneSystem zoneSystem; private GuiReferences guiReferences; - private AdventureSettings adventureSettings; private TimeHandler timeHandler; private PartyInventoryHandler partyInventoryHandler; private PartyGuiView partyGuiView; diff --git a/Assets/Code/GameState/PlayModes/Encounters.meta b/Assets/Code/GameState/PlayModes/Encounters.meta new file mode 100644 index 0000000..6a55bc1 --- /dev/null +++ b/Assets/Code/GameState/PlayModes/Encounters.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d6216fd41db9494aaa6c127d9d790b93 +timeCreated: 1776506857 \ No newline at end of file diff --git a/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs b/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs new file mode 100644 index 0000000..88e1201 --- /dev/null +++ b/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs @@ -0,0 +1,7 @@ +using System; + +namespace Nox.Game { + + public class EncounterHandler { + } +} diff --git a/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs.meta b/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs.meta new file mode 100644 index 0000000..5f5ee1e --- /dev/null +++ b/Assets/Code/GameState/PlayModes/Encounters/EncounterHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 523274f9158f453dbfac02601a77c3f7 +timeCreated: 1776506833 \ No newline at end of file diff --git a/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs b/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs new file mode 100644 index 0000000..15ee914 --- /dev/null +++ b/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs @@ -0,0 +1,19 @@ +using Nox.Game.UI; + +namespace Nox.Game { + public class EncounterView : IMenuView{ + + public void Initialize() { + throw new System.NotImplementedException(); + } + public void Show() { + throw new System.NotImplementedException(); + } + public void Hide() { + throw new System.NotImplementedException(); + } + public void Tick() { + throw new System.NotImplementedException(); + } + } +} diff --git a/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs.meta b/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs.meta new file mode 100644 index 0000000..d2e42c8 --- /dev/null +++ b/Assets/Code/GameState/PlayModes/Encounters/EncounterView.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b69490c9f1d8471a84b4594d1b1be117 +timeCreated: 1776590016 \ No newline at end of file diff --git a/Assets/Database/Encounters.meta b/Assets/Database/Encounters.meta new file mode 100644 index 0000000..ca00c0a --- /dev/null +++ b/Assets/Database/Encounters.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 83509b822db37ec4e863ff7a2b4c01ae +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterRegistry.asset b/Assets/Database/Encounters/EncounterRegistry.asset new file mode 100644 index 0000000..f19fdd0 --- /dev/null +++ b/Assets/Database/Encounters/EncounterRegistry.asset @@ -0,0 +1,16 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0dfee180882d49c9a3d4474f389d4905, type: 3} + m_Name: EncounterRegistry + m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.EncounterRegistry + encounterCollections: + - {fileID: 11400000, guid: b3c3371ae34b4e34ea57a013b5125022, type: 2} diff --git a/Assets/Database/Encounters/EncounterRegistry.asset.meta b/Assets/Database/Encounters/EncounterRegistry.asset.meta new file mode 100644 index 0000000..166007a --- /dev/null +++ b/Assets/Database/Encounters/EncounterRegistry.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7a17d50d1abe3764695c6cd9598487ca +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables.meta b/Assets/Database/Encounters/EncounterTables.meta new file mode 100644 index 0000000..551a89b --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 453cbe825e21cba41b61175034c2b5d1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs.meta b/Assets/Database/Encounters/EncounterTables/Dialogs.meta new file mode 100644 index 0000000..069c366 --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 65c1422c9083d1b4d9721cf275cfe7f3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset b/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset new file mode 100644 index 0000000..d474f36 --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset @@ -0,0 +1,22 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 142d6e5b0f6a6cb41beddeae92b56fee, type: 3} + m_Name: DialogLineLibrary + m_EditorClassIdentifier: Jovian.EncounterSystem::Jovian.EncounterSystem.DialogLineLibrary + lines: + - id: test_you_die + text: Click me and see what happens. MIght all your dreams com true? + - id: click_to_continue + text: This is a test like that should you click it, it will continue and record + quest progress + - id: right_choice + text: You have chose right, padwan, here is 4 RON! diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset.meta b/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset.meta new file mode 100644 index 0000000..258f2d2 --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/DialogLineLibrary.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 11b94daa76442834198b68996afe0013 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset new file mode 100644 index 0000000..ecfcf11 --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset @@ -0,0 +1,29 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c47caaa92bb94eeca3e47dd86fd010cf, type: 3} + m_Name: Dialog_Set_0 + m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.EncounterDialogOptionSet + id: Dialog_Set_1 + library: {fileID: 11400000, guid: 11b94daa76442834198b68996afe0013, type: 2} + options: + - text: + id: click_to_continue + inlineText: + events: + - rid: 1352971465325281416 + references: + version: 2 + RefIds: + - rid: 1352971465325281416 + type: {class: LogEvent, ns: Jovian.EncounterSystem, asm: Jovian.EncounterSystem} + data: + message: An thus, you continue... diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset.meta b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset.meta new file mode 100644 index 0000000..58defcb --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_0.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7bc554ae0760bbb4796a1b3acef22cb3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset new file mode 100644 index 0000000..2d69f9f --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset @@ -0,0 +1,38 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: c47caaa92bb94eeca3e47dd86fd010cf, type: 3} + m_Name: Dialog_Set_1 + m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.EncounterDialogOptionSet + id: Dialog_Set_1 + library: {fileID: 11400000, guid: 11b94daa76442834198b68996afe0013, type: 2} + options: + - text: + id: test_you_die + inlineText: + events: + - rid: 1352971465325281414 + - text: + id: right_choice + inlineText: + events: + - rid: 1352971465325281412 + references: + version: 2 + RefIds: + - rid: 1352971465325281412 + type: {class: GiveRewardEvent, ns: Jovian.EncounterSystem, asm: Jovian.EncounterSystem} + data: + reward: {fileID: 11400000, guid: 2c02212ce09c5a246a8fe11a5253bfd4, type: 2} + - rid: 1352971465325281414 + type: {class: LogEvent, ns: Jovian.EncounterSystem, asm: Jovian.EncounterSystem} + data: + message: You died! HAhahAhaha! diff --git a/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset.meta b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset.meta new file mode 100644 index 0000000..725302f --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/Dialogs/Dialog_Set_1.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9496570aa3d05624a9b8bbbf6009c453 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset b/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset new file mode 100644 index 0000000..8be37b7 --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset @@ -0,0 +1,57 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e480a30007b949679b8ca1e0e6088675, type: 3} + m_Name: TestEncounterTable + m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.EncounterTable + id: TestEncounterTable + encounters: + - k__BackingField: + internalId: adce0a09-6402-4c2e-b24a-db7c9c67e3e5 + id: test_quest_1 + name: Test Quest Stage I + description: An encounter like no other which leads to another encounter like + no other + k__BackingField: + difficulty: 0 + k__BackingField: + icon: {fileID: 21300000, guid: ea02ea44fa86ee445be0f7ca82098b75, type: 3} + encounterColor: {r: 0, g: 0, b: 0, a: 0} + encounterArt: {fileID: 21300000, guid: a9c4c7681315e25419b9381d28aa9d80, type: 3} + k__BackingField: {fileID: 11400000, guid: 9496570aa3d05624a9b8bbbf6009c453, type: 2} + k__BackingField: + rid: 1352971465325281411 + - k__BackingField: + internalId: adce0a09-6402-4c2e-b24a-db7c9c67e3e5 + id: test_quest_2 + name: Test Quest Stage II + description: An encounter like no other which should be now completed + k__BackingField: + difficulty: 0 + k__BackingField: + icon: {fileID: 21300000, guid: ea02ea44fa86ee445be0f7ca82098b75, type: 3} + encounterColor: {r: 0, g: 0, b: 0, a: 0} + encounterArt: {fileID: 21300000, guid: 819d7a244820ad84585a1de7566bf9d0, type: 3} + k__BackingField: {fileID: 11400000, guid: 9496570aa3d05624a9b8bbbf6009c453, type: 2} + k__BackingField: + rid: -2 + references: + version: 2 + RefIds: + - rid: -2 + type: {class: , ns: , asm: } + - rid: 1352971465325281411 + type: {class: QuestKind, ns: Jovian.EncounterSystem, asm: Jovian.EncounterSystem} + data: + nextEncounter: + table: {fileID: 11400000} + internalId: adce0a09-6402-4c2e-b24a-db7c9c67e3e5 + questTitle: diff --git a/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset.meta b/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset.meta new file mode 100644 index 0000000..5fa664d --- /dev/null +++ b/Assets/Database/Encounters/EncounterTables/TestEncounterTable.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 396a5409178bf0d4b938094eefe22cca +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/Rewards.meta b/Assets/Database/Encounters/Rewards.meta new file mode 100644 index 0000000..5926771 --- /dev/null +++ b/Assets/Database/Encounters/Rewards.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 57820b3b9a698e24393172741670d8fe +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/Rewards/Reward.asset b/Assets/Database/Encounters/Rewards/Reward.asset new file mode 100644 index 0000000..93db044 --- /dev/null +++ b/Assets/Database/Encounters/Rewards/Reward.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ce47d4bfb319877429589295ac214255, type: 3} + m_Name: Reward + m_EditorClassIdentifier: Jovian.EncounterSystem::Jovian.EncounterSystem.Reward + id: gold + displayName: All Ze Money + kind: + rid: 1352971465325281413 + references: + version: 2 + RefIds: + - rid: 1352971465325281413 + type: {class: CurrencyRewardKind, ns: Jovian.EncounterSystem, asm: Jovian.EncounterSystem} + data: + currencyId: gold + amount: 100 diff --git a/Assets/Database/Encounters/Rewards/Reward.asset.meta b/Assets/Database/Encounters/Rewards/Reward.asset.meta new file mode 100644 index 0000000..835a67e --- /dev/null +++ b/Assets/Database/Encounters/Rewards/Reward.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2c02212ce09c5a246a8fe11a5253bfd4 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Database/Encounters/TestEncountersCollection.asset b/Assets/Database/Encounters/TestEncountersCollection.asset new file mode 100644 index 0000000..12767e5 --- /dev/null +++ b/Assets/Database/Encounters/TestEncountersCollection.asset @@ -0,0 +1,16 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 96ab08e2592347f68b8ad2e6e8d45187, type: 3} + m_Name: TestEncountersCollection + m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.EncountersCollection + encounterTables: + - {fileID: 11400000, guid: 396a5409178bf0d4b938094eefe22cca, type: 2} diff --git a/Assets/Database/Encounters/TestEncountersCollection.asset.meta b/Assets/Database/Encounters/TestEncountersCollection.asset.meta new file mode 100644 index 0000000..95a31a0 --- /dev/null +++ b/Assets/Database/Encounters/TestEncountersCollection.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b3c3371ae34b4e34ea57a013b5125022 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/CLAUDE.md b/CLAUDE.md index 659de09..cbd28d8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -109,3 +109,20 @@ Assets/Code/ - Factory pattern for character/party creation - Action delegates for UI event communication (e.g., `menuGameStateData.startGameRequests += handler`) - Mixed async patterns: both `async Task` and `IEnumerator` coroutines for async operations + +## Planning Docs Convention + +Non-trivial features are planned in `docs/plans/` as paired markdown files: a design doc and an implementation doc, both prefixed with the date. Examples: `2026-04-05-ingame-logging-design.md` + `2026-04-05-ingame-logging-implementation.md`, `2026-04-06-popup-system-design.md` + `2026-04-06-popup-system-implementation.md`. When starting a new feature, look here first for existing context, and follow the same pair-of-docs pattern for new work. + +## In-House Jovian Packages + +Several packages under `Packages/` are first-party code maintained alongside the game, not third-party dependencies. Before adding new capabilities, check whether one of these already provides what you need: + +- `Jovian.SaveSystem` — JSON persistence, used by `GamePersistenceController` +- `Jovian.Calendar` — custom in-game calendar system +- `Jovian.InGameLogging` — runtime logging surface +- `Jovian.EncounterSystem` — data-driven encounter authoring, `IEncounterKind` polymorphic payloads, `EncounterLink` cross-table refs, `QuestProgress` gated progression + `QuestLog`. Designer browser at `Jovian → Encounters → Encounter Browser`. +- `Jovian.PopupSystem` — popup/dialog UI +- `Jovian.ZoneSystem` — zone/region management +- `Jovian.Logger` — developer logging +- `Jovian.InspectorTools` / `JovianUtilities` — editor and general utilities diff --git a/Packages/com.jovian.encounter-system/Editor.meta b/Packages/com.jovian.encounter-system/Editor.meta new file mode 100644 index 0000000..8976890 --- /dev/null +++ b/Packages/com.jovian.encounter-system/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d89f89053ce0384c9f7b48a5b491bca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs b/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs new file mode 100644 index 0000000..c2736e0 --- /dev/null +++ b/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs @@ -0,0 +1,106 @@ +using Jovian.EncounterSystem; +using UnityEditor; +using UnityEngine; + +namespace Jovian.EncounterSystem.Editor { + /// Id dropdown (library inherited from the owning asset's library field) + inline fallback + resolved preview. + [CustomPropertyDrawer(typeof(DialogLineRef))] + public class DialogLineRefDrawer : PropertyDrawer { + private const string NonePlaceholder = ""; + private const string EmptyLibraryPlaceholder = ""; + private const float PreviewHeight = 32f; + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { + var idProp = property.FindPropertyRelative("id"); + var inlineProp = property.FindPropertyRelative("inlineText"); + var library = ResolveLibrary(property); + + EditorGUI.BeginProperty(position, label, property); + + var lineHeight = EditorGUIUtility.singleLineHeight; + var spacing = EditorGUIUtility.standardVerticalSpacing; + + var idRect = new Rect(position.x, position.y, position.width, lineHeight); + DrawIdPicker(idRect, library, idProp, label); + + var inlineRect = new Rect( + position.x, + position.y + lineHeight + spacing, + position.width, + lineHeight * 2); + EditorGUI.PropertyField(inlineRect, inlineProp, new GUIContent("Inline")); + + var previewRect = new Rect( + position.x, + position.y + lineHeight + spacing + lineHeight * 2 + spacing, + position.width, + PreviewHeight); + DrawPreview(previewRect, library, idProp, inlineProp); + + EditorGUI.EndProperty(); + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { + var lineHeight = EditorGUIUtility.singleLineHeight; + var spacing = EditorGUIUtility.standardVerticalSpacing; + // id + (inline 2 lines) + preview + return lineHeight + spacing + lineHeight * 2 + spacing + PreviewHeight; + } + + private static DialogLineLibrary ResolveLibrary(SerializedProperty property) { + var libraryProp = property.serializedObject.FindProperty("library"); + return libraryProp?.objectReferenceValue as DialogLineLibrary; + } + + private static void DrawIdPicker(Rect rect, DialogLineLibrary library, SerializedProperty idProp, GUIContent label) { + if(library == null || library.lines == null || library.lines.Count == 0) { + using(new EditorGUI.DisabledScope(true)) { + EditorGUI.Popup(rect, label.text, 0, new[] { EmptyLibraryPlaceholder }); + } + return; + } + + var count = library.lines.Count; + var ids = new string[count + 1]; + var names = new string[count + 1]; + ids[0] = string.Empty; + names[0] = NonePlaceholder; + + var currentIndex = 0; + for(int i = 0; i < count; i++) { + var line = library.lines[i]; + var id = line?.id ?? string.Empty; + ids[i + 1] = id; + names[i + 1] = string.IsNullOrEmpty(id) ? $"" : id; + if(id == idProp.stringValue && !string.IsNullOrEmpty(id)) { + currentIndex = i + 1; + } + } + + var newIndex = EditorGUI.Popup(rect, label.text, currentIndex, names); + if(newIndex != currentIndex) { + idProp.stringValue = ids[newIndex]; + } + } + + private static void DrawPreview(Rect rect, DialogLineLibrary library, SerializedProperty idProp, SerializedProperty inlineProp) { + var id = idProp.stringValue; + var inline = inlineProp.stringValue; + + string resolved = null; + if(library != null && !string.IsNullOrEmpty(id)) { + resolved = library.Resolve(id); + } + if(string.IsNullOrEmpty(resolved)) { + resolved = inline; + } + + var style = new GUIStyle(EditorStyles.helpBox) { + fontStyle = FontStyle.Italic, + wordWrap = true + }; + var label = string.IsNullOrEmpty(resolved) ? "" : resolved; + EditorGUI.LabelField(rect, new GUIContent("Preview: " + label), style); + } + } +} diff --git a/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs.meta b/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs.meta new file mode 100644 index 0000000..50ba8b5 --- /dev/null +++ b/Packages/com.jovian.encounter-system/Editor/DialogLineRefDrawer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: a55b866cc153f5749a71928930faeb62 \ No newline at end of file diff --git a/Packages/com.jovian.encounter-system/Editor/EncounterBrowserWindow.cs b/Packages/com.jovian.encounter-system/Editor/EncounterBrowserWindow.cs new file mode 100644 index 0000000..3aea7ea --- /dev/null +++ b/Packages/com.jovian.encounter-system/Editor/EncounterBrowserWindow.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Jovian.EncounterSystem; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Jovian.EncounterSystem.Editor { + /// Browser for every encounter across all tables. Search + kind filter + detail pane. Quest chains render as a tree rooted at the first step. + public class EncounterBrowserWindow : EditorWindow { + private const string AllKinds = "All"; + + private class Record { + public EncounterTable table; + public int index; + public IEncounter encounter; + } + + private readonly List allRecords = new(); + private string searchText = string.Empty; + private string kindFilter = AllKinds; + + private readonly Dictionary> issuesByEncounter = new(); + + private TreeView treeView; + private VisualElement detailPane; + private ToolbarMenu kindDropdown; + + [MenuItem("Jovian/Encounters/Encounter Browser")] + public static void Open() { + var window = GetWindow("Encounters"); + window.minSize = new Vector2(640, 360); + } + + private void CreateGUI() { + BuildToolbar(); + BuildSplit(); + Refresh(); + } + + private void BuildToolbar() { + var toolbar = new Toolbar(); + + var search = new ToolbarSearchField(); + search.style.flexGrow = 1f; + search.RegisterValueChangedCallback(evt => { + searchText = evt.newValue ?? string.Empty; + ApplyFilter(); + }); + toolbar.Add(search); + + kindDropdown = new ToolbarMenu { text = $"Kind: {AllKinds}" }; + foreach(var choice in GetKindChoices()) { + var captured = choice; + kindDropdown.menu.AppendAction(captured, _ => { + kindFilter = captured; + kindDropdown.text = $"Kind: {captured}"; + ApplyFilter(); + }); + } + toolbar.Add(kindDropdown); + + var refreshButton = new ToolbarButton(Refresh) { text = "Refresh" }; + toolbar.Add(refreshButton); + + rootVisualElement.Add(toolbar); + } + + private void BuildSplit() { + var split = new TwoPaneSplitView(0, 280, TwoPaneSplitViewOrientation.Horizontal); + split.style.flexGrow = 1f; + rootVisualElement.Add(split); + + treeView = new TreeView { + makeItem = MakeRow, + bindItem = BindRow, + fixedItemHeight = 22, + selectionType = SelectionType.Single + }; + treeView.selectionChanged += OnSelectionChanged; + treeView.style.flexGrow = 1f; + split.Add(treeView); + + detailPane = new ScrollView(ScrollViewMode.Vertical) { + style = { paddingLeft = 8, paddingTop = 8, paddingRight = 8, flexGrow = 1f } + }; + ShowEmptyDetail(); + split.Add(detailPane); + } + + private static VisualElement MakeRow() { + var row = new VisualElement { + style = { + flexDirection = FlexDirection.Row, + alignItems = Align.Center, + paddingLeft = 6, + paddingRight = 6, + height = 22 + } + }; + + var badge = new VisualElement { + name = "issue-badge", + style = { + width = 8, + height = 8, + marginRight = 6, + borderTopLeftRadius = 4, + borderTopRightRadius = 4, + borderBottomLeftRadius = 4, + borderBottomRightRadius = 4, + visibility = Visibility.Hidden + } + }; + row.Add(badge); + + var label = new Label { + name = "row-label", + style = { + flexGrow = 1f, + unityTextAlign = TextAnchor.MiddleLeft + } + }; + row.Add(label); + + return row; + } + + private void BindRow(VisualElement element, int index) { + var record = treeView.GetItemDataForIndex(index); + var label = element.Q