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.
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.
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).
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.
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.
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.
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.
Reflecting on a huge comeback to programming…
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!
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.
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.