Last active
August 20, 2024 22:10
-
-
Save megamaz/80fbe4d30cc1707bacb3deac48a14b83 to your computer and use it in GitHub Desktop.
Optimizes the Elytra for horizontal speed while pulling up in Celeste
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import sin, pi | |
DELTA_TIME = 0.016666699201 # the exact in-game value when running at 60fps | |
MAX_ANGLE_CHANGE_INV_SPEED_FACTOR = 480.0 | |
MIN_SPEED = 64.0 | |
MAX_SPEED = 320.0 | |
DECEL = 165.0 | |
FAST_DECEL = 220.0 | |
ACCEL = 90.0 | |
STABLE_ANGLE = 0.2 | |
RAD_TO_DEG = 180.0 / pi | |
DEG_TO_RAD = pi / 180.0 | |
STABLE_ANGLE_DEG = STABLE_ANGLE * RAD_TO_DEG | |
"""PLEASE READ THIS IF YOU'RE GOING TO USE THIS TO OPTIMIZE YOUR ELYTRA | |
So the Elytra is really weird, in that there's a pretty big discrepancy between the angle you're visible flying at and the angle you're inputting using feather controls. | |
As a result, it's really weird to optimize because for pulling up you have to match the rate at which the elytra angles upwards otherwise you lose a ton of speed. | |
This script does just that. It simulates the in-game code for the elytra to find the most optimal pull-up angle for the elytra. | |
In order to properly use this, you'll need to set your Custom Info HUD to the following: | |
PlayerGlideAngle: [[return (math.deg(math.atan(player.Speed.Y, player.Speed.X)) + 90) % 360]] | |
PlayerNormalizedSpeed: [[return math.sqrt(player.Speed.X^2 + player.Speed.Y^2)]] | |
Launch the script the frame before you open the elytra. | |
For "Initial angle flying at", insert PlayerGlideAngle. For "Initial speed", insert PlayerNormalizedSpeed. The console will output a series of angles, up till pulling up at full up. | |
You can then copy-paste, then trim the inputs you don't need from the end. | |
A couple of things to note: | |
1. This script is solely for PULLING UP. | |
2. For going down, the most optimal method is to hold a 90 degree angle until your PlayerGlideAngle reaches ~101 degrees, at which point you should simply hold an angle of 180. | |
If you run into any issues while using this ping `megamaz` in the CelesteCord (I dont like DMs so dont DM me) | |
I'm not the elytra dev but I understand most of its physics so feel free to ping me about that as well :D | |
""" | |
ELYTRA_HOTKEY = "PE" # change this if you're using PP or something else | |
PRECISION = 2 # how many digits of precision | |
ADDITIONAL_ANGLE = 0 # how many extra degrees to add to the angle change between frames. This will slow you down more, but will allow you to pull up faster. | |
HOLD_JUMP = False # this can sometimes allow you to get more height | |
JUMP_KEY = "J" | |
initial_angle = float(input("Initial angle flying at: ")) | |
target_angle = STABLE_ANGLE * RAD_TO_DEG + (360 if initial_angle > 180 else 0) | |
initial_speed = float(input("Initial speed: ")) | |
output = f" 1,{f'{JUMP_KEY},' if HOLD_JUMP else ''}{ELYTRA_HOTKEY},F,{initial_angle - STABLE_ANGLE_DEG:.{PRECISION}f}" | |
speed = initial_speed | |
# the angle in feather units | |
angle = initial_angle | |
def Approach(value, target, step): | |
if value > target: | |
return max(value - step, target) | |
elif value < target: | |
return min(value + step, target) | |
return target | |
while sin((angle-90) * DEG_TO_RAD) > sin((target_angle-90) * DEG_TO_RAD): | |
maxAngleChange = DELTA_TIME * MAX_ANGLE_CHANGE_INV_SPEED_FACTOR / speed | |
# simulate in-game speed changes | |
newSpeed = speed | |
# subtract 90 to convert to normal angle units | |
y = -sin((angle - 90) * DEG_TO_RAD) | |
yInput = y | |
# I need to add 90 here because the stable angle is an offset from the horizontal | |
if angle < STABLE_ANGLE_DEG + 90: | |
decel = FAST_DECEL if speed > MAX_SPEED else DECEL | |
newSpeed = Approach(speed, MIN_SPEED, DELTA_TIME * decel * abs(yInput)) | |
else: | |
if speed < MAX_SPEED: | |
newSpeed = Approach(speed, MAX_SPEED, DELTA_TIME * ACCEL * abs(yInput)) | |
# make the variable changes accordingly | |
speed = newSpeed | |
angle = Approach(angle, target_angle, (maxAngleChange * RAD_TO_DEG) + ADDITIONAL_ANGLE) | |
# since the `angle` variable is the angle we're flying at, I wanna cancel out the stable angle in the input | |
output += f"\n 1,{f'{JUMP_KEY},' if HOLD_JUMP else ''}{ELYTRA_HOTKEY},F,{angle - (STABLE_ANGLE_DEG * -1 if angle > 180 else 1):.{PRECISION}f}" | |
output += f"\n9999,{f'{JUMP_KEY},' if HOLD_JUMP else ''}{ELYTRA_HOTKEY},F,{target_angle - (STABLE_ANGLE_DEG * -1 if angle > 180 else 1)}" | |
print(output) | |
print(f"\nExtra info:\nEnding speed: {speed}") | |
input("Hit enter to end") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment