Posted September 13, 2025 by andrew-leary
#GameDev
Plan developed with chat with Claude.io.
I like using Guthub Projects for updates for this sprint - Click here
Reflection:
- my apprentice (Claude.io) was overly enthusiastic and created a system that was too complex for me and didn't work.
- Some progress here with version 2 of above, this commit gives me confidence we are making progress:
- Trouble shooting getting UI to work when transitioning from Main Menu to Story mode. Devlog10 video
- Perseverance pays off - basic version of story mode works - commit feature: Story Mode - basic story complete with polish needed
- Demo4 uploaded to itch.io - tutorial system needs fixing: story mode panel gets in the way.
- I like using spreadsheets for UML style diagrams - see screen shot
First few hours
Each class has one reason to change:
StoryManager
→ Story progression logic only
DialogueSystem
→ Dialogue display only
HistoricalContext
→ Historical facts only
EulerNPC
→ Euler character behavior only
Open for extension, closed for modification:
IStoryElement
interface allows new story types without changing existing code
StoryMissionFactory
can create new mission types
StoryMission
base class for common behavior
Derived classes must be substitutable:
StoryMission
can replace MissionDefinition
IStoryElement
can be used interchangeably
KonigsbergMission
is-a StoryMission
Clients don't depend on unused interfaces:
IDialogueProvider
separate from IStoryProgression
IHistoricalNarrator
separate from INPCBehavior
Depend on abstractions, not concretions:
StoryManager
depends on IStoryElement
, not concrete classes
DialogueSystem
depends on IDialogueProvider
classDiagram %% Existing System (Simplified) class LearningMissionsManager { -MissionDefinition[] missions +StartMission(int index) +GetCurrentMissionIndex() } class MissionDefinition { +string missionName +JourneyType targetType +string learningObjective } %% New Story System class IStoryElement { <<interface>> +string StoryId +bool IsComplete +void Initialize() +void Execute() +void Complete() } class StoryManager { -IStoryElement[] storyElements -IDialogueSystem dialogueSystem -IHistoricalContext historicalContext +void StartStory() +void ProgressStory() +void ShowDialogue(string text) } class DialogueSystem { -TextMeshProUGUI dialogueText -Button continueButton +void ShowDialogue(string text) +void HideDialogue() +event Action OnDialogueComplete } class IDialogueProvider { <<interface>> +string[] GetDialogue(string context) +string GetIntroduction() +string GetConclusion() } class EulerNPC { -Vector3 position -Animator animator +void Appear() +void Speak(string dialogue) +void Disappear() } class StoryMission { <<abstract>> -string storyIntroduction -string historicalContext -EulerNPC euler +abstract void ExecuteStoryPhase() +void ShowIntroduction() +void ShowConclusion() } class KonigsbergMission { -int bridgesCrossed -bool puzzleAttempted +void ExecuteStoryPhase() +void ShowKonigsbergHistory() +void DemonstrateImpossibility() } class HistoricalContextProvider { -Dictionary~string, HistoricalFact~ facts +string GetHistoricalContext(string period) +string GetMathematicalExplanation(string concept) +HistoricalFact GetEulerBiography() } %% Relationships LearningMissionsManager --> MissionDefinition : contains StoryManager --> IStoryElement : manages StoryManager --> DialogueSystem : uses StoryManager --> HistoricalContextProvider : uses StoryMission ..|> IStoryElement : implements StoryMission ..|> IDialogueProvider : implements KonigsbergMission --|> StoryMission : extends EulerNPC ..|> IDialogueProvider : implements DialogueSystem --> IDialogueProvider : uses %% Integration with existing LearningMissionsManager --> StoryManager : delegates to StoryMission --> MissionDefinition : extends
sequenceDiagram participant Player participant UI as LearningMissionsManager participant SM as StoryManager participant DS as DialogueSystem participant Euler as EulerNPC participant JT as JourneyTracker Player->>UI: Start Mission 1 UI->>SM: StartStory("KonigsbergIntro") SM->>DS: ShowDialogue("Welcome to 1736...") DS->>Player: Display introduction Player->>DS: Click Continue DS->>SM: OnDialogueComplete SM->>Euler: Appear() Euler->>DS: ShowDialogue("I am Leonhard Euler...") Player->>DS: Click Continue DS->>SM: OnDialogueComplete SM->>JT: SetMissionType(Walk) SM->>UI: BeginGameplay() loop Gameplay Phase Player->>JT: Move/Cross Bridges JT->>SM: OnProgressUpdate alt Mission Complete SM->>Euler: Speak("Interesting approach...") SM->>DS: ShowConclusion() end end SM->>UI: MissionComplete() UI->>SM: StartStory("NextMission")
// Extend existing MissionDefinition public class StoryMissionDefinition : MissionDefinition { public string storyIntroduction; public string[] eulerDialogue; public string historicalContext; public string conclusionText; } // Extend LearningMissionsManager public partial class LearningMissionsManager { [SerializeField] private StoryManager storyManager; // Override existing method public override void StartMission(int missionIndex) { if (missions[missionIndex] is StoryMissionDefinition storyMission) { storyManager?.StartStoryMission(storyMission); } else { base.StartMission(missionIndex); // Original behavior } } }
public class StoryManager : MonoBehaviour { // Dependencies injected via inspector or constructor [SerializeField] private DialogueSystem dialogueSystem; [SerializeField] private EulerNPC eulerNPC; [SerializeField] private HistoricalContextProvider contextProvider; // Constructor injection for testing public StoryManager(IDialogueSystem dialogue = null, IHistoricalContext context = null) { this.dialogueSystem = dialogue ?? GetComponent<DialogueSystem>(); this.contextProvider = context ?? GetComponent<HistoricalContextProvider>(); } }
graph TB subgraph "Existing Game Systems" LMM[LearningMissionsManager] JT[JourneyTracker] BS[Bridge System] UI[MinimalModeUI] end subgraph "New Story System" SM[StoryManager] DS[DialogueSystem] HCP[HistoricalContextProvider] ENPC[EulerNPC] end subgraph "Story Content" SMD[StoryMissionDefinition] KM[KonigsbergMission] HC[HistoricalContext] end %% Dependencies LMM --> SM : delegates story missions SM --> DS : displays dialogue SM --> HCP : gets historical facts SM --> ENPC : controls NPC SM --> JT : monitors progress %% Content SM --> SMD : loads story data KM -.-> SMD : implements HCP --> HC : provides facts %% UI Integration DS --> UI : reuses text components SM --> UI : triggers updates style SM fill:#e1f5fe style DS fill:#e8f5e8 style HCP fill:#fff3e0 style ENPC fill:#fce4ec
IStoryElement
IStoryElement
, IDialogueProvider
)
This design leverages your existing architecture while adding story capabilities through clean, maintainable OOP principles.