Oct 31, 2025
Monster House Racing is a Mario Kart–inspired kart racer with a spooky, cartoon vibe—set inside the haunted halls of Grindstone Manor, where tight corners, creepy set-pieces, and mischievous power-ups turn every lap into chaos.
It’s available on PlayStation 5 + PS VR2, and also on Steam for PCVR. On PC, it’s built to run across modern headsets via OpenXR and common streaming setups (so systems like Meta Quest, HTC Vive, and Valve Index are all in play).
The game is designed for couch co-op, allowing up to three players to race together on a single PS5 (one in VR with PS VR2, plus up to two using DualSense controllers or a compatible steering wheel), and you can also jump in solo against AI for a quick haunted hit of high-speed fun.
Monster House Racing features:
6 playable characters and karts
8 spooky tracks
a VR comfort mode
English and Japanese language support
Monster House Racing started life as a very different game.
In late 2022, I began designing a cute Halloween-themed VR party game called Monster House Party. The concept was a set of eight short mini games connected by a larger story set inside the mysterious Grindstone Manor and its mischievous inhabitants. Each mini-game was designed as a fast five-minute challenge. Some were puzzle-based, such as match-three and hidden object style games. Others leaned more into action, such as shooting gallery sequences and maze runs.
The project was also going to draw from earlier character design work I had already done, including a large set of monster concepts developed for the Monsters and Misfits project, which featured more than one hundred original characters. The plan was to reuse that foundation to move quickly while keeping the game playful, expressive, and full of personality.
We pitched Monster House Party for government funding, both federally through Screen Australia and locally through Screenwest. While we were not successful at the federal level, we were awarded Screenwest funding. The original budget assumed support from both agencies, so when only one came through, we had a choice. We could abandon the project or reduce the scope and ship something with the resources available.
We chose to ship.
After reviewing the plan with our small team of six, we made a deliberate pivot. We took one of the original mini games and expanded it into a complete standalone title. The mini game we chose was a Mario Kart-inspired racer, and that became Monster House Racing. It is a monster-themed kart racer that takes place inside Grindstone Manor with tight corners, spooky set pieces, and chaotic power-ups.
Early in production, we had the opportunity to speak with a Sony PlayStation representative. With PlayStation VR2 still relatively new, Sony was keen to see more compelling VR titles reach players. We proposed an unusual approach and transformed the concept into a couch co-op experience. One player races in VR using PS VR2 while up to two others play alongside them using DualSense controllers or a compatible steering wheel. The idea was simple. If someone already owns a PS VR2 headset, they can invite friends over and play together. New players can get a feel for the game on a controller before trying it in VR.
At that point, we shifted primary development to PlayStation 5 and PS VR2, while keeping future versions in mind for other platforms, including PCVR and standalone headsets.
As project lead, I broke the work down into a production task plan for the team. We had three digital artists working across 2D and 3D, plus a producer. All were people I had worked with previously and whose strengths I knew well. The artists began building environments and props for the eight tracks. Unfortunately, our character rigger and animator became unavailable, so I reduced character animation to the minimum needed for the game and took on the rigging and animation work myself.
Later in production, we brought in a local audio designer who helped build the game’s soundscape using FMOD, including kart engine audio, music loops, and sound effects.
From there, it became a full production effort. We built, iterated, optimised, integrated, tested, and pushed through console certification while keeping the core promise intact. It needed to be a fun, spooky, family-friendly kart racer that feels great both in VR and on screen.
As the programmer on the project, I came into Monster House Racing without prior PlayStation development experience, so I began with focused research and development on the systems that would define the game’s technical foundation.
The first and most important area was rendering. The game needed to support couch co-op with a PS VR2 player and up to two non-VR players on a TV. That meant the rendering system had to be highly flexible. If only the VR player were present, the headset view needed to be mirrored cleanly to the TV. If one non-VR player joined, the TV needed to switch to a full-screen non-VR view. If two non-VR players joined, the TV needed to split horizontally and show both players. All of those configurations also needed to work while a VR player was active, and players needed to be able to join or leave at any time.
My first approach was straightforward and used one Unity camera per player. However, I quickly ran into a strange performance problem. If I had a non-VR camera rendering to the TV and then added a second camera for the PS VR2, the frame rate would drop and lock to 60 fps.
After experimenting with different approaches, I found a reliable workaround. Rendering the views into render textures and then drawing those textures to the screen through a full-screen UI avoided the frame rate drop when the PS VR2 render was active. With that in place, I built a ScreenManager singleton that configures the entire camera and output setup dynamically based on the current players and their input type. It also supports players joining and leaving during play.
The ScreenManager also had to handle camera culling layers. Several UI elements and gameplay objects needed to be visible only to a specific player. To solve this cleanly, the system waits until a player camera is created, then applies the correct culling settings and per-player visibility rules so each camera renders only what it should.
Another tricky camera-related feature was fading. When transitioning between scenes, I fade to black, load the next scene, then fade back in. I had an existing VR fade system from previous projects, but Monster House Racing uses multiple cameras and multiple output targets, so I built a new MultiCameraFader component. That allowed a single call to fade out or fade in all active cameras consistently across VR and TV views.
The second major area I tackled was input. I wanted Monster House Racing to support multiple control methods across VR and non-VR play, including gamepads, PS VR2 controllers, steering wheel peripherals, and keyboard and mouse for fast iteration inside the Unity Editor. To make that manageable, I built an input layer that abstracts device-specific details away from gameplay.
The core of the system is an InputMapper that listens for input signals from any connected device and maps them to consistent in-game actions. That let me create device-specific wrappers whose main job is to translate raw device input into a shared set of events. Some mappings were simple, while others required more specialised handling. For example, steering on a gamepad uses a thumbstick, VR steering uses controller rotation around a virtual wheel, a steering wheel provides a rotation value from the hardware, and keyboard steering is driven by key inputs. The point of the system was that the gameplay code responds to the same high-level actions regardless of device.
I also made the input layer context-aware. It knows whether the game is in a title screen, menu, race, or options screens, and only routes the inputs that make sense for that state. This avoids accidental input leakage and helps keep menus and gameplay responsive and predictable.
When the project shifted to PlayStation 5, steering wheel support felt like an obvious fit for a kart racing game. Unity’s input solution did not support PlayStation steering wheel peripherals out of the box, so I wrote a custom C++ plugin using the PlayStation 5 SDK. It had been a while since I had written C++ professionally, but once the toolchain was in place, I was able to build a working test plugin quickly. The greater effort was integrating it properly and pulling the full set of data needed. That included not only steering angle, but also buttons and pedal inputs, and the device-level details required to read that raw data reliably.
One of the more complex parts of PlayStation development was input device association. DualSense controllers and steering wheels need to be associated with PlayStation user accounts, and PS VR2 behaviour adds another layer on top since the headset is tied to the account that launched the game. That became particularly important once trophy support entered the picture, because trophies and player identity are tightly connected. To handle this cleanly, I updated the input system with a PlayStation-specific layer that enforces one input device per account and keeps player identity consistent. On other platforms, this rule is not required, so the system treats it as a platform-specific policy rather than a core limitation.
As development progressed, I also extended the C++ plugin to support the DualSense lightbar. I used that to reinforce player identity in couch co-op by matching the controller lightbar colour to each character or kart accent colour, making it easier for players to track who is controlling what at a glance.
Loading screens for some of the supported input devices
Monster House Racing makes extensive use of my CustomEvent system. It is a lightweight event framework I built a few years ago that sits between standard C# events and UnityEvents. It supports events with up to six parameters and is designed to work cleanly across both MonoBehaviour and non MonoBehaviour code.
One of the key benefits is automatic cleanup. Scripts can subscribe to CustomEvents without needing brittle manual unsubscribe code everywhere. If the subscribed method belongs to a MonoBehaviour, the subscription is removed automatically when the GameObject is destroyed. If the subscriber is a non-MonoBehaviour class instance, the subscription is removed when that instance becomes null. This makes it safe to use anonymous methods and short-lived subscriptions without slowly accumulating event leaks over time.
I used CustomEvents throughout the project, especially for handling player input and game state flow. For Monster House Racing, I intentionally avoided building a separate hierarchical state machine, which is an approach I have used on earlier projects. Instead, I tried a GameObject-based state system that keeps the state visible and easy to debug inside the Unity Editor.
The approach is simple. Each player is represented by a player root GameObject that is instantiated from a prefab. When the player enters a new mode, such as joining a race, a corresponding state prefab is instantiated into the scene and parented under that player. For example, a PlayerRacingState prefab is created for that player. I also instantiate a prefab for that player’s input layer. When a new state is created, any existing state object for that player is destroyed first, so only one state is active at a time.
Most state objects subscribe to CustomEvents and filter for events that apply to their owning player. For example, PlayerRacingState listens for race-related actions invoked by the InputMapper. When a steering event is raised, the state checks whether the event belongs to its player, then applies steering to that player’s kart.
This GameObject-based approach had a practical benefit during development. Because inputs and states exist as scene objects, it is easy to inspect what each player is currently running while debugging in the editor. It is also easy to pause or suspend behaviour by toggling GameObjects on and off. For example, when opening an options menu, deactivating the relevant state objects effectively pauses their logic without needing extra complexity in the state code.
Once the core rendering and input systems were stable, I focused on the overall visual look. Early prototypes leaned toward a toon rendered style, which suited the original performance target and made it easier to blend purchased assets with bespoke art. After shifting to PlayStation 5, I chose to push the look further and moved toward a soft subsurface scattering style inspired by soft vinyl designer toys.
To achieve this, I built a custom subsurface scattering (SSS) shader in Shader Graph. I already had custom Shader Graph nodes from earlier experiments that expose real-time lighting and baked global illumination data, including lightmaps and light probes. For Monster House Racing, I expanded this shader with additional controls such as rim lighting and emission. Rim lighting helped highlight important objects like pickups, and emission allowed selective glowing details that could be boosted through post-processing. The shader exposes a set of parameters to control the balance of real-time light, baked GI, scattering strength and colour, rim intensity, and emission so the look could be tuned per character and per environment material.
The original plan was to prototype in Shader Graph and later rewrite the final version in HLSL. After profiling, Shader Graph performance was already good enough, so I kept it in Graph form. It also scaled better than expected and ran acceptably on lower power headsets such as Quest and Pico, which helped later when expanding platform support.
Some of the Monster House Racing art assets using the SSS shader.
Comparing the low-poly, toon shading vs the high-poly, sub surface scattering shader.
To support the shader’s baked GI inputs, I set up a consistent pipeline for lightmap baking and light probe placement. For baking, I used Bakery. The project structure also influenced tooling. The game additively loads a scene containing the full Grindstone Manor environment. Because those baked lightmaps are authored in that scene, I wrote a LightmapLoader tool to ensure the correct lightmaps are loaded and applied reliably when the environment scene is streamed in at runtime.
For light probes, the requirement was simpler. Most gameplay happens along the track, so probes only need to follow the racing path. I wrote a small editor tool that places light probes along the track path at a consistent height. That meant probe placement could be rebuilt at any time with a single button press, even as tracks evolved during development.
The lighting in the game is a mix of baked lightmaps and lightprobes, and real-time.
Post-processing was the final step in defining the look. Bloom was particularly important for the Halloween theme and for making emissive materials read well. On PlayStation 5, the performance cost was minimal. On standalone headsets, it was more noticeable and could push the frame rate under the minimum, 72fps.
To keep performance consistent, I built a custom occlusion zone system. The approach is deterministic rather than continuously evaluated. When a race starts, the full Manor scene loads once during the loading screen, then the chosen track loads. Each track defines which pre-authored zones of the manor it uses. The OcclusionZoneManager then removes all other rooms and non-essential content not required for that track. I initially tried Unity’s built-in occlusion culling, but it did not behave reliably for this layout, and it is designed as a continuously running runtime system. A track-based system fitted the game better because only a subset of the manor is needed for any given race.
This zone-based culling was enough to keep post-processing enabled while still running smoothly on lower power platforms such as Meta Quest 3 and Pico 4S.
For track creation and runtime track generation, I used Dreamteck Splines. I evaluated several spline options and considered building a custom solution, but Dreamteck Splines had the feature set and runtime performance I needed across both console and standalone headsets.
I also experimented early with physics-driven karts, but in VR, a first-person kart that bumps and jitters with physics can trigger motion sickness very quickly, especially during drops or track edge cases. To address this, I switched to a spline-constrained driving model. Karts move along a computed spline and are allowed a controlled horizontal offset around the spline to support steering. The result feels smooth in VR while still allowing skill-based driving.
Collisions were handled with lightweight logic tuned for comfort and clarity. When a kart impacts another from behind, acceleration is reduced, and a small steering push is applied to encourage separation rather than chaotic physics reactions. In play, this feels responsive and adds strategy, because players need to navigate around opponents rather than relying on ramming.
Because Dreamteck Splines generates the track mesh at load time, I also added a quality option for lower-end hardware, where the generated mesh can be made coarser. This does not affect driving, since driving is based on the mathematical spline rather than mesh collision fidelity.
Dreamteck Splines also made a number of gameplay tasks easier. It can place objects along the spline, so I used it to position pickups and to define starting grid locations. It also simplified race position ranking, since kart placement can be calculated from distance along the spline combined with lap count.
Tracks are built using the Dreamteck Splines asset.
Monster House Racing includes four pickup types, each spawned at pre-designed locations along the track. Pickups are collected by driving through a rotating pickup icon, which then triggers an immediate effect or grants the player a usable item.
Speed Boost is an instant pickup that gives the kart a temporary acceleration increase. The effect is reinforced with a fiery particle trail so players can read the boost clearly in the middle of a race.
Rocket pickups grant a single rocket that can be fired at any time with a button press. Rockets automatically lock onto the kart directly ahead of the firing player. If the firing player is currently leading, the rocket targets a random opponent to avoid wasted shots. When a rocket hits, the target kart is slowed for several seconds, with visual feedback such as a steam effect from the front of the kart and a reduced top speed during the slowdown window.
Pumpkin Bomb pickups can be dropped onto the track behind the player’s kart. Any kart that hits a bomb is slowed using the same slowdown rule and feedback as rockets. This includes the kart that dropped the bomb, which keeps the mechanic fair and encourages deliberate placement rather than careless spamming.
Red Ghost pickups behave as track hazards rather than held items. If a kart drives through a rotating red ghost, it is slowed for several seconds using the same slowdown behaviour and visuals.
To keep gameplay readable and avoid stacking frustration, slow effects do not compound. If a kart is already slowed, additional rockets, bombs, or ghosts do not apply further slowdown until the current effect ends.
From a technical standpoint, I built the pickup system using modular components. Each pickup type is a GameObject behaviour that references its data through ScriptableObjects derived from an abstract KARTING_Pickup base class. This kept pickup behaviour consistent while allowing tuning and iteration through shared data assets.
For development and testing, I also created a PickupDebugger tool that lets me award specific pickups to karts on demand. That made it much faster to validate balance, effects, edge cases, and multiplayer behaviour without needing to drive laps to reach pickup spawns.
In-race pickups: Speed boost, Rocket, Pumpkin Bomb, Red Ghost.
Monster House Racing uses a lightweight AI system designed to keep races fun and competitive without adding unnecessary complexity. Races always contain at least four karts, and since up to three can be human-controlled, there is usually at least one AI kart in play and sometimes more.
AI karts follow the same spline-based driving model as players. Each AI kart is assigned a lane offset on the spline and drives forward while trying to maintain that lane position. To keep the behaviour from feeling too robotic, lane selection is periodically changed. If an AI kart collides with another kart, or when it completes a lap, it randomly chooses a new lane offset. This small variation is enough to create the impression that AI karts are adjusting their driving line and reacting to traffic.
Pickup usage is handled with simple timing logic. When an AI kart collects a pickup that can be used later, it starts a random timer. When the timer completes, the AI triggers the pickup, such as firing a rocket or dropping a bomb. This produces believable behaviour and keeps pickup use unpredictable without needing complex decision making.
To improve race pacing, I implemented a mild rubber banding system based on each AI kart’s position relative to human players. Any AI karts that are ahead of the leading human-controlled kart are subtly slowed, which helps keep the front of the pack within reach. Likewise, AI karts that fall behind the slowest human-controlled kart receive a small speed boost. Combined with pickups, this keeps the race tight and competitive without making the AI feel unfair.
Monster House Racing uses a mix of background music and in-race sound effects such as kart engines, collisions, and pickups. To support the project’s audio needs, I built a custom AudioManager that can play both Unity AudioSources and AudioClips as well as FMOD events.
This setup was primarily about flexibility and workflow. Simple one-shot UI sounds were quick to implement using Unity audio, while FMOD was better suited to more complex audio tasks such as seamless looping music, engine sound modelling, and richer impact and movement effects. Having both systems available meant we could choose the right tool for each sound without forcing everything into a single pipeline.
Implementation-wise, I structured AudioManager as an abstract base class with partial class extensions. One partial class handled Unity AudioSources and clips, and another handled FMOD support with FMOD-specific overloads. This was my first time using partial classes for extensibility, and it worked well as a clean way to keep a single public audio interface while allowing backend-specific implementations. It also sets the system up for future expansion, such as adding another partial class to support the Wwise middleware solution.
There was also an interesting mixing problem driven by couch co-op. Players can be in different physical positions on the track, but TV audio is shared. The solution was to bias audio for non-VR TV players slightly left or right, depending on their split-screen side, while keeping the VR player’s audio centred. Combined with strong background music and careful level balancing, this produced a mix that felt clear enough without needing complicated per-player spatialisation.
One of the more complex systems in the game was the options menu. Any player can open it at any time, which pauses gameplay and brings up a settings interface with checkboxes, sliders, and menu actions. Settings include music and SFX levels, screen brightness, VR comfort mode, language switching between English and Japanese, and the ability to return to the main menu.
The main challenge was not the UI itself, but making it work cleanly across multiple players and multiple display modes. The game can show split screen on the TV while also rendering to the VR headset, and players may be using different input devices. That raised a few design questions, such as whether only the player who opened the menu should be able to change settings, and how navigation should behave when one player is in VR, and others are on controllers.
The final approach prioritised simplicity and practicality. Any player can open the options menu, the menu is shown to all players, and any player can navigate and adjust settings. Any player can also close the menu. This avoided awkward ownership rules and made the system feel consistent during couch co-op sessions, where players may swap devices or take turns.
I also made a few small choices that improved usability. Even though gameplay pauses when the menu opens, background music continues to play, so the transition does not feel abrupt. Sound effects such as engine loops are paused while the menu is open, which keeps the menu experience calm and avoids audio fatigue if players leave the menu open. All settings are persisted using PlayerPrefs, so players do not need to reconfigure options each time they launch the game.
The in-game options screen. Accessible by VR and non-VR players.
Monster House Racing targets multiple platforms, including PlayStation 5, standalone headsets, and PC and PCVR. To keep the project maintainable across those targets, I built a PlatformHelper system that runs during the boot flow and configures the game based on the detected platform.
On startup, PlatformHelper identifies the current runtime and then additively loads a small platform-specific Unity scene. Each platform scene contains only the systems and configuration needed for that target, such as platform services integrations, headset-specific features, and any platform-only UI or settings hooks. For example, one platform scene might include an achievements integration, while another includes a different headset vendor feature set.
Using additive platform scenes ended up being simpler to manage than instantiating platform prefabs via code at boot time. It made the platform differences explicit, kept platform-only objects out of shared scenes, and reduced the amount of conditional logic spread through gameplay code. It also improved iteration since platform-specific changes could be made in isolation without risking unrelated systems.
The approach worked well for Monster House Racing, and it is a pattern I plan to continue using and extend for future multi-platform projects.
To accelerate the VR side of Monster House Racing, I leaned on my custom GXR Framework. This is a growing set of roughly 40 Unity scripts and tools I have built and refined over the past decade of XR development. Having a consistent foundation meant I could stand up VR camera and input rigs quickly across Meta Quest, Pico, and PCVR targets, then spend more time on gameplay, polish, and platform integration.
GXR includes a mix of runtime components and editor-friendly utilities that solve the repeated problems that show up in XR projects. Examples include an in-headset LogManager for debugging, an FPS counter and diagnostics helpers, a lightweight Singleton pattern, UI canvas interaction helpers, haptics management, pause and resume handling, and common XR rig building blocks. Using GXR on this project reduced setup overhead, kept platform differences contained, and made it easier to iterate on VR-specific behaviour without re-solving the same plumbing in every scene.
Late in production, we were invited to show Monster House Racing at a game event in Japan, so I implemented a lightweight localisation system to support Japanese alongside English. The game does not have a huge volume of text, but it appears across lots of touch points like track names, race prompts, loading screens, control labels, options menu items, and short in-game status messages.
To keep things simple and reliable, most text is treated as key-based “static” UI. I wrote a small localisation component that sits alongside TextMeshPro objects. When a text object becomes active, it asks a central Translator service for the current language version of that string based on the player’s language setting in Options, then swaps the displayed text automatically.
For dynamic strings such as race notifications and player-specific messages, the Translator supports formatted lookups so parts of a sentence can be translated and then combined at runtime. I also handled font switching as part of the same system, since English fonts do not necessarily include Japanese glyph coverage. The end result is that players can switch between English and Japanese at any time from the Options screen, and the system is structured so additional languages can be added later without rewriting UI logic.
Monster House Racing currently supports English and Japanese.
Because PlayStation QA and the trophies pipeline added significant overhead late in production, we decided to ship a PC and PCVR version on Steam first via Early Access. To support this, I integrated Steamworks using SteamWorks.NET and implemented the Steam Achievements system.
To keep the codebase clean across platforms, I abstracted achievements and trophies behind a single interface. The Steam implementation is only enabled when the game is running on PC with Steamworks available, so other platforms simply load their own platform-specific equivalent. Compared to the PlayStation trophies workflow, the Steam integration was much faster to implement and iterate on, which made it a practical path for getting the game into players’ hands earlier. After the PlayStation release, we exited Steam Early Access as part of the full launch cycle.
As we got closer to release, we needed to capture clean trailer footage and marketing shots. To make this easier and more repeatable, I built a CameraCapture system that lets me author “capture cameras” directly into each track.
The system uses trigger zones placed along the course. When a kart enters a zone, the CameraCapture system can switch to a predefined camera setup for that moment, which makes it easy to stage consistent angles and timing while still using real gameplay. I implemented multiple camera modes to cover different shot types, including look-at, follow, move, and free cameras.
Because the project ran for a long time with lots of iterative builds, I wrote a lightweight GameVersion tool to make build tracking foolproof. Each time a new build was generated, the tool automatically incremented the version counter so every build had a unique identifier.
During development, the current version was displayed on the main menu screen. This made it easy for the team to confirm exactly which build was being tested or reviewed, and it helped speed up bug reporting and feedback by tying notes to a specific build number.
The project also makes use of a small utility I wrote called DelayedMethodCall. It provides a simple way to delay execution of a block of code, either by a specified number of seconds or until the end of the current frame. The main goal was convenience and consistency, so I could schedule short, delayed actions without having to write lots of one-off coroutines scattered across different classes.
To make it easier to debug, I also added inspector-facing debug information so I could quickly see which delayed calls were currently queued.
EditorHelper is a small Unity Editor utility I wrote to solve a common testing pain point. In Unity, pressing Play simply runs whatever scene is currently open, which can be awkward for projects that require a specific startup flow.
Many of my projects, including Monster House Racing, rely on a dedicated boot scene that loads core settings and systems before additively loading the rest of the game. EditorHelper checks whether the boot scene is active when entering Play Mode, and if it is not, it automatically opens the boot scene first. This keeps Editor testing consistent with how the game actually starts, without needing extra manual steps or custom editor UI.
To make scene management safer and easier across the project, I wrote a custom SceneReference type with a matching PropertyDrawer. This lets scripts hold direct references to Unity scenes in a clean, reliable way, rather than relying on fragile string names.
SceneReference supports both synchronous and asynchronous load and unload, plus status checks such as whether a scene is loaded or currently in the middle of loading or unloading. It can also trigger callbacks automatically when a scene finishes loading or unloading, and exposes public static CustomEvents for key lifecycle moments, including about to load or unload, started, and finished.
On the usability side, the PropertyDrawer is intentionally constrained so designers can only select scenes that are already included in the project’s Build Settings scene list, preventing invalid references and reducing integration mistakes.
The in-race mini-map was a fun system to build because it is generated automatically when a track loads. Rather than relying on a hand-authored map image, the game creates the mini-map from the loaded track data. That meant I could keep iterating on track layout and geometry during development, and the mini-map would always stay in sync without extra manual updates.
I also implemented a simple mapping utility that converts any world-space position into mini-map coordinates. This made it straightforward to place and update kart icons on the map in real time, keeping player feedback accurate even as tracks and racing lines evolved.
In-race mini-map is generated at runtime.
Throughout development, we ran multiple public playtesting sessions to validate the game with real players and gather practical feedback on controls, comfort, readability, and overall fun factor. These events were especially valuable for stress-testing couch co-op flow and VR comfort in real-world conditions.
Playtesting events included:
Let’s Break Games, a WA Games Industry Council playtesting event at The RISE in Maylands on Thursday, 2 May 2024
Pixel Expo: Act III in Perth on 28–29 September 2024
Game Lab at WA Museum Boola Bardip on Saturday, 22 March 2025
Each event produced consistent, actionable feedback that we used to refine gameplay balance, usability, and polish ahead of release.
Public playtesters at the GameLab @ WA Museum Boola Bardip.