Day 4: Refactoring Majority of the Codebase
After realising the portals need ID matching, and pedestals had to be separated between dynamic and static types, I made a new PedestalController script to determine how the pedestals behave.
Each pedestal now has the following properties: a bool "isRed" to determine its current colour, a "pairID" variable to mark its ID to match other pedestals, and a bool "ignoreLever" to determine whether it can be affected by the lever. The lever now changes the isRed state of all pedestals except the ones marked ignoreLever— these would be the static portals.
The pedestal hierarchy is a neutral pedestal parent with a child red and child blue portal/pedestal combination. By default, the pedestal starts blue and enables the blue child object. If ignoreLever is true, it also changes the sprite to a static version of the portal.
Each child coloured pedestal prefab contains its own portal component. Each portal prefab is tagged with portalSmall. The portal controller then checks all pedestals' IDs and isRed status, and their children's portalSmall tags to find their match. If its pedestal shares the same pairID and colour, they are considered linked. The target location of the portal is now programmatically set to the other portal’s transform location.
If there is no matching portal, that pedestal's portal object and logic are disabled. The portals are enabled if a match is found, and if they are not the same object (an early bug occurred when it would always teleport to itself since it was always marking itself as a valid pair). This allows a system where matching only happens if both pedestals are active and share the same traits. Otherwise, they are inactive.
The portal is then disabled on player entry and re-enabled on OnTriggerExit2D to prevent looping teleport bugs. As the teleport destination is also a portal, this ensures that the player cannot endlessly bounce between portals.
On paper, this system works. In practice, however, the new framework required a lot of variables to trigger correctly, which introduced a lot of bugs. Let's see how the code is written.
There are multiple stages in how the script detects pedestals, assigns a pair, sets coordinates, and activates the portal object.
First, the script declares every child object and component it has: both its pedestal_blue and pedestal_red GameObjects, and the coloured portals within those game objects. They are stored internally for later code to call and reference them.
It then activates the main coloured prefab depending on its isRed state. As the other components are disabled, this ensures that only the correct variables are detectable by later segments, which will be relevant when the code wants to identify pairs and enable portals.
The script then attempts to find matching pedestals. It does this by first finding pedestals with a similar ID. If there are other pedestals that have a similar ID (excluding itself), it is marked as an ID match via an internal boolean. It then searches whether the paired pedestal also has the same colour. Only when both requirements are satisfied, are two pedestals considered to be matched.
The script then attempts to create a portal between matching pedestals. It clarifies the parent pedestal's isRed state to determine what colour should it link to—obviously, a red pedestal should create a red portal, and vice versa, paired to a portal of the same colour. It then sets the target location of the teleport to the opposite paired portal.
At this stage, I was experiencing some bugs where even if a pedestal was paired by both ID and colour match, its portals did not appear So I had a series of functions to explicitly turn on the portal objects, assuming requirements were met. I also made a very quick debug screen to identify each pedestal's variables in runtime.
Despite having a logical workflow, I kept having multiple bugs that I spent nearly a whole day replicating and identifying. The flaw persists beyond the refactor because of the dependency on Unity Editor's tools instead of having most of the logic dependent on the scripts. Errors like prefabs being activated instead of being disabled by default, minor tag typos, or case-sensitive references. I also made several mistakes in the order of functions, causing static pedestals that ignored the lever to never run the pairing function, making them impossible to pair and create portals with, or sometimes, oddly enough, for the opposite to happen.
A whole day was spent managing a variety of these bugs. I was losing time and momentum, and I haven't made levels or a win condition yet. I decided to stop making improvements as long as I have a relatively stable script—I had to start making playable levels ASAP. I repurposed the old portal script for some of the nonfunctional portals as a patch job.
With the portal logic mostly functional, the next phase is level design. I needed to build a few tutorial levels to ease players into the mechanics, then build more complex puzzles.
I made a simple Level Manager for game progression: Each level is its own parent GameObject, activated or disabled by the level manager. Each Level object contained the grid element for the level layout, the portal and pedestal GameObjects, its own camera set to a specific size that fits each level's intended viewing angle, and a player component that handled interactions. While this is not the cleanest or most elegant solution, it was the fastest implementation I could manage to build given the time. Multiple cameras and player controllers are an invitation for errors, but as long as the level manager worked by ensuring only one Level object was active at a time, there shouldn't be any major errors.
I might need to add a UI system to handle levels, pausing, and navigation, but the core MVP is mostly playable. Art and music can come last. I need to test the prototype MVP from start to finish.
Get Red and Blue Portals
Red and Blue Portals
Navigate through puzzles with portals
Status | Released |
Author | Luise Rivaldo |
Genre | Puzzle |
More posts
- Post-Jam: Reflection and Future of the Project2 days ago
- Day 5: More Levels and Finishing Touches2 days ago
- Day 3: Major Flaw in the Logic2 days ago
- Day 2: Bug Fixing and Polish2 days ago
- Day 1: Conceptualisation and Prep work2 days ago
Leave a comment
Log in with itch.io to leave a comment.