top of page

Gameplay Video 

Dialogue System

Ink Framework  diagram 

InkFramework.drawio.png

Problem:
NPCs needed to hold multiple story states and reveal different dialogue depending on which clues the player had found.

 

Approach:
Built a reusable Ink↔UE5 framework, then a dialogue manager on top of it. Each NPC has a first-meeting state and a loop state; discovered clues set Ink variables that unlock new dialogue options across every NPC. Per-NPC state lives in a shared parent NPC Blueprint rather than duplicated per character, and updates the corresponding Ink variable on state change ,keeping Unreal's state and Ink's story state in sync.

 

Tradeoff:
Chose Ink over a native Blueprint dialogue tree for readable, fast-to-iterate branching logic and at the cost of UE5 having no native Ink support, meaning the integration itself had to be built from scratch with little community documentation to draw on.

 

Implementation:
A dialogue manager Blueprint drives the Ink story through four events: On Story Begin (executes the story, updates text), On Continue (pushes next line), On Make Choice (displays and resolves choices), On Story End (closes the conversation).

The four core events driving the dialogue manager: Story Begin, Continue, Make Choice, and Story End."

Screenshot 2026-06-26 112621.png

Checking whether this is the NPC's first meeting, then setting the Ink variable that switches their story from first-meeting to loop

Screenshot 2026-07-13 023915.png

Screenshot showing   story start event

Screenshot 2026-06-26 112030.png

Journal system

Jornal Flow Diagram

JournalSYstem.drawio.png

Problem:
Investigation information (clues, suspects, locations) needed a central place for players to review, updating automatically as new information was discovered.
 

Approach:
A shared interaction interface handles all three types identically at the point of interaction ,retrieval doesn't care which type it hit. From there, each type fires its own Event Dispatcher, which triggers that tab's rebuild.
 

Tradeoff:
Used three separate Event dispatchers instead of one shared dispatcher, since each tab rebuilds from a different struct array and would've needed to branch by type regardless so splitting them kept each update event simple rather than adding a branch inside one shared handler.
 

Implementation:
Each dispatcher triggers: Clear Children (empty that tab's scroll box) → For Each Loop (iterate that type's struct array) → Create Text Widget (spawn an entry) → Add Child (insert into the scroll box). The Journal UI's three pages bind to their respective dispatcher on Event Construct.

The three core events driving journal system

Screenshot 2026-07-13 163204.png
Screenshot 2026-07-13 163132.png
Screenshot 2026-07-13 163055.png

Screenshot showing UI of the journal system

Screenshot 2026-07-13 163410.png

Interaction

Interaction Flow Diagram

Untitled Diagram.drawio(2).png

Problem:
Players needed a consistent way to interact with NPCs, clues, and locations ,18 individual interactables (5 NPCs, 8 clues, 5 locations) that each needed different resulting behavior.
 

Approach:
Pressing E fires a single line trace. If it hits an actor implementing the Interact interface, that actor's own Interact event runs its type-specific logic, then feeds into the Dialogue and Journal systems already in place.
 

Tradeoff:
Chose an interface-driven line trace over collision-based interaction, since collision would've meant setting up and maintaining an interaction volume per object across all 18 interactables , the interface let any new interactable just implement one function and immediately work with existing input, with no per-object setup.
 

Implementation:
One Interact interface function, implemented per type (NPC/Clue/Location), each firing its own Event Dispatcher into the systems it belongs to.

Screenshot showing a debug line trace in-game

Screenshot 2026-06-26 123451.png

Checking If the hit actor contains the interface to check if it's interactable

Screenshot 2026-06-26 122041.png
Screenshot 2026-06-26 122149.png
bottom of page