Quest for Dorinthia spec ed
Quest for Dorinthia: Special Edition
October 10th 2014, 01:46 PM
ninkasi
After getting through the fence and burning the trees in the correct order and wiping out the pillbugs and getting the fire axe, every attempt to return to the mainland via the warp machine leaves me totally stuck on a dark screen with some scattered points of light. Everything is frozen and all I can do is ctrl-alt-del my way out. I can finish the game without the axe but would love to be able to own it - Am I doing something out of order?
Still reproducible 8 years later, with v2.5 version released "April 18th, 2018".
The map of interest is #156. It has a warp machine which doesn't have a script attached, but instead is configured to warp Dink like a door does.
In FreeDink 109.6, touching this warp machine causes screen to _slowly_ fade to dark (Dink is frozen) and remain that way, but the warp apparently never happens (ducks can still be heard quacking). He is also never unfrozen.
So, it is obvious it is the bug the author overlooked, no action in game is going to affect this (neither map nor warp has any script). The only remedy is to avoid this part of game (it is optional), or save before visiting it and, having explored it just for the sake of seeing what's there (not much actually), reload the save.
The question is: what attributes did the author specify wrong on the warp's machine sprite? Just for the sake of learning which mistakes to avoid when making a d-mod, in case I ever get around to that, of course.
The map of interest is #156. It has a warp machine which doesn't have a script attached, but instead is configured to warp Dink like a door does.
In FreeDink 109.6, touching this warp machine causes screen to _slowly_ fade to dark (Dink is frozen) and remain that way, but the warp apparently never happens (ducks can still be heard quacking). He is also never unfrozen.
So, it is obvious it is the bug the author overlooked, no action in game is going to affect this (neither map nor warp has any script). The only remedy is to avoid this part of game (it is optional), or save before visiting it and, having explored it just for the sake of seeing what's there (not much actually), reload the save.
The question is: what attributes did the author specify wrong on the warp's machine sprite? Just for the sake of learning which mistakes to avoid when making a d-mod, in case I ever get around to that, of course.
Hmm, I looked over the map but I can't quite figure out what's wrong there.
The only thing different from usual warp sprites I'm familiar with is that this one has a brain and a base walk set.
The only thing different from usual warp sprites I'm familiar with is that this one has a brain and a base walk set.
Checked via editing that map: indeed, setting brain to 0 (alone - didn't touch base walk) will unbreak the warp machine, but it stops animating. Setting brain back to 6 makes the bug happen again.
The conclusion so far is that animating warp things should use scripts for warping, not the editor warp attributes. By animating warp here I mean those with idle animation.
Of course, since the original poster never said anything about the engine he used to play this d-mod, it might still be that it worked in some, but certainly doesn't in FreeDink (up to the current v109.6 at least). The more plausible, however, is that it never worked in anything and that author arrived at this broken setup by first making a working warp (which he did check), but then making it animating by giving it a brain, after which it stopped working but he didn't check that anymore.
The conclusion so far is that animating warp things should use scripts for warping, not the editor warp attributes. By animating warp here I mean those with idle animation.
Of course, since the original poster never said anything about the engine he used to play this d-mod, it might still be that it worked in some, but certainly doesn't in FreeDink (up to the current v109.6 at least). The more plausible, however, is that it never worked in anything and that author arrived at this broken setup by first making a working warp (which he did check), but then making it animating by giving it a brain, after which it stopped working but he didn't check that anymore.
I think we need RobJ's input on this. Surely he must know the secrets of animated warps!
I would agree with Vigilante and say it just needs to be a scripted warp, rather than set in the editor. I mean, that will definitely fix it.
tbh, I've never tried setting a brain 6 editor sprite to warp in the editor. Any warps out of the ordinary, I just script them instead.
tbh, I've never tried setting a brain 6 editor sprite to warp in the editor. Any warps out of the ordinary, I just script them instead.
Alternatively if the warp isn't a solid object, have it scripted under the animated sprite as a separate one, and set the real warp to nodraw. Could work for solid objects but may seem a little odd to just walk into it.
In FreeDink 109.6, touching this warp machine causes screen to _slowly_ fade to dark (Dink is frozen) and remain that way,
How interesting. Maybe the brain 6 causes the warp code to try to execute on every frame of the animation, so it gets stuck in an endless loop, and fades down slowly because it's constantly trying to run code.
I think something like that's happening, since you can actually fix it by changing the warper's brain to 0 after Dink's already stuck.
It also doesn't work on old Dink or HD either, so this bug is definitely on the author.
How interesting. Maybe the brain 6 causes the warp code to try to execute on every frame of the animation, so it gets stuck in an endless loop, and fades down slowly because it's constantly trying to run code.
I think something like that's happening, since you can actually fix it by changing the warper's brain to 0 after Dink's already stuck.
It also doesn't work on old Dink or HD either, so this bug is definitely on the author.
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:
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:
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.
.
.
.
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.
Also of note is that the RTDink source skips the 24-bit display check and does it regardless which explains Scratcher's experience.