Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • 0
Memfis

How to make a ZDaemon-friendly Boom scroller?

Question

Sometimes Boom scrollers move a lot slower in ZDaemon for some reason. What is the cause and is there any way to avoid these problems?

Share this post


Link to post

3 answers to this question

Recommended Posts

  • 3

The guideline:

Make your lines with carrying specials at least 22 map units long to avoid any issues.

This actually goes back to at least Boom 2.02, so anyone targeting the original Boom or PrBoom+ complevel 9 should also keep this in mind; somewhat. Unlike ZDaemon, these two ports will accelerate voodoo dolls to intended speed after a real player has moved (as Melon pointed out); other things will still scroll slowly though.

Explanation:

If the momentum/velocity of a thing falls below a certain threshold, the engine resets it to 0 effectively bringing the thing to a complete halt. Boom scrollers accelerate things by adding only a small fraction of their speed value to the thing's momentum/velocity each tick; it thus takes multiple ticks to accelerate the thing to full speed. For very short scroll special lines, this fractional value will be below the above-mentioned stop threshold, and thus the thing's momentum/velocity will get reset to 0 each tick effectively making it move at only a tiny fraction of intended speed.

The details:

The threshold value:

STOPSPEED = 0.0625


The multiplier to get the fractional boost value:

CARRYFACTOR = 3 / 32 = 0.09375


The formula:

carry_speed_increment = line_length / 32 * CARRYFACTOR


Results for line lengths around the critical point:

21 -> 0.0615234375 (less than STOPSPEED; will get reset each tick)
22 -> 0.064453125  (more than STOPSPEED; will start accumulating properly)


The exact break is at 21.333 (periodical), but 22 is easier to remember and measure.


Source code references:

This is the part responsible for resetting the momentum/velocity (GitHub). The example comes from ZDoom 2.8.1, but it is functionally identical to what appears in the source code of ZDaemon 1.06; from observation, it remained the same in ZDaemon 1.10b07 also.

if (mo->velx > -STOPSPEED && mo->velx < STOPSPEED
    && mo->vely > -STOPSPEED && mo->vely < STOPSPEED
    && (!player || (player->mo != mo)
        || !(player->cmd.ucmd.forwardmove | player->cmd.ucmd.sidemove)))
{
    // if in a walking frame, stop moving
    // killough 10/98:
    // Don't affect main player when voodoo dolls stop:
    if (player && player->mo == mo && !(player->cheats & CF_PREDICTING))
    {
        player->mo->PlayIdle ();
    }

    mo->velx = mo->vely = 0;
    mo->flags4 &= ~MF4_SCROLLMOVE;

    // killough 10/98: kill any bobbing velocity too (except in voodoo dolls)
    if (player && player->mo == mo)
        player->velx = player->vely = 0;
}



This is the way the issue has been remedied as it appears in ZDoom 2.8.1 (GitHub). The acceleration will be smoothed out only if the fractional value would be larger than STOPSPEED; if it won't be (it won't be for scroll line lengths <21.333), the thing is simply moved at the scroller's full speed right from the start, and the whole momentum/velocity accumulation is not used. This also means that, in these cases, the thing will come to a complete stop as soon as it leaves the scroller because there will be no momentum/velocity accumulated; but it will move at intended speed while on the scroller. Obviously, ZDaemon is missing this fix/workaround.

#define STOPSPEED            0x1000
#define CARRYSTOPSPEED      (STOPSPEED*32/3)


// [RH] Carrying sectors didn't work with low speeds in BOOM. This is
// because BOOM relied on the speed being fast enough to accumulate
// despite friction. If the speed is too low, then its movement will get
// cancelled, and it won't accumulate to the desired speed.
mo->flags4 &= ~MF4_SCROLLMOVE;
if (abs(scrollx) > CARRYSTOPSPEED)
{
    scrollx = FixedMul (scrollx, CARRYFACTOR);
    mo->velx += scrollx;
    mo->flags4 |= MF4_SCROLLMOVE;
}
if (abs(scrolly) > CARRYSTOPSPEED)
{
    scrolly = FixedMul (scrolly, CARRYFACTOR);
    mo->vely += scrolly;
    mo->flags4 |= MF4_SCROLLMOVE;
}
xmove += scrollx;
ymove += scrolly;



Both examples come from the P_XYMovement() function located in p_mobj.cpp.

Share this post


Link to post
  • 0

I vaguely remember hearing something about Boom actually only determining scrollers' speed based on line length increments of 32, or 64, or something like that, so different lengths might be getting treated as different speeds in some ports. Sorry for lacking specifics, but this might be a direction to try looking in.

Share this post


Link to post
  • 0
On 29.3.2017 at 7:58 PM, esselfortium said:

I vaguely remember hearing something about Boom actually only determining scrollers' speed based on line length increments of 32, or 64, or something like that, so different lengths might be getting treated as different speeds in some ports. Sorry for lacking specifics, but this might be a direction to try looking in.

Looking through PrBoom's code I cannot see anything like that in there. The actual problem with the scrollers is that they indeed work by just adding some velocity instead of actually moving the carried actors and that friction tends to get in the way here. Implement that part differently and discrepancies are inevitable. Use an old engine like ZDaemon which carries over a lot of ZDoom bugs long gone and things will get even worse.

The main difference here is that ZDoom changed how the scrollers work - they do not add velocity directly, but just set a sector property that contains the accumulated carrying velocity of all scrollers attached to a sector. That setup is more robust but may create a few edge cases where not fully compatible with Boom, which then gets compounded by the abovementioned velocity cutoff and no compensation.

ZDaemon is also missing the compatibility option that re-enables accumulation of all touching carrying sectors instead of averaging, which is normal procedure in ZDoom.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×