546 - bombShield(int a, int script)


Sets the bomb invulnerability flag (a=0 false, a=1 true), the caller's ANM script will change to script when a bomb is active.

611 - etEx(int etId, int async, int type, float a, float b)


Adds bullet transformation to bullet manager etId, Transformation of flag type determines the specific behaviour of the bullet. Documentation can be found here.

BulletEffectType-67108864 - etExDelay(string et, string isAsync, string time)


Hide the bullet for time frames. During this time, it will not move, will be invisible and won't have a hitbox. If used as a first transformation, can be used to delay when the bullet actually appears.

6 - isDelayedSpawn


While this flag is set, the bullet will be invisible and not have a hitbox. This flag is cleared once the delay timer ends.

4 - short_timer


Integer value between -1 and 15 inclusive (by default -1). If non-negative, shooters using short_timer shoot their bullets and timer increments by 1 per frame until 15 is reached. Once 15, timer reset to -1 or 0 depending on Z key state.

5 - long_timer


Integer value between -1 and 120 inclusive (by default -1). If non-negative, shooters using long_timer shoot their bullets and timer increments by 1 per frame until 120 is reached. Once 120, timer reset to -1 or 0 depending on Z key state.

503 - flagClear(int n)


Clears flag(s) according to n. Refer to the flag table here for exact values.

91 - floatTime(int slot, float var, int time, int mode, float start, float final)


In time frames using mode mode, variable var changes from start to final. slot is used to set the slot to be used by this ins, every enemy has 8 slots.

-9980 - F1


Local float variable, inherited by spawned enemies.

-9984 - I1


Local integer variable, inherited by spawned enemies.

-9989 - ANGLE_PLAYER


Angle from the enemy to the player.

-9962 - BOSS_Y


Final Y position of the boss.

-9990 - PLAYER_Y


Player's Y position.

-9963 - BOSS_X


Final X position of the boss.

-9991 - PLAYER_X


Player's X position.

81 - circlePos(float varX, float varY, float angle, float radius)


Performs following operation: varX = cos(angle) * radius and varY = cos(angle) * radius

-9981 - F0


Local float variable, inherited by spawned enemies.

300 - enmCreate(string sub, float x, float y, int hp, int score, int item)


Creates an enemy using subroutine sub at coordinates (x, y) (relative to position of the parent), health of created enemy is hp, score bonus is score and item drop is item.

601 - etOn(int etId)


Shoots bullet(s) using properties from bullet manager etId.

23 - wait(int time)


Stops sub execution for time frames.

1 - delete()


Returns to the top of current call stack.

2 - GAME_SPEED


The value controls by how much faster the game speed is run. This variable is often set to a number between 0 and 1. This value is often changed when a (final) boss dies or when a photo is taken. Its default value is 1.

-9985 - I0


Local integer variable, inherited by spawned enemies.

-9983 - I2


Local integer variable, inherited by spawned enemies.

-9982 - I3


Local integer variable, inherited by spawned enemies.

-9954 - ENEMY_HP


Enemy's current HP.

3 - goheiExists


A flag that determines if a gohei exists on-screen or not. Flag is set to true by active gohei. Flag is set to false if gohei goes off-screen or is despawning.

-9926 - GI0


Global integer value. Value is initialised to 0 on stage load but not on stage reset.

-9925 - GI1


Global integer value. Value is initialised to 0 on stage load but not on stage reset.

-9924 - GI2


Global integer value. Value is initialised to 0 on stage load but not on stage reset.

-9923 - GI3


Global integer value. Value is initialised to 0 on stage load but not on stage reset.

17 - distortion(int a)


Triggers distortion effects on the edge of the screen. The meaning of the argument is not entirely clear. SA uses a value of 1 to create distortion at the bottom of the screen, while UFO uses this same value to create distortion at the top.

Stage 6 Desync


Specifications


  • Versions: 1.00a
  • Difficulty: Easy - Normal - Hard - Lunatic - Extra
  • Mode: Main game - Practice mode
  • Shottype: ReimuA - ReimuB - ReimuC - MarisaA - MarisaB - MarisaC

What happens


All full-game replays are able to desync on Stage 6 during Utsuho under two unique circumstances.

How it happens


For the desync to happen, the player must do one of the following:

  • Start the replay from Stage 5. Right when the stage is about to end, fast-forward by using Ctrl.
  • Start the replay from Stage 6.

The desync always happens on Utsuho, usually during her first non-spell or first spell-card. The desync in both cases is differently.

Why it happens


The desync is caused because there is a desync in the RNG. A desync in the RNG means that the RNG value is different than what it is supposed to be. This means that after an RNG desync, if the RNG value is called for, the game desyncs.

There are two different versions desyncs: one starting from Stage 5 and where the game is fast-forwarded during the stage transition, and one starting from Stage 6. The two desyncs seem like they might be the same, but they are different. Nonetheless, their cause is similar.

In summary, there are three different outcomes when playing back Stage 6:

  • Method 1: You fast-forward during the Stage 5 stage transition. This method desyncs the replay.
  • Method 2: You do not fast-forward during the Stage 5 stage transition. This method does not desync the replay.
  • Method 3: You start the replay directly from Stage 6. This method desyncs the replay.

RNG difference


From replay analysis, we can take a look at the number of RNG calls the replay makes.

We take any replay that enters Utsuho on 1cc pace, and we watch Stage 6 with Method 2. Then, we look at its number of RNG calls during the 7200th frame of Stage 6 (which is always during Utsuho's dialogue). Let's suppose that Method 2 yields n number of RNG calls.
Using the same replay, we watch Stage 6 using Method 1. Its number of RNG calls is equal to n-5.
Using the same replay, we watch Stage 6 using Method 3. Its number of RNG calls is equal to n+1.

This means that Method 1 makes 5 RNG calls too few compared to the non-desynced Method 2. This also means that Method 3 makes 1 RNG call too many compared to the non-desynced Method 2. If too many or too few RNG calls are made relative to the non-desynced Method 2, it means that anything that the RNG value is different and therefore anything that uses the RNG value does it so wrongly.

Desync cause


Upon analysis, it turns out the stage background is loaded at a different time depending on how the stage is entered from. Usually, the stage background is independent of the playing area, but in few cases the two are intertwined. The stage background in question is the file stage06.std.

When entering Stage 6 using Method 1, the stage background is loaded 5 frames later compared to Method 2.
When entering Stage 6 using Method 3, the stage background is loaded 1 frame earlier compared to Method 2.

In the file stage06.std, data about the Stage 6 background is noted. In it, there is an instruction that applies some stage background effects which will be called distortion, (thanks ExpHP for documentation).
In particular, distortion(2) is the instruction that calls for RNG once per frame (Note: no other stages use this instruction hence it not happening on other stages). This STD instruction is only used right when the stage's background switches to the sun right before Utsuho spawns, meaning the desync only happens on Utsuho and never before Utsuho's appearance.

In terms of why the stage background is loaded differently depending on how it is viewed, we do not know. Please refer to ZUN for such questions.

Conclusion


Replays desync at Utsuho's if the replay is started from Stage 6 or if the replay is started from Stage 5 and fast-forwarding is done in between stage 5 being cleared and stage 6 starting. This has to do with the RNG being different. The RNG difference is caused by code used by the stage background. The RNG difference exists because the stage background is loaded at a wrong time during the desync.


Replays


Any replay that reaches Utsuho suffices, so none are provided.

Videos


This section has no content yet. Would you like to add to this section? Contact me if you are interested!

All Subterranean Animism pages:
Negative Spell Bonus · ReimuA 2 Power Damage · Mid-boss skips · ReimuC Desync · Score Desync · ReimuA Desync · Stage 6 Desync · Stage transition Desync · Extra Relocking · Extra Leaderboard Crash · 999.99s Spell Timer · Stage Transition Death Crash · Slowdown Item Duplication
All Desync-related pages:
All Stage transition-related pages: