Diagonal Springs Lock Your Controls


What does this do?
When you touch a diagonal spring, your horizontal movement controls become locked for a short time.

Uh... why?
Diagonal springs reset your horizontal *and* vertical momentum. They're generally placed with an intention to send you somewhere specific. But you still have a lot of air control, so it's easy to hold a direction a bit too long and wind up accidentally veering away from where it was trying to send you. This mod gives you a little window where you can let go of the buttons or the stick so the spring can take you where it will.

This mod comes with a new console variable, "springlock", which measures how many frames your controls will be locked for. It defaults to 25, and can be set to anything between 1 and 70. Having the Super Sneakers powerup makes the timer run out twice as fast.

If you end up in any state other than springing or falling before that time runs out, your controls will immediately unlock, so if you land early or get hit by something on the way you'll have full control right away.


  • VL_SpringLock-v1.lua
    1.4 KB · Views: 348


Warrior from Algol
This is the kind of thing that annoyed me a bit when I started SRB2 back in '15 (during the 2.1 days), I know that you should "let it go" when you use one but this isn't really intuitive.

I especially remember those springs from the last quarter of Techno Hill Act 2.

This mod should only be for vanilla maps because I feel like custom maps could use "trap springs" that sends you to a bottomless pit so you must have a backup and quick reflexes.

Tl;Dr Thanks it was really needed


If a feature like this was officially adopted, the devs would probably add a flag to springs that turns it on or off. For a simple mod like this, that's a bit out of scope.

Ace Dragon

This will be very nice for us custom map makers that makes use of diagonal springs, but don't want to deal with the fact it could allow players to easily cheese the level (if measures, that might detract from the aesthetic, are not put in place).

I will be making use of this, thanks. I may also try to use it to increase the efficacy of horizontal springs.
You know, this is one of those things that's so obvious, a problem with the spring physics so blatant that every single person is guaranteed to fail at the first time they play GFZ2, something I've complained about so many times at one point or another for making the game unnecessarily inaccessible, something I've seen so many new players on YouTube irritated at right out of the gate... I figured the reason it hasn't been changed all this time was because of some weirdness in the Doom movement code that was difficult to fix.

The fact that it can be fixed with a tiny Lua script actually kind of angers me.

Thank you so much for this!

Ace Dragon

I made a second copy of the script for my project and managed to make horizontal springs actually have power behind them.
//Lua script originally written by Dabir, modified to make horizontal springs work//
    name = "springlock2",
    defaultvalue = "25",
    flags = CV_SHOWMODIF,
    PossibleValue = {MIN = 1, MAX = 70}

local function springBounceLock(thing, tmthing, lockTime)
    local p = tmthing.player
    if not p
    --Doom collision detection checks just x and y values by default, add z value check--
    if abs(thing.z-tmthing.z)/FRACUNIT <= 25
        --Different values for different spring types--
        if thing.type == MT_BLUEHORIZ
	    p.springlock2 = 15
	elseif thing.type == MT_YELLOWHORIZ
            p.springlock2 = 20
	elseif thing.type == MT_REDHORIZ
	    p.springlock2 = 40

addHook("MobjCollide", springBounceLock, MT_REDHORIZ)
addHook("MobjCollide", springBounceLock, MT_YELLOWHORIZ)
addHook("MobjCollide", springBounceLock, MT_BLUEHORIZ)

addHook("PreThinkFrame", function()
    for player in players.iterate()
        -- Existence check
        if not(player.mo and player.mo.valid)
        -- Controls not locked
	if not(player.springlock2 == nil) -- the variable does not have a valid number when the level starts--
	    if player.springlock2 <= 0
	        -- Lock controls this frame
		player.cmd.forwardmove = 0
		player.cmd.sidemove = 0
		player.cmd.angleturn = 0
		-- Run timer down 2x if sneakers
		if player.powers[pw_sneakers]
		    player.springlock2 = max($-2, 0)
		    player.springlock2 = $-1
The approach is slightly different from the script for diagonal springs, but it works.