Hey. I finally fixed that bug. The “Final Boss of All Bugs” bug. The bug I called my “White Whale.”
The “Become unable to interact with objects or characters” bug.
Want to hear what was causing the problem? Click “Continue Reading.”
Very patient bug-testers discovered that the bug could occur by standing perfectly still at the start of the day and letting 6 hours and 42 minutes pass. The bug would always occur at exactly 1:42 PM.
You didn’t have to use any specific weapon. You didn’t have to kill any specific student. You didn’t have to accelerate time with the Pass Time feature or a photo of Senpai. In fact, you didn’t have to do anything. You just had to let 402 in-game minutes pass.
Armed with that knowledge, I started performing experiments.
- Disable all students. Accelerate time by 25x. Wait until 1:42 PM.
Bug still happens. Alright, it has nothing to do with students.
- Disable Yandere-chan’s script. Accelerate time by 25x. Wait until 1:42 PM.
Bug still happens. Alright, it has nothing to do with Yandere-chan.
- Disable all “manager” objects. Accelerate time by 25x. Wait until 1:42 PM.
…oh? The bug didn’t happen that time.
That means one of the managers is causing the bug.
There are around 25 “managers.” Each of them is responsible for managing a specific aspect of the game, such as students, weapons, schemes, etc. Disabling them 1-by-1 and waiting for the bug to happen would take forever. So instead, I disabled 5 at a time.
- Disable StudentManager, WeaponManager, SchemeManager, CleaningManager, and PopulationManager. Accelerate time by 25x. Wait until 1:42 PM.
…oh? The bug didn’t happen that time.
That means one of those five manages is the culprit.
I had a theory. I presumed it was WeaponManager.
- Disable the WeaponManager GameObject. Accelerate time by 25x. Wait until 1:42 PM.
Ohoho! The bug didn’t happen.
This means that WeaponManager is the culprit.
But, why? What is the script doing that is causing the bug?
…wait. IS it the script? Or is it the object itself?
- Disable WeaponManagerScript. Accelerate time by 25x. Wait until 1:42 PM.
Huh. The bug still happened.
So, the bug is not happening due to anything that is occurring within the WeaponManager script. But, disabling the WeaponManager GameObject prevents the bug from happening.
What does this mean? Well…
All of the weapons at school are the “children” of WeaponManager.
WeaponManager is like a container that is holding all of the weapons in the school environment.
Disabling the WeaponManager GameObject disables all of the weapons at school.
So if WeaponManager itself isn’t the culprit…
…the true culprit is one of the weapons contained within WeaponManager.
But, how could one of the game’s weapon have the unique property of breaking all raycasts? And which one is it? Well, time to find out.
I started disabling weapons in groups of 5.
After I disabled a particular group of weapons, the bug instantly went away.
So, I knew that the true culprit was one of those weapons. I started disabling them one-by-one.
MagicalGirlWand? Nope, disabling it didn’t stop the bug.
FantasySword? Nope, disabling it didn’t stop the bug.
FragileKnife? Nope, disabling it didn’t stop the bug.
Dumbbell? Nope, disabling it didn’t stop the bug.
But…that means…by process of elimination…it’s the last weapon in this set…
…the Baton that the Martial Arts Club uses when training with you?
Well, this weapon does operate differently from all the others. Unlike the other weapons, this one cannot be picked up by the player, and exists as a non-interactive prop that is only meant to spawn in a character’s hand during the Martial Arts Club training minigame.
But…why does it break the game? What is it doing that would cause Unity to lose the ability to use raycasts?
Well, let’s just take a closer look at the object, and…
If you’ve ever messed around with a calculator out of curiosity, you might have tried typing in 9,999,999 x 9,999,999 just to see what the calculator would do if it was commanded to display a number larger than could fit on its display. And, if you did, you’d probably see some weird number appear like this: 9.999998e+13
“What the heck? There’s a letter in this number?” Yes, there is. On a calculator display, “e” stands for “exponent of 10”, and the number that comes afterward is the value of the exponent. For example, if a calculator was asked to display “25 trillion,” it would display “2.5e13” meaning “25 followed by thirteen zeroes.”
So, if a number within Unity is being displayed with an “e”…
…that means it’s larger than 9,999,999. Over 10 million.
As you can see in the screenshot above, the Baton’s “y” – its vertical position in space – is less than negative 2,147,483,648. That number exceeds the maximum integer that a 32-bit operating system is capable of performing calculations with.
No wonder the game couldn’t fire a raycast at the Baton. The Baton had reached a vertical position of more than 2,147,483,648 meters from the floor of the school.
Do you have any idea how much distance that is? That’s over 2,000,000 kilometers.
Jupiter has a diameter of 139,820 kilometers.
The Baton was more than 14 Jupiters away from Akademi.
But, how did it possibly get all the way out there? Wouldn’t it have to be traveling insanely fast to get that far away from the school?
Well, as a matter of fact…
If I reset the Baton’s position to 0, and then I advanced one frame, I observed that the Baton had already fallen 1,578.852 meters.
One frame is a 60th of a second. The Baton traveled 1.5km within a 60th of a second.
That’s 94,731,000 meters per second.
Light travels at about 300,000,000 meters per second.
The Baton was falling at almost a third of the speed of light.
It takes sunlight 8 minutes to travel from the sun to Earth.
It would take the Baton only 24 minutes to make the same trip.
So, why was it traveling that fast? It had no collider stopping it from colliding with the ground, so it actually fell through the floor at the beginning of the game, kept falling, and kept building up speed until it reached the maximum speed supported by the physics engine. At that speed, it took 402 in-game minutes to reach a vertical position so large that no 32-bit computer could possibly calculate it, causing Unity to fail whenever attempting to fire a raycast at it, resulting in a situation where Unity’s raycasting system completely broke and stopped reporting whether or not any raycast was hitting any non-static collider.
You lost the ability to pick up objects because a baton fell through the floor, reached 1/3rd the speed of light, and traveled 14 Jupiters away from a high school.
Don’t worry, though, I fixed it. I told the Baton to not fall through the floor at the beginning of the day. So now everything is groovy.
I presume that this bug didn’t exist before the Baton was added to the game. If you find the build that was released before the Baton was added, you could probably pass 402 in-game minutes without seeing the “can’t pick up objects” bug occur. I wonder if anyone will care enough to test this hypothesis…
(Theoretically, you could re-create this bug by opening a fresh Unity project and letting a physics object fall for several hours until it reached such a ludicrous speed/distance that Unity’s ability to perform raycast calculations completely failed…)
The bug fix will be available in the next build. It will either be released today or tomorrow.
Thank you for following the harpooning of this white whale!