Spring
Springs in Vanilla CC
Springs are a mechanic in Celeste Classic and a lot of its Mods.
Springs can be found in several levels in the vanilla game, including 300m and 800m. They can be triggered by landing on one, which will launch madeline upwards.
Vanilla Internal data
Springs give player momentum and move the player a little bit away from them. The player's Y speed is always set to -3, And its X speed is multiplied by 0.2. Its Y position is also set to be 4 Pixels above the spring, before any speed is given.
You can see the movement being triggered here:
hit.move(0,this.y-hit.y-4,1) hit.spd.x*=0.2 hit.spd.y=-3
Springs also break fall_floor (crumbles) that are below them, to avoid floating springs.
Once hit, springs become inactive for 10 frames, and during this time its sprite is set to sprite 19, showing the spring being depressed into the ground. After this time is over, it returns to its previous state.
Spring object code in Vanilla CC
spring = { tile=18, init=function(this) this.hide_in=0 this.hide_for=0 end, update=function(this) if this.hide_for>0 then this.hide_for-=1 if this.hide_for<=0 then this.spr=18 this.delay=0 end elseif this.spr==18 then local hit = this.collide(player,0,0) if hit ~=nil and hit.spd.y>=0 then this.spr=19 hit.y=this.y-4 hit.spd.x*=0.2 hit.spd.y=-3 hit.djump=max_djump this.delay=10 init_object(smoke,this.x,this.y) -- breakable below us local below=this.collide(fall_floor,0,1) if below~=nil then break_fall_floor(below) end psfx(8) end elseif this.delay>0 then this.delay-=1 if this.delay<=0 then this.spr=18 end end -- begin hiding if this.hide_in>0 then this.hide_in-=1 if this.hide_in<=0 then this.hide_for=60 this.spr=0 end end end }
Springs in EverCore
Springs in the EverCore CC Modbase differ slightly. Minus the smaller token size, they also support Left and Right directions. When sprite 19 is placed on the map next to a ground tile, Once the cart is run, It will automatically stick to that wall. On hit, it will bounce the player in the opposite direction. Vertical facing springs (Placed with sprite 18) are still the same as in vanilla
EverCore Internal data
The amount of speed and movement that vertical facing springs give the player is exactly the same as they were in Vanilla CC, But with smoother animation, and the ability to place left and right facing springs. A Horizontal spring, When placed, Will check in each direction if there is a ground tile or other solid object there. It starts with checking LEFT, meaning that if there is a wall or solid object on both sides of the spring, it will face Right.
The amount of speed that a horizontal spring gives you is a fixed number, determined by the springs facing direction. It will always give you 3 speed in the direction it is facing, and -1.5 y speed. It will also move you 4 pixels away from the spring, in its facing direction as well.
The animation of the spring has also changed. Now, The spring has a "Delta" Value, which determines its offset when drawing the sprite. On hit, Its "Delta" Value is set to 8, moving it into the ground by 4 pixels. It remains at four pixels down for 2 frames, and it slowly returns to its original position after 4 more frames. During this 6 frame window, the spring cannot be hit again. The same animation happens to horizontal springs, but they move towards the wall they are stuck to, instead of the ground below.
Spring object code in EverCore
spring={ init=function(this) this.delta=0 this.dir=this.spr==18 and 0 or this.is_solid(-1,0) and 1 or -1 this.show=true this.layer=-1 end, update=function(this) this.delta=this.delta*0.75 local hit=this.player_here() if this.show and hit and this.delta<=1 then if this.dir==0 then hit.move(0,this.y-hit.y-4,1) hit.spd.x*=0.2 hit.spd.y=-3 else hit.move(this.x+this.dir*4-hit.x,0,1) hit.spd=vector(this.dir*3,-1.5) end hit.dash_time=0 hit.dash_effect_time=0 hit.djump=max_djump this.delta=8 psfx"8" this.init_smoke() break_fall_floor(this.check(fall_floor,-this.dir,this.dir==0 and 1 or 0)) end end, draw=function(this) if this.show then local delta=min(flr(this.delta),4) if this.dir==0 then sspr(16,8,8,8,this.x,this.y+delta) else spr(19,this.dir==-1 and this.x+delta or this.x,this.y,1-delta/8,1,this.dir==1) end end end }
Note the object's smaller code size, while having more features then its vanilla counterpart.