Difference between revisions of "ADnD: Dragons of Flame/Game Mechanics and Techniques"
From SDA Knowledge Base
(→Enemies) |
m (→Enemy spawning (overworld)) |
||
(13 intermediate revisions by the same user not shown) | |||
Line 15: | Line 15: | ||
: - If the player is moving down, the enemies will spawn at the bottom of the screen | : - If the player is moving down, the enemies will spawn at the bottom of the screen | ||
: - If the player is standing still, the enemies will spawn in any of the 4 sides of the screen with equal probability | : - If the player is standing still, the enemies will spawn in any of the 4 sides of the screen with equal probability | ||
− | Once the side of the screen has been determined, the game randomly calculates the other coordinate. If the calculated spawning position coincides with an object, the | + | Once the side of the screen has been determined, the game randomly calculates the other coordinate. If the calculated spawning position coincides with an object, a new coordinate will randomly be generated within the next few frames (more detailed description for what determines when to calculate a new coordinate is missing). This means enemies will appear relatively fast also when the border is mostly filled up with objects.<br /> |
* Note: The only possibility for an enemy to spawn on the right side of the screen is if the player is standing still (and then it's a 25% probability). | * Note: The only possibility for an enemy to spawn on the right side of the screen is if the player is standing still (and then it's a 25% probability). | ||
Line 22: | Line 22: | ||
: - When the enemy is running into an obstacle, the movement direction is recalculated every frame until a direction moving away from the object is found. | : - When the enemy is running into an obstacle, the movement direction is recalculated every frame until a direction moving away from the object is found. | ||
: - If you make small pauses and thereby get out of sync with the enemy movements, you will notice they will also make brief stops, waiting for the positions to sync (same thing happens if they run into obstacles). | : - If you make small pauses and thereby get out of sync with the enemy movements, you will notice they will also make brief stops, waiting for the positions to sync (same thing happens if they run into obstacles). | ||
− | : - When the x- and y-distance to the player is equal, the x-movement is preferred. This means it's | + | : - When the x- and y-distance to the player is equal, the x-movement is preferred. This means it's comparatively safer to try and run past an enemy above or below than to do it a square to the left or right of the enemy. It's regardless a game of luck trying to walk right past an enemy though... |
==Enemies and damage== | ==Enemies and damage== | ||
− | The images in this section come from http://setsumei.html.xdomain.jp/famicom/adandddragonsofflame/adandddragonsofflame.html (except for the trap and Verminaard). The enemies described here are only the ones found in the dungeons. There are a couple of more enemies exclusive to the overwold. | + | The images in this section come from http://setsumei.html.xdomain.jp/famicom/adandddragonsofflame/adandddragonsofflame.html (except for the trap and Verminaard). The enemies described here are only the ones found in the dungeons. There are a couple of more enemies exclusive to the overwold. However, since the overworld encounters are only about hack-'n-slash, they don't require any additional description.<br /><br /> |
− | For enemies that deal body or weapon damage, the damage taken is calculated with the formula [Base damage]-[Front character's defense]. For enemies that deal projectile damage, only the base damage counts (meaning the damage is always the same for all characters, regardless of stats and equipment). For enemies that do both types of attacks, the damage is calculated as projectile damage, regardless of which type of attack was used.<br /><br /> | + | For enemies that deal body or weapon damage, the damage taken is calculated with the formula [Base damage]-[Front character's defense]. For enemies that deal projectile damage, only the base damage counts (meaning the damage is always the same for all characters, regardless of stats and equipment). For enemies that do both types of attacks, the damage is calculated as projectile damage, regardless of which type of attack was used. Note that despite this game is built on the dungeons and dragons lore, there is no RNG or "dice-rolling" involved in calculating the damage. It's completely deterministic.<br /><br /> |
'''Enemies dealing body or weapon damage'''<br /> | '''Enemies dealing body or weapon damage'''<br /> | ||
Line 34: | Line 34: | ||
[[File:ADD DOF-Griffon.png]] - Base damage 64. Can be jumped over. The hitbox is more to front of the sprite though so jump early (regardless if you're moving left or right).<br /><br /> | [[File:ADD DOF-Griffon.png]] - Base damage 64. Can be jumped over. The hitbox is more to front of the sprite though so jump early (regardless if you're moving left or right).<br /><br /> | ||
− | [[File:ADD DOF-Capac.png]] - There appears to be two versions of the | + | [[File:ADD DOF-Capac.png]] - There appears to be two versions of the Baaz Draconians. They look identical, but they deal different base damage. The first encounters are with the weaker version (base damage 32), but starting from around room 46, all Baaz are of the stronger version (base damage 46). It's not possible to pass a Baaz without taking at least one hit (unless using magic). But try to jump over their first attack to at least avoid taking two hits from the same enemy.<br /><br /> |
[[File:ADD DOF-Troll.png]] - Base damage 64. Generally, you will take two hits by trying to run or jump through a troll. However, a few things to note: | [[File:ADD DOF-Troll.png]] - Base damage 64. Generally, you will take two hits by trying to run or jump through a troll. However, a few things to note: | ||
Line 79: | Line 79: | ||
<br /> | <br /> | ||
'''Enemies dealing projectile damage'''<br /> | '''Enemies dealing projectile damage'''<br /> | ||
− | [[File:ADD DOF-Bozak.png]] - Just like the | + | [[File:ADD DOF-Bozak.png]] - Just like the Baaz, the Bozak Draconians come in two visually identical variants. The stronger variant (damage 46) starts occurring at the same time as the stronger Baaz variant. The weaker Bozaks deal 24 in damage. It's worth remembering that they deal no body damage. The projectiles can easily be avoided by ducking, for a small time loss (usually ~10 frames).<br /><br /> |
[[File:ADD DOF-Trap.png|60px]] - Traps deal 64 damage. Due to their fairly big hitbox, expect an evasive maneuver to cost in the vicinity of a second to avoid damage. It can be worth mentioning that Tasslehoff detects and disarms traps if he's in front. But since he should never be in front and his detection is announced by some time-consuming text, it's not relevant for a speedrun.<br /><br /> | [[File:ADD DOF-Trap.png|60px]] - Traps deal 64 damage. Due to their fairly big hitbox, expect an evasive maneuver to cost in the vicinity of a second to avoid damage. It can be worth mentioning that Tasslehoff detects and disarms traps if he's in front. But since he should never be in front and his detection is announced by some time-consuming text, it's not relevant for a speedrun.<br /><br /> | ||
− | [[File:ADD DOF-Goblin.png]] - 32 damage. The Goblin occurs only in | + | [[File:ADD DOF-Goblin.png]] - 32 damage. The Goblin occurs only in one spot and has to be defeated to progress.<br /><br /> |
[[File:ADD DOF-Ember.png|60px]] - 80 damage. Ember is the second-to-last boss. It attacks both through fire breath (set pattern) and body damage if you get too close.<br /><br /> | [[File:ADD DOF-Ember.png|60px]] - 80 damage. Ember is the second-to-last boss. It attacks both through fire breath (set pattern) and body damage if you get too close.<br /><br /> | ||
− | [[File:ADD DOF-Verminaard.png|60px]] - 40 damage. Verminaard, the last boss, | + | [[File:ADD DOF-Verminaard.png|60px]] - 40 damage. Verminaard, the last boss, attacks with magic from a distance and starts whacking if you get too close. |
==Magic== | ==Magic== | ||
Line 104: | Line 104: | ||
* ''Hold person'' - Similar to sleep and web. It's possible it works on different enemies. Difficult to see any use in a speedrun though. | * ''Hold person'' - Similar to sleep and web. It's possible it works on different enemies. Difficult to see any use in a speedrun though. | ||
* ''Spiritual hammer'' - Deals damage to enemies. Of no interest in a speedrun. | * ''Spiritual hammer'' - Deals damage to enemies. Of no interest in a speedrun. | ||
− | * ''Blessing'' - Effect unknown. The manual describes it as "Protection From Evil" (PFE). PFE was a spell in Heroes of the Lance that greatly | + | * ''Blessing'' - Effect unknown. The manual describes it as "Protection From Evil" (PFE). PFE was a very useful spell in Heroes of the Lance that greatly reduced the chance to get hit (and possibly the damage taken). The same effect has not been seen in Dragons of Flame. It's possible it only works against certain enemies? |
* ''Dispel magic'' - Blocks enemy magic on screen and prevents enemies from casting new magic for a few seconds. It's only relevant against Bozak Draconians and Verminaard. Of no interest in a speedrun, but makes fighting Verminaard trivial. | * ''Dispel magic'' - Blocks enemy magic on screen and prevents enemies from casting new magic for a few seconds. It's only relevant against Bozak Draconians and Verminaard. Of no interest in a speedrun, but makes fighting Verminaard trivial. | ||
* ''Heal'' - Restores 127HP (i.e. 50% of full health). | * ''Heal'' - Restores 127HP (i.e. 50% of full health). | ||
Line 112: | Line 112: | ||
==RAM-addresses== | ==RAM-addresses== | ||
+ | * 79 - Global counter that starts on reset. It provides entropy to the RNG-calculation that starts at instruction $D016. | ||
+ | * 83, 84 - RNG-addresses. Updated in the sub-routine that starts at instruction $D016. | ||
+ | * A0/A2 - The screen's (small) y/x-position | ||
+ | * 6452/6453 - The player's y/x-position on the screen | ||
+ | * 6457 - First character's defense | ||
+ | * 6458 - First character's HP | ||
+ | * 6462 and 646C - Enemy HP | ||
+ | * 646X - Enemy attack damage | ||
+ | * 6472,4*X - X = 0,1 or 2. Enemy movement direction in the overworld. 0 means the enemy is moving to the right, 1 to the left, 2 up and 3 down (0F means it's idling, waiting to sync up with the player). | ||
+ | * 6473/6474,4*X - X = 0,1 or 2. Enemy y/x-position in the overworld. | ||
+ | * 6475,4*X - X = 0,1 or 2. Counter that increases every (non-lag) frame and resets to 0 after reaching #$2F. When the value is #$10, the new enemy direction is random. When the value is #$0 or #$20, the enemy will pick a direction that follows the player. | ||
+ | * 6485 - Room number (dungeons) |
Latest revision as of 09:02, 13 November 2020
Contents
RNG
The RNG only matters for the overworld. The dungeon levels only depend on the player actions.
The RNG-addresses are $83 and $84. They're updated with a recursive formula, taking the global timer in $79 as entropy. The sub-routine starts at instruction $D016. The formula produces a sequence that doesn't appear to be possible to manipulate in real-time. Since the global timer in $79 starts running from power-on, it's essentially impossible to manipulate something even at the very start of the game.
Pressing the d-pad from a standstill position will move the player 16 pixels in the corresponding direction. The overworld can therefore be thought of as a grid of 16x16 pixel squares. Several of the events described below occur when the player occupy these corners. Below, these will be referred to as "intersections".
Enemy spawning (overworld)
If there are less than 3 enemies in the memory, the game does a random check every time the player reaches an intersection. The random check has a 25% chance of producing an enemy (the check starts at instruction $8DCD).
- Note 1: If the player is standing still, the check will be done every frame!
- Note 2: If there are no enemies or only one enemy, a check will be done for every missing enemy. So up to 3 enemies can spawn in a single frame.
The player actions determine to a certain extent where the new enemy will spawn:
- - If the player is moving to the right, the enemies will spawn at the bottom of the screen
- - If the player is moving to the left, the enemies will spawn at the left of the screen
- - If the player is moving up, the enemies will spawn at the top of the screen
- - If the player is moving down, the enemies will spawn at the bottom of the screen
- - If the player is standing still, the enemies will spawn in any of the 4 sides of the screen with equal probability
Once the side of the screen has been determined, the game randomly calculates the other coordinate. If the calculated spawning position coincides with an object, a new coordinate will randomly be generated within the next few frames (more detailed description for what determines when to calculate a new coordinate is missing). This means enemies will appear relatively fast also when the border is mostly filled up with objects.
- Note: The only possibility for an enemy to spawn on the right side of the screen is if the player is standing still (and then it's a 25% probability).
Enemy movement (overworld)
The general movement of enemies is "2 steps towards the player, 1 random step, 2 steps towards the player, 1 random step, etc". This pattern results from the check that starts at instruction $8EBA. The movement direction is updated every time both the player and the enemy are at intersections. A few observations:
- - When the enemy is running into an obstacle, the movement direction is recalculated every frame until a direction moving away from the object is found.
- - If you make small pauses and thereby get out of sync with the enemy movements, you will notice they will also make brief stops, waiting for the positions to sync (same thing happens if they run into obstacles).
- - When the x- and y-distance to the player is equal, the x-movement is preferred. This means it's comparatively safer to try and run past an enemy above or below than to do it a square to the left or right of the enemy. It's regardless a game of luck trying to walk right past an enemy though...
Enemies and damage
The images in this section come from http://setsumei.html.xdomain.jp/famicom/adandddragonsofflame/adandddragonsofflame.html (except for the trap and Verminaard). The enemies described here are only the ones found in the dungeons. There are a couple of more enemies exclusive to the overwold. However, since the overworld encounters are only about hack-'n-slash, they don't require any additional description.
For enemies that deal body or weapon damage, the damage taken is calculated with the formula [Base damage]-[Front character's defense]. For enemies that deal projectile damage, only the base damage counts (meaning the damage is always the same for all characters, regardless of stats and equipment). For enemies that do both types of attacks, the damage is calculated as projectile damage, regardless of which type of attack was used. Note that despite this game is built on the dungeons and dragons lore, there is no RNG or "dice-rolling" involved in calculating the damage. It's completely deterministic.
Enemies dealing body or weapon damage
- Base damage 24. Can easily be jumped over. The hitbox is more to front of the sprite though so jump early (regardless if you're moving left or right).
- Base damage 64. Can be jumped over. The hitbox is more to front of the sprite though so jump early (regardless if you're moving left or right).
- There appears to be two versions of the Baaz Draconians. They look identical, but they deal different base damage. The first encounters are with the weaker version (base damage 32), but starting from around room 46, all Baaz are of the stronger version (base damage 46). It's not possible to pass a Baaz without taking at least one hit (unless using magic). But try to jump over their first attack to at least avoid taking two hits from the same enemy.
- Base damage 64. Generally, you will take two hits by trying to run or jump through a troll. However, a few things to note:
- In room 97, you will only be damaged once by running straight through the troll.
- There is always a frame-perfect jump that allows you to only be damaged once. (since the game runs at 30fps in the dungeons, the window for this jump translates to two actual frames)
- Attacking a troll will temporarily stun it and guarantees that you will only take one hit. An attack costs 10 frames, but is often well worth it considering the massive damage a second hit from a troll means.
- Base damage 46. Not possible to jump over without taking damage (one or two hits). Similar to the troll, you can guarantee only taking one hit by attacking it first.
- Base damage 32. Not possible to jump over without taking damage (one hit). With an attack and jump right after, you can get by without taking damage.
- Base damage 32. Can be jumped over without taking damage. You need to jump fairly late to avoid taking a hit on the way down.
As mentioned above, to get the damage dealt by these enemies, the base damage is subtracted by the front character's defense. It hasn't been investigated exactly how the defense is calculated, but it's likely a combination of one or several of the base stats and the equipment. Since changing equipment is far too costly in time compared to the benefits, only the default defense needs to be considered.
Defense | |
Caramon | 10 |
Riverwind | 12 |
Raistlin | 0 |
Sturm | 15 |
Goldmoon | 7 |
Tanis | 13 |
Flint | 12 |
Tasslehoff | 7 |
Enemies dealing projectile damage
- Just like the Baaz, the Bozak Draconians come in two visually identical variants. The stronger variant (damage 46) starts occurring at the same time as the stronger Baaz variant. The weaker Bozaks deal 24 in damage. It's worth remembering that they deal no body damage. The projectiles can easily be avoided by ducking, for a small time loss (usually ~10 frames).
- Traps deal 64 damage. Due to their fairly big hitbox, expect an evasive maneuver to cost in the vicinity of a second to avoid damage. It can be worth mentioning that Tasslehoff detects and disarms traps if he's in front. But since he should never be in front and his detection is announced by some time-consuming text, it's not relevant for a speedrun.
- 32 damage. The Goblin occurs only in one spot and has to be defeated to progress.
- 80 damage. Ember is the second-to-last boss. It attacks both through fire breath (set pattern) and body damage if you get too close.
- 40 damage. Verminaard, the last boss, attacks with magic from a distance and starts whacking if you get too close.
Magic
Unlike in the previous game in the series, Heroes of the Lance, you need to enter the menu every time magic is used. It's therefore generally too time-consuming to cast in a speedrun considering the often moderate effect.
Raistlin's magic
- Charm - Apparently renders humanoids docile. Of no interest in a speedrun.
- Sleep - Freezes at least some enemies in place long enough to run past them. It works for example on trolls and is the fastest method (fewest menu presses) to get through them without taking damage. Of no interest for an optimized speedrun, but could be worth keeping in mind in a casual or marathon run.
- Magic missile - Deals damage to enemies. It's by far the most efficient way to deal with Ember (the second-to-last boss). Otherwise not worth it (it doesn't deal enough damage to kill enemies in one shot).
- Web - From a glance, seems to work similar to the sleep spell. It's possible it works on different enemies. Difficult to see any use in a speedrun though.
- Burning hand - Deals damage to enemies. Since it doesn't have any special ability like the magic missiles, it's of no interest in a speedrun.
- Fireball - Deals damage to enemies. Of no interest in a speedrun.
Goldmoon's magic
- Cure light wounds - Restores 51HP (i.e. 20% of full health).
- Hold person - Similar to sleep and web. It's possible it works on different enemies. Difficult to see any use in a speedrun though.
- Spiritual hammer - Deals damage to enemies. Of no interest in a speedrun.
- Blessing - Effect unknown. The manual describes it as "Protection From Evil" (PFE). PFE was a very useful spell in Heroes of the Lance that greatly reduced the chance to get hit (and possibly the damage taken). The same effect has not been seen in Dragons of Flame. It's possible it only works against certain enemies?
- Dispel magic - Blocks enemy magic on screen and prevents enemies from casting new magic for a few seconds. It's only relevant against Bozak Draconians and Verminaard. Of no interest in a speedrun, but makes fighting Verminaard trivial.
- Heal - Restores 127HP (i.e. 50% of full health).
- Turn undead - Effect not investigated. According to the manual, it attacks or turns away undead. Of no interest in a speedrun.
- Cure critical wounds - Restores 204HP (i.e. 80% of full health).
- Raise dead - Unlike in Heroes of the Lance, you can now revive lost characters at any time and not only where they perished. Of no interest in a speedrun, but a good fail-safe to keep in mind in a casual or marathon run.
RAM-addresses
- 79 - Global counter that starts on reset. It provides entropy to the RNG-calculation that starts at instruction $D016.
- 83, 84 - RNG-addresses. Updated in the sub-routine that starts at instruction $D016.
- A0/A2 - The screen's (small) y/x-position
- 6452/6453 - The player's y/x-position on the screen
- 6457 - First character's defense
- 6458 - First character's HP
- 6462 and 646C - Enemy HP
- 646X - Enemy attack damage
- 6472,4*X - X = 0,1 or 2. Enemy movement direction in the overworld. 0 means the enemy is moving to the right, 1 to the left, 2 up and 3 down (0F means it's idling, waiting to sync up with the player).
- 6473/6474,4*X - X = 0,1 or 2. Enemy y/x-position in the overworld.
- 6475,4*X - X = 0,1 or 2. Counter that increases every (non-lag) frame and resets to 0 after reaching #$2F. When the value is #$10, the new enemy direction is random. When the value is #$0 or #$20, the enemy will pick a direction that follows the player.
- 6485 - Room number (dungeons)