The Dink Network

Alliance Command Ending

Alliance Command

September 21st, 12:44 PM
custom_king.png
redink1
King He/Him United States bloop
A mother ducking wizard 
A few days ago, I started cleaning out the closet in my office, and found a bag full of hard drives and old backup CD-ROMs. As one does.

An aside: the term 'backup' implies properly categorized, dated, and maintained archives of information. But I use the term 'backup' pretty loosely - these weren't done with any real rigor or intention. It was pretty random. And given that these artifacts where anywhere from 15 to 25 years old, I expected most of the drives and discs to be have major issues. But, I was pleasantly surprised to discover that I was able to easily recover 100% of the data from the vast, vast majority of the drives and discs.

That got my mind to wondering - did I have a backup of the original Alliance Command ending tucked away somewhere? As Tim wrote in COTPATD:

The most disappointing thing, however, is that after going through all the effort to reach the end, nothing happens. There's a credits script in the story folder, but it's never called. This feels like an awful shame.

Now, as I recall, what happened was I used a non-ASCII character in the ending script. When I 'compiled' the scripts to .d format it created a file with one malformed byte in it.

So, I searched around a bit, and I found some old Alliance Command source files! With timestamps dating from May through July 1999.

I thought it would be pretty funny to release a new version with the original ending restored some 26 years after I originally released it.

I tried to figure out where the problem was, but it wasn't clear to me by looking through the source code and the editor. So, to see it for myself, I played Alliance Command for the first time in ages, and even recorded my playthrough.

Overall, I did enjoy playing through it, even if the gameplay was a little bit simple and too easy. I did briefly considering updating it to fix an issue where the projectiles seemed to hit either text sprites (damage numbers) or blood spurts before enemies, but I just decided to change the way I played.

And, after almost an hour, I arrived at Level 10, and... the ending worked perfectly, and the credits rolled!

I believe the missing ending issue was due to an aspect of DinkC that manifests differently in different versions of Dink Smallwood.

The ending is invoked by this script (A10-s5.c):

void main(void)
{
&confusion = 0;
&polymorph = 0;
int &bnut = count_item("item-fireb");
if (&bnut == 1)
{
kill_this_item("item-fireb");
add_item("item-kha",88, 3);
&cur_weapon = 1;
arm_weapon();
}
if (&screen_8 == 0)
{
goto end;
}
int &shoe = sp_y(1, -1);
if (&shoe >= 350)
{
goto end;
}
freeze(1);
move_stop(1, 8, 300, 1);
script_attach(1000);
fade_down();
&player_map = 398;
load_screen();
draw_screen();
draw_status();
sp_x(1, 313);
sp_y(1, 121);
sp_dir(1, 2);
fade_up();
kill_this_task();
end:
}


So, the ending will be skipped for two conditions:
  1. If screen_8 is 0
  2. If the player's Y coordinate is >= 350
screen_8 is set to 1 when the player clears the player clears the bottom-center screen. This was cleared in Tim's screenshot, so that's not the problem.

The player's Y coordinate... hey, that's weird. Why would the ending be skipped if the player's Y coordinate is >= 350? If the intention is that the ending is played when the player comes 'up', wouldn't we want to skip it if Dink's Y coordinate was <= 350?

Without digging into it too much, I suspect this is FreeDink's fault.
  • The official Dink Smallwood lineage versions (Dink Smallwood 1.06 through Dink Smallwood HD) likely do not update the player's Y coordinate until the first screen update. A10-s5.c is invoked before the first screen update, so when the script executes the player's Y coordinate is the last Y coordinate from the previous screen. This worked great back in 1999 (and, oddly, today with Dink HD), but not for FreeDink.
  • FreeDink likely 'fixed' this bug, so that the player's Y coordinate is accessible to DinkC before the first screen draw.
Now, oddly, if that's true, the ending is still accessible in FreeDink. All the player would need to do is is clear the bottom-center screen, then re-enter the center screen from any other direction. (And, doubly-oddly, the player should be able to reach the ending in any version by clearing the bottom-center screen and entering the center screen from either the left or right).

Now, as for why I remember the ending disappearing due to a non-ASCII character .d issue - I don't know. I assume I got that mixed up with another situation (maybe for the unreleased Clone War Demo?), and when I read Tim's issue I short-circuited Memory B with Memory A. Yay.
September 21st, 04:08 PM
goblins.gif
drone1400
Peasant He/Him Romania
C# nerd 
Interesting writeup, and very interesting difference between FreeDink and Dink/DinkHD. Perhaps it should be documented in the DinkC Reference website somewhere?

I'll have to check out the playthrough!

Alliance Command was one of my favorite DMODs back in the early 2000s.. I was always a fan of Warcraft 2 and the thought of playing a Warcraft 2 themed RPG was very exciting at the time

EDIT: The Y coordinate difference probably doesn't matter much at all for most DMODs, but I find it intriguing how many weird little peculiarities DinkC and the original Dink engine have.
September 21st, 11:14 PM
death.gif
Seseler
Peasant He/Him Heard Island And Mcdonald Islands
 
>EDIT: The Y coordinate difference probably doesn't matter much at all for most DMODs, but I find it intriguing how many weird little peculiarities DinkC and the original Dink engine have.

Well, it does matter in the base game; check out s1-mh-o, which works around the issue by wait()'ing:

void main( void )
{
wait(1);
 //Outside the Old wizard's house
 int &hcrap = sp_y(1,-1);
 if (&hcrap > 300)
 {
 playmidi("wanderer.mid");
 }
}


I've done a similiar things on Questlog and Ill Omens (I'll get around to finish it soon, I swear...).
September 22nd, 12:50 AM
peasantmb.gif
yeoldetoast
Peasant They/Them Australia
Oh, NOW YOU'VE DONE IT! 
>FreeDink likely 'fixed' this bug

Only temporarily in the old 108 SDL1.2 branch. In the source of the 108 branch, draw_map_game() is called after setting player X/Y in preparation for screen change.

This was altered after Cocomonkey's write-up, in the 109 branch, which has a commented line remarking upon the change in did_player_cross_screen() in which the screen is drawn first, and then player X/Y updated.