It is currently 07 Jul 2021, 11:57
   
Text Size

Shandalar - Program Bugs

2-color enemies overlap others in shandalar_duel_victories[] (fix completed)

 

Monsters like Fungus Lord and several others offer tribute despite only being beaten once. This, I think, is an old Shaldalar bug that just couldn't be fixed before. I'm sure for Fungus Lord, as he starts offering Tribute after only being defeated once.

Since the update, I've noticed this happenning with other monsters too, if I spot any more I can probably add it to the comments here?
Last edited by Korath on 23 Sep 2015, 00:52, edited 1 time in total.
Reason: retitle from "Some monsters offer tribute at odd times"; version Thieves Hideout 2->Ruined Tower 1

Comments

Posted by Korath » 23 Sep 2015, 00:50

Looks like it's only storing the enemy's class and its wanderer color (which is always just one color), rather than its full color. For most enemies there's no overlap, but for nine of the ten 2-color enemies there is:
  • Centaur Shaman is black, green, and ENEMYCLASS_DRAGON (why, I dunno) so overlaps with Mandurang (black) and Prismat (green).
  • Centaur Warchief is red, white, and ENEMYCLASS_DRAGON (again, I dunno why) so overlaps with Dracur (red) and Kiska-Ra (white).
  • Elementalist is blue, red, and ENEMYCLASS_FEMALEWIZ so overlaps with Seer (blue) and Sorceress (red).
  • Lord of Fate is black, white, and ENEMYCLASS_KNIGHT so overlaps with Undead Knight (black) and Crusader (white).
  • Tusk Guardian is green, white, and ENEMYCLASS_LORD so overlaps with Beastmaster (green) and Paladin (white).
  • Ape Lord is green, red, and ENEMYCLASS_LORD so overlaps with Beastmaster (green) and Goblin Lord (red).
  • Mind Stealer is black, blue, and ENEMYCLASS_LORD so overlaps with Vampire Lord (black).
  • Fungus Master is blue, green, and ENEMYCLASS_MALE_WIZ so overlaps with Conjurer (blue) and Druid (green).
  • Sedge Beast is black, red, and ENEMYCLASS_TROLL so overlaps with Troll Shaman (red).
On the one hand, there's only one byte per duel victory to store both an enemy's wanderer color and enough data to identify its type, if we still want to distinguish e.g. between Fungus Masters starting out in forests and ones starting out in islands (and I think we do). On the other, shandalar_duel_victories[] is widely-enough referenced, and in the middle of large-enough functions, that it's going to be difficult to change its semantics at all without rewriting all those functions entirely. Either way, it'll break savegame compatibility.

Posted by lujo » 23 Sep 2015, 08:30

Hmmm, but as is it breaks the game, tbh. If monsters start behaving like you've allready made them run (or even offer tribute) it means several things:

1 - chasing them around for quests is unreasonably difficult compared to everything else, for no good reason. Chasing around a Fungus Master can get annoying, even if it sounds minor.
2 - You can (easily) get dual color monsters to give you tribute, and those guys are likely to have either a very desirable mana base (and strip mines and mishra's factories and what have you)
3 - You get free stuff for no reason at all - get enough monsters to tribute status and the only things you are fighting are quest monsters and lvl 6 minions. It's raining jewels, cards, what have you.

And that's just the effects that leap to mind wihtout seriously thinking. I'd say broken save games would be very small fry compared to getting a major thing like that fixed.

Not to mention that if there's even a slight chance of getting dungeon wins to not count, and in that way getting rid of that bit of abuse (go into a dungeon with a deck that's guaranteed to abuse life carrying over, beat everything up, walk around invincible afterwards just collecting tribute), that would be huuuuuuge (and it would also probably open up to totaly customize dungeons - custom enemies, custom dice reward pools, custom enemy starting card - every dungeon a mini-shandalar, that's a dream that might just take fiddling with those functions to come true).

How much you want to do any of this, is ofc your own decision. I'd personally take a time machine to when I was a kid and learn to code so I could do it, but that's just me. That's been bugging me for something like 2 decades (and now I know why it was so) XD
Last edited by lujo on 23 Sep 2015, 08:34, edited 3 times in total.

Posted by Korath » 23 Sep 2015, 22:06

I'm not concerned about breaking savegame compatibility, though of course I'd prefer a solution that could avoid it.

The bigger problem here is that the code that manipulates the data in question is poorly isolated - it's stuck in the middles of some very large functions. It's always more difficult and errorprone to replace part of a function than to replace the whole thing, and the overall purpose of several of those large functions is completely unknown, so it'll be difficult to check for side effects.

Getting dungeon wins not to count, on the other hand, just means I'd have to remove it from one place, and it's a place where I already know more or less what's going on. That's a lot easier.

Still, I'd rather get this right the first time, and robustly enough that if we actually can add another couple or dozen or hundred new enemy types, we don't end up with the same problem again down the road.

Posted by Korath » 16 Oct 2015, 23:47

Dungeon wins, in fact, don't count. The only thing that does is normal duels in the wilderness. (And duels with lieutenants in the wilderness, if you consider those abnormal.)

You can test for this (sort of) easily by:
  1. Start a new game as a red wizard (for the Staff of Thunder)
  2. Wander around forests to encounter green enemies
  3. Force win through the cheat menu against those and take dungeon hints until
    1. you see the location of at least one dungeon with creatures of a non-green color, preferably red or blue (which are the easiest terrains to avoid), and preferably two or more dungeons of the same color so you can get to it conveniently; and
    2. you have five or more wins against one type of green enemy
  4. Verify that the enemy that you have five wins against offers tribute
  5. Trek to the dungeon, avoiding creatures of your target color and all 2-color creatures (Staff of Thunder for emergencies)
  6. Wander around the dungeon and defeat enemies with the cheat menu. Deliberately answer quizzes wrong to get more enemies.
  7. Repeat until you have at least five wins against a particular creature. Preferably more than one kind of creature; but don't get more than nine against any. (9 wins make it so a creature type doesn't get spawned anymore. Though it doesn't actually matter, since that uses the same counter as tribute and fear, and the whole point of this is to show that dungeon victories don't count.)
  8. Leave the dungeon and track down the creature you only have dungeon wins against. Again, avoid dual-color creatures.
  9. Observe that it doesn't offer you tribute.

Posted by Korath » 17 Oct 2015, 04:16

commit b1b50557666bd6b960fa11a00c72b5647f8b9f49
Author: Korath <dgk@Dirge.none>
Date: Fri Oct 16 23:59:52 2015 -0400

[NB] FIX #741: change shandalar_duel_victories[] semantics; make configurable

This was an array of 1000 bytes, each representing a duel victory for the
player; the low four bits of each held the enemy's enemy_class, while the high
four held its color of origin. This wasn't enough to uniquely identify any of
the two-color enemies except Winged Stallion, was one of many barriers to
adding new enemies (as they would also overlap), and - while not enough so to
actually matter - is gratuitously inefficient, both in performance and
capacity.

So change it to an array of uint8_t[5][199], with enough room to store 255
victories against each of 199 enemy types in each of five colors, with four of
the five remaining bytes devoted to a total count (so it doesn't need to be
recomputed every time it's used). If we ever need more enemies than that,
it'll be easy to move the array completely into Shandalar.dll; the only
untouched uses still in Shandalar.exe are in H_SHANDLAR_startup1() (which
clears it) and save_or_load_ver1() (the back end of saving and loading games).

While the array no larger than the old one, it still breaks savegame
compatibility, at least to the extent that your old victory counts will be
lost, and you'll get a new set containing gibberish. It's all the more
insidious in that it won't affect the numbers displayed in the status screen,
which are kept track of separately but probably aren't used for anything else.

Since all three checks are directly based on and proximate to the victory
array, make the minimum number of victories over an enemy type to make it run
away, to make it offer tribute, and to prevent it from being spawned at all
configurable.

ENEMYCLASS_BOSS life is also directly dependent on victories (against creatures
that spawned in the appropriately-colored terrain); so move the life-
computation logic into Shandalar.dll. It was inlined in all four places used
in the executable - wise man's hint, initialize statwin.dll (which displays
wizard animations and the static wizard status screen), display wizard status,
and actually set life at the start of a duel - which was pretty irritating.

Shandalar.ini:
[Enemies]VictoriesForFlee
[Enemies]VictoriesForTribute
[Enemies]VictoriesForNoSpawn

Support:
shandalar_years_arzakon_banished_for()
shandalar_register_duel_victory()
get_total_duel_victories()
enough_duel_victories_for_tribute()
enough_duel_victories_for_no_spawn()
enough_duel_victories_for_flee()
duel_victories_against_color()
life_of_enemy()
shandalar_get_wizard_life_for_wiseman_hint()
set_initial_enemy_life()

inject_inc_eax()
inject_add_ebp_eax()
inject_mov_eax_ebp()
inject_mov_ebp_eax_wide()
Last edited by Korath on 17 Oct 2015, 04:24, edited 1 time in total.
Reason: commit hash changed due to rebase

Posted by lujo » 19 Oct 2015, 13:40

Impressive work!

Ticket details

  • Ticket ID: 741
  • Project: Shandalar
  • Status: Fix completed
  • Component: Adventure Mode
  • Project version: Ruined Tower 1
  • Priority: Normal
  • Severity: Normal
  • Assigned to: Korath
  • Reported by: lujo
  • Reporter's tickets: List all tickets
  • Reported on: 22 Sep 2015, 20:52
  • Last visited by Korath » 01 Nov 2015, 17:53.
 

Login Form