Poyong

How can we introduce narrative in a virtual immersive medium using new and innovative mechanics while maintaining VR UX best practices?

 

Project Details

Poyong was created as the final project for the DMED501: Visual Storytelling course at the Centre for Digital Media. Projects must include some form of interactive storytelling and branching narrative.

 

Timeline

Jan — Apr 2022
13 weeks

 

Role Summary — Unreal Developer

Responsible for developing and designing all gameplay systems in Unreal Engine 4.

Team

1 Narrative Designer
1 3D Artist
1 Unreal Developer

About the Game

When a mysterious foreign army invades and upends the peaceful village of Pasir Emas, a desperate Harun Zukifli carries a cursed weapon into a boggy battle while searching for his closest friend. His decisions that follow may decide the fate of his village and the known world. He comes face-to-face with Poyong, the demon that resides in his cursed weapon.

Poyong is a 10-15 minute VR game that explores how VR can introduce narrative delivered through a dialogue system. Players can move, pick up objects, and interact in Poyong using a dialogue window that appears spatially whenever they trigger a dialogue sequence.

Reveal Trailer

Full Playthrough

 

Key Responsibilities

In Poyong, I worked as the Unreal Developer and Game Designer:

  • Developed and designed all gameplay systems for Poyong in Unreal Engine 4:

    • Dialogue system with spatial dialogue choice window and world space subtitles

    • Scripted events through player interactions to indicate major game state changes

    • Backend disposition system to quantify and track player’s dialogue and non-dialogue choices

    • Non-dialogue interactions to allow the game to react to unconventional player actions (e.g. Tossing a sword multiple times activates unique dialogue)

    • Ending branching system to determine one of three endings based on the backend disposition system

    • Spatial UI for menus and credits

  • Designed end-to-end player experience of Poyong, accommodating for unique cases and possible player actions.

  • Collaborated with a narrative designer to accurately flesh out visual and dialogue-based storytelling.

  • Consulted on the accuracy of adapting Malaysian elements to narrative and art elements throughout Poyong.

Designing and developing a new reality

With virtual reality (VR), we are immersing users in an entirely foreign and fresh experience which can be overwhelming. However, this new medium allows for maximum sensory engagement and interactivity compared to traditional 2D and 3D mediums. This meant that we had to fulfill a variety of criteria when designing for gameplay and UX in VR…

Interactions need to be rich but simple to execute

Take care in the design and flow of interactions to avoid sensory and cognitive overload

Script for as much interactivity in all situations to maximize immersion when possible

Refrain from innovating too quickly, stick to conventions when possible

 

Highlights

 

Immersive world space dialogue system

One of the core themes we wanted to explore in Poyong was allowing players to react to narrative delivery in game. With our love for RPGs, we wanted to attempt a dialogue system similar to traditional dialogue systems in CRPGs such as Baldur’s Gate or Divinity. These systems had values (known as disposition values) tied to dialogue choices that affected how the game reacts to players. However, as VR was unlike traditional 2D/3D mediums due to its immersive nature, we needed to find a way to display dialogue that fits seamlessly into the world. We found that a dialogue system that existed in world-space would allow the players to understand the breadth of dialogue choices they had while also increasing readability of subtitles in VR.

I followed Reids’ tutorial on YouTube to create the backend of our dialogue system. The dialogue tree was built on Unreal Engine’s behavior tree class, with tasks for Poyong speaking and player replies. The subtitles are displayed on a world-space actor containing a widget component that spawns a certain distance from the player whenever they activate a dialogue interaction (by stepping into a trigger area). The player’s corresponding replies to the dialogue interaction was adapted to OpenXR’s menu actor that allows players to view choices on their left or right VR controller. Players can then select any of the dialogue options presented to them by pointing at it with the opposing controller or activating a cursor with the same controller.

This promoted VR interactivity and immersion for the player to feel like their dialogue selections are connected to themselves.

A typical dialogue interaction flow

We prototyped the dialogue system in low fidelity at the beginning, allowing us to squash any bugs that came up while adapting it to OpenXR’s menu actor

After fixing bugs related to consecutive dialogue areas not popping up, we stylized the dialogue window and subtitles using materials and font faces

 

Scripted VR cutscenes

In addition to a dialogue system, we also wanted to help the player feel as if their actions have an impact on the world. To achieve this, we needed to link player actions to a type of mechanic that indicated major game state changes and story progression within our narrative-driven game. To achieve this, we decided to explore how cutscenes would play out in VR.

However, we couldn’t stick to how cutscenes were conventionally done (by cutting to a new scene with multiple cameras), it had to happen in real-time. Conventional cutscenes were also risky in VR as it may disorient players if their viewports were constantly switching between cameras, causing physical discomfort. Working with our narrative designer, we designated specific areas in the level that triggered these real-time events. I also utilized the environment to our advantage by blocking out distracting visual elements (e.g. a torch) and spatial sound to direct the players attention towards these events.

A battle sequence in the distance that activates when the player steps into a trigger area, showing a nearby fight between two parties

The climax sequence triggered by the player dropping their sword into the fire and summoning Poyong

 

Accounting for unique player behavior

In VR, players have the freedom to interact with a new world in any manner they wish to. This meant that they could freely move or interact with props we provided them with. Unlike traditional 2D/3D mediums that typically wouldn’t allow these behaviors, there would be an almost infinite array of unique player actions that we needed to account for. However, at the same time, we wanted to reward players for thinking beyond the capabilities of a new medium by letting the game react to these actions.

We needed to account for unique player behavior throughout the game. I worked with our narrative designer to brainstorm various actions that players would take in game. An example includes Poyong reacting angrily to the player if they dropped the sword multiple times (which was a common occurrence in VR, players would toss objects consecutively to explore the physics).

If the player drops their sword more than three times, Poyong reacts to it by threatening the player multiple times

If the player doesn’t place the sword in the fire to activate the climax and instead walks into the sea, Poyong tries to sway the player to turn back

 

Linear level design to deliver a linear experience

Poyong’s level was designed to be linear without branching paths to deliver a linear narrative experience.

I worked with our narrative designer to build the flow of the story and understand how he wanted it to be presented in game. I followed the story beats that he designed and wrote to create a basic level design with denoted points for significant events (e.g. Poyong summoning). I wanted the player to use the opening area as an onboarding section to get used to the smooth locomotion movement system in VR.

Top-down view of the level

Initial level greybox in Unreal

Level layout version 2

Final level layout

 

Backend disposition system tracking

Across the dialogue system and direct or indirect actions that players can take, any object or system in the game can have an impact on the player’s total disposition count. This disposition count can trigger instanced events in the game, such as a sound effect that plays when the player hits a disposition count of 5, and determine which ending the player will get.

This meant that I needed to create a backend system that would allow our team to assign a disposition value to any actor or system in the game. I needed to find a way to:

Modularly assign disposition values to any action or dialogue choice

Track total concurrent player disposition count

Check if player disposition count hit certain thresholds, triggering a response

To achieve this, I used a combination of behavior trees, actors, and game instances to implement this system.

In the behavior tree, integer values are tied to dialogue options, passing them on to dialogue area manager actors. These managers then track these values for instanced low-level responses to value thresholds achieved by the player.

Simultaneously, the total disposition count is passed to the Game Instance class to determine the overall disposition count, dictating which ending the player gets.

Disposition values tied to each dialogue option gives players control over how they portray Harun and story direction

Disposition values tied to dropping their sword multiple times is an example of the game reacting to players’ non-dialogue actions

 

Ending story branching system

As our game revolved around reactivity towards players’ actions, we also needed to create an ending branching system that was tied to our players’ disposition counter. This would serve as a culmination of the journey our player took to get here. Building this system meant that depending on the player’s final disposition counter, players would get a different voice line and subtitles in a separate ending scene that indicated whether they:

Allowed Poyong to possess them

Successfully denied Poyong’s possession

Failed to deny Poyong’s possession

To achieve this, the ending branching system has to:

Determine the player’s final disposition counter

Communicate the player’s ending branch to the game instance

Allow the game instance to pull relevant assets related to the corresponding ending branch

Pass assets to the final ending scene

I used the Game Instance class and inRange function to determine the ending branch of the player depending on their disposition value and stored it in an Enum variable. This Enum variable then passes on a voice line and ending text which corresponded to the ending branch into an actor placed in the ending scene to display them.

Determining the final ending branch using disposition values stored in the game instance, then passing it to the Enum variable

With the Enum variable finalized, I can pass the relevant ending’s assets (voice lines, relevant subtitles) to the ending scene

 

Editor tools to allow easy design changes

While working with our narrative designer, we realized that we needed to find a way to easily transfer dialogue texts from Milanote, the tool he used to visualize dialogue branches, into Unreal Engine. This would allow us to cut down on the back and forth between designers and developers to modify simple parameters (e.g. dialogue texts). Hence, I needed to create a pipeline and documentation that facilitated this process smoothly. This pipeline should aim to:

Easily create or modify dialogue in our game without affecting other systems in place

Onboard our narrative designer to Unreal Engine steadily through editor tools and simple visualizations

Simplify the process of transferring content from one platform to the other as our narrative designer hadn’t worked in Unreal prior

As our dialogue system was created on Unreal’s behavior trees, we created input fields in editor corresponding with dialogue branches on Milanote. These fields included the text to display as subtitles and a voice line that determines the length of which the text will be displayed for. The Node Name field references standardized dialogue codes on Milanote that allowed us to easily identify and match different dialogue branches across both platforms.

(click to view more)
Dialogue branches in Milanote for branch D20P16 translated to…

(click to view more)
Behavior tree in Unreal for branch D20P16 inputted by our narrative designer using the editor

 

Reflecting on a huge comeback to programming…

  1. Feeling great to be back, developing

    I used to be a computer science major in university before switching to psychology. It felt good to put on my programmer hat again. Even though I only used blueprints in Unreal Engine, it was extremely rewarding to be able to work through problems by breaking them down, step-by-step. Unreal Engine reignited my love for programming, and Poyong manifested this love into a tangible product!

  2. VR game design

    Poyong was the first VR game I’ve built. I learnt that VR game design differed slightly from traditional game design, where there was a larger emphasis on using various senses to draw the player’s attention. There’s also a huge focus on immersion and how our mechanics and any form of UI should contribute towards immersing players in a VR world. My understanding of attention and perception from psychology came in handy when I designed various triggers in game. We also had to be cognizant of UX in VR, understanding that a large group of users will probably suffer from motion sickness and ergonomic issues, hence we had to avoid immersing players too quickly into new mechanics we wanted to introduce.

  3. Narrative influences game design

    This was also my first time working with a narrative designer to create a game. I never understood how narrative could impact the mechanics of the game. However, working with Marshall (our narrative designer) made me realize that mechanics had to make sense in a narrative premise. This premise subsequently influenced the level and environment design for things in the world to make sense. I finally made the connection through Poyong that games are immersive because of the stories we built that make the world come to life. Without a lively world, games would be devoid of soul.