Alliance Command Ending
Alliance Command
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):
So, the ending will be skipped for two conditions:
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.
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.
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:
- If screen_8 is 0
- If the player's Y coordinate is >= 350
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, 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.
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.
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.
>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:
I've done a similiar things on Questlog and Ill Omens (I'll get around to finish it soon, I swear...).
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...).
>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.
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.