Any% category
3 years ago
Mexico

When I was trying to do my first BTG run I accidentally discovered a way to skip levels (like in NES version).

Looks like some stages has an item that looks like a ball with wings (or a golden snitch). If you defeat an enemy and you're lucky to get it you can skip stages. At the moment I was able to find 3 of them.

First one (Timestamp: 22:16) makes you go from B18F to B12F and the second (Timestamp: 38:16) moves you from 05F to 09F:

When I was uploading my run I decided to give a try to a BTG attempt again (offstream) and accidentally found a 3rd one that makes you go from B09F to B02F:

I don't know exactly the pattern that you need to follow to get those skips and/or if you need to defeat specific enemies to get it, this is something that need some testings. Plus I think that probably the item can spawn in another stages.

NerdyNester likes this
United States

Wow nice finds!! Ill talk with the other mods and see what they have to say. More than likely we will make an All Stages category and a second category for the use of skips. Thank you for posting!

Edited by the author 3 years ago
NerdyNester likes this
United States

Nice find and having a all levels board and any% board would probably be a good idea which I'm cool with. :)

United States

Board and rules have been updated. :)

New Zealand

NoHeadZedd reached out online to investigate the requirements to spawn the level skip object. I obliged and reverse-engineered the item drop logic. The smiley face and level skip items are allowed to be dropped by an enemy under these conditions:

  • The number of remaining enemies is 1, OR
  • The number of remaining enemies is 2 AND there is at least 1 active snowball AND the current level is outside of the 11~20 range (B40-B31F)

The smiley face has a 1/256 chance of spawning. If the check fails, then the level skip object gets a 1/256 chance of spawning. (An enemy is considered defeated once it drops an item, or the snowball containing it has been destroyed.)

Once the level skip object is collected, extra logic is run after level completion to decide if the level skip should occur. This is a simple division+modulus of the next level number by 10. If the next level is a boss level, the modulo is 0 and the level skip is aborted. Otherwise, the next level is set to (division result) * 10 + 9. This translates to the floor numbers B?2F & 09F as observed by others.

The pseudorandom number generator (RNG) in this game is very crude:

The value is only ever set to 0 on the title screen.
Every call to the RNG routine multiplies the value by 5 and adds 1. Only the lower byte of the result is saved, so this is effectively modulo 256.

A more formal definition:
RNG(0) = 0 on title screen
For n >= 1:
RNG(n) = (RNG(n-1) * 5 + 1) % 256

The smiley face requires the RNG output to be exactly $15 after one call for it to spawn. Likewise, the level skip item requires a value of $55 after another call.

I would say that the randomness is "good enough" to not be too predictable throughout a casual playthrough. Since the starting seed is consistent, manipulating the output for the first few levels to get a level skip to B42F seems doable in my opinion. Beyond that, you're pretty much at the mercy of the RNG since many things use it.

Edited by the author 6 months ago
New Zealand

A few more details about the RNG:

  • The output cycles back to 0 on the 256th call.
  • All values from 0~255 are present in said cycle.

Essentially, this RNG routine is best described as obtaining values from a shuffled list of size 256.

I ported the routine to Python to see how many calls are required from the title screen to obtain the smiley face & level skip items:

#!/usr/bin/env python3

class Random:
	def __init__(self):
		self.rng = 0
	
		def next(self):
		self.rng = (self.rng * 5 + 1) % 256
		return self.rng
		
		if __name__ == "__main__":
	random = Random();
	x = random.rng
	values = []
	for i in range(256):
		if i > 0:
			x = random.next()
		print(f'Call {i}: {hex(x)}')
		values.append(x)
		if x == 0x15:
			print("Smiley face")
		elif x == 0x55:
			print("Level skip")

The 94th call after initialisation gets the level skip. The 157th call gets the smiley face. The cyclical nature means that 256 calls must happen before the same value is picked again. So I was correct about the early manipulation idea. Get a semi-consistent level skip in the first set of floors, then hope for the best afterwards.

Edited by the author 6 months ago
NoHeadZedd and Edo_87 like this
New Zealand

Oh, I almost forgot about the relevant variable locations:

$C1E1 = RNG output
$C695 = level skip flag
$C6A4 = # of remaining enemies
$C676 = level from level select screen
$C67D = next level (level skip flag applied here)
$C67E = current level (incremented on level clear)
NoHeadZedd likes this
Game stats
Followers
9
Runs
24
Players
6
Latest threads
Posted 1 month ago
2 replies
Posted 6 months ago
6 replies