The Dink Network

Reply to Re: Quest for Dorinthia spec ed

If you don't have an account, just leave the password field blank.
Username:
Password:
Subject:
Antispam: Enter Dink Smallwood's last name (surname) below.
Formatting: :) :( ;( :P ;) :D >( : :s :O evil cat blood
Bold font Italic font hyperlink Code tags
Message:
 
 
September 4th 2024, 10:17 PM
death.gif
Seseler
Peasant He/Him Heard Island And Mcdonald Islands
 
To anyone having this bug: run the game in truecolor (24-bit) mode, and you can get through the warp. This should also work on any other D-mod using repeating animated objects as warps.

.

.

.

A technical explanation of the underlying issue:

When dink is warping game calls process_warp_man() function on every screen update.

A slighthly cleaned up version of the function from 1.08 looks like this:
void process_warp_man(void)
{

    int sprite = find_sprite(process_warp);

    if (spr[sprite].seq == 0)
    {
        process_count++;
        if (!truecolor || (truecolor && process_count == 1) )
        {
            CyclePalette();
        }
        if ( ( process_count > 5 && !truecolor ) || ( truecolor && process_downcycle == false) )
        {
            //Actual warping happens here, omited for brevity
            //[...]
            process_count = 0;
            //[...]
        }
    }
    else
    {
        process_count = 0;
    }

}


I think the point of "if (spr[sprite].seq == 0)" is there for the door warps: when you walk on door on Dink Smallwood (or reasonably well-made D-mods), you first freeze, then the door animation plays and only then the screen fades down. This works because touching the door sets its seq to value on it's touch_seq, and after sprite's animation is done, the game automatically resets the seq to 0.

So events will process like this:
 - Game's main loop calls updateFrame
 - If Dink is touching a warp-sprite, updateFrame calls process_warp_man.
   * If the warp sprite's seq is 0 this sets the internal process_count variable to 0 but does nothing else.
   * Otherwise, process_count is incremented. If it reaches 5, the game warps.
 - UpdateFrame calls sprites's brain functions. If the warp-sprite doesn't have brain 6 this is not relevant.
 - UpdateFrame draws sprites and processes the animations. If a sprite reaches the end of it's animation, it's sequence is set to 0.
 - Repeat above steps ad infinitum.


Now, what if you have a brain 6 sprite?
Sprite 6 brain checks if its sequence is 0 and if so sets it to its pseq. Since this happens after process_warp_man, there will be one frame, where the "if (spr[sprite].seq == 0)" check will be true, before the brain reset the seq. This causes process_warp_man call CyclePalette, which darkens the screen slightly. The process_count will be incremented by one, but on the next frame, "(spr[sprite].seq == 0)" check will fail again, and process_count gets reset to 0.
Since the actual warping will only happen when process_count hits 5, the warp never finishes, unless the sprite's brain is changed by a script or something.

Fixing this bug on the engine is pretty easy: just delete the else-block from process_warp_man. AFAICT it's removal should not have any side effects, nor is process_count used anywhere outside the process_warp_man.

For the D-mod authors: If your d-mod requires true-color mode (or you don't mind breaking 8-bit mode) you don't need to worry about this bug. If you do want to use 8-bit colors (for nostalgia or palette swap effects or whatever) and want use brain 6 sprite as a warp, make a script-based warp.