Go back to : Skydrift research homepage
Mods designed for research purposes were used to create this document and screenshots / footages.
Based on experiments from novembre 2024, with some rewriting from december 2025 (without the testing tools, so I might rewrite something stupid).
This study follows the ring bounce one, so some concept might have been explained in that one & not here.
I believe there might be a slight luck factor for Voile Library's spiral NISC if you hit the second bookshelf (like the first example of MegaMia's video).
In Gensou Skydrift, every 20 frames (0.4sec), if you're on the ground, there's a check. You want that check to happen in most parts of the bookshelf with the rings (or skip the check while in the air). Otherwise, you'll keep the second bookshelf gravity.
this.mIsEnableAutoHorizon is what causes the character to, sometimes, not pivot in the air.
This is based on various observations showing this variable having different values wether the character pivot or not.
Note : below is an extract of updateTankMove, the function in charge of handling most of a player movements (with comments by me).
Only parts related to this.mIsEnableAutoHorizon were extracted.
The "gravity ray" is a ray starting from in front of a player, pointed below them.
// /!\ /!\ /!\ This codes only executes if gravity ray hits something /!\ /!\ /!\
// If State frames are a multiple of 20
if (this.getStateFrame() % 20 == 0)
{
// Disables AutoHorizon if dot product of the road normal vector and (0, 1, 0) is inferior to 0.4
this.mIsEnableAutoHorizon = (Vector3.Dot(this.mRoadNormalVec, Vector3.up) > 0.4f);
}
// /!\ /!\ /!\ This codes only executes if gravity ray --> DOES NOT <-- hit something /!\ /!\ /!\
// If auto horizon is enabled, changes road normal vec
if (this.mIsEnableAutoHorizon)
{
// ??? To this day, still have not tried to properly document this
this.mRoadNormalVec = Vector3.Slerp(this.mRoadNormalVec, Quaternion.AngleAxis(this.mRotateX, this.mTankform.right) * Vector3.up, 0.02f * cTimeBase);
}
this.mIsEnableAutoHorizonfalse.true at the beginning of a track, as the road normal vector is (0, 1, 0) at the beginning, so Vector3.Dot(this.mRoadNormalVec, Vector3.up) returns 1, which is superior to 0.4f (see code in Hypothesis section if needed).DisableHorizon ground type, sets this.mIsEnableAutoHorizon to false.
(Example of DisableHorizon : Embers of Blazing Hell tilted part, skipped by supercut)
NoJump ground type, sets this.mIsEnableAutoHorizon to true.
DisableHorizon sets this.mIsEnableAutoHorizon in the else if part of the collided object tag, while the NoJump is an extra if based on the current player ground type right after that all else if part.
So having the NoJump ground type will always change this.mIsEnableAutoHorizon to true, while changing from DisableHorizon to Null or HeavyZone will keep this.mIsEnableAutoHorizon to false.
(Though I'm not sure if it's somehow possible to trigger this scenario).
Vector3.Dot(this.mRoadNormalVec, Vector3.up) returning strictly more than 0.4f sets this.mIsEnableAutoHorizon to true, otherwise sets it to false.this.mIsEnableAutoHorizon is true, looks like it rotates the road normal vector to eventually reach (0, 1, 0), which ricochet into rotating the character
0.NoJump or DisableHorizon :
-18 while still having elevation frames, droping to -6 after elevation frames reach 1 (= their final value once elevator is consummed),6.
Depending on where on the ring bookshelf and the next bookshelf you're standing, the Vector3.Dot(this.mRoadNormalVec, Vector3.up) > 0.04f can end up returning false.
But if this condition returns false and you keep this value in the air, the character won't pivot and will keep going straight following the gravity they had when elaving the ground.
This means you want this.mIsEnableAutoHorizon to be true when you leave the 2nd bookshelf, which happens if :
this.mRoadNormalVec (property of the player) does not instantle switch to the collided object normal raycastHit.normal (uses Vector3.Slerp()).
Normals of the bookshelves for the NISC :
(0.9, 0.4, 0) might not set the same this.mIsEnableAutoHorizon.
True or the number in parenthesis is less than 0.4(0.9, 0.5, 0), returns true(0.9, 0.4, 0), usually returns true(0.9, 0.4, -0.1), usually returns true(1.0, 0.3, 0), returns false(1.0, 0.3, -0.1), returns false(1.0, 0.1, 0), returns false(1.0, 0.1, -0.1), returns false(1, 0, 0), returns falseThis first video point was to reproduce different situations (failing / succeeding the NISC or changing gravity) to gather data. Monitoring & comparing values in the debugger was then used to propose a first hypothesis.
Timecodes for each situation :
This second video point was to confirm the hypothesis seems to line up with game, by reproducing different situations (failing / succeeding the NISC or changing gravity).
Timecodes for each situation :
false and leaving the last bookshelf at frame 6499 (= a new check happens on the next frame)