Fixing The Damage Threshold Bug In Foundry VTT D&D5e

by Admin 53 views
Fixing the Damage Threshold Bug in Foundry VTT D&D5e

Hey folks! Ever run into a weird issue in your Foundry VTT D&D5e game where healing just doesn't seem to work right? You might be hitting a bug related to how the damage threshold is being handled. Let's dive into it, and I'll walk you through what's happening and how to potentially fix it.

The Bug: Damage Threshold and Healing Gone Wrong

So, here's the deal. Imagine you're trying to heal a character in your game. You've set up their hit points (HP) using the HitPointsConfig dialog, and everything seems fine. But then, when you try to apply some healing, something's off. It's like the game is misinterpreting the damage threshold, and the healing isn't being applied correctly. That's exactly the kind of situation this bug creates.

The core of the problem lies in a specific line of code. Basically, the game is using this condition: damages.amount < (this.system.attributes?.hp?.dt) ?? -Infinity. Let's break down what's happening here and why it's causing trouble. The main issue is the order in which JavaScript evaluates the different parts of this condition. The less-than operator (<) is being evaluated before the nullish coalescing operator (??). This is where things get a bit wonky. When you set the HP on the actor, the dt (damage threshold) value might end up as null instead of undefined. Here's the kicker: in JavaScript, -1 < undefined is false, but -1 < null is true. Yeah, I know, it's a bit of a head-scratcher. This unexpected behavior is what leads to the healing not working as expected. Let's go a bit deeper on this. You've probably experienced this: You are running a game, your player is a bit beat up and needs a heal. You roll for the heal, and nothing happens. Or worse, the heal does the opposite of what you want and ends up doing damage. It's frustrating, and it can disrupt the flow of your game. This is where the bug comes into play. The dt or damage threshold is the system's way of determining whether the healing should be applied. When it is incorrectly set, the game's calculations get messed up. The good news is, there's a relatively simple fix for this.

Step-by-Step Reproduction: Seeing the Bug in Action

Want to see this bug in action yourself? Here's how you can reproduce it in your Foundry VTT game. It's pretty straightforward, so you can easily test it and see the problem firsthand.

  1. Create a New Actor: Start by creating a brand-new actor in your D&D5e game. This will be the test subject for our little experiment. You can do this through the Actors directory in Foundry VTT. Make sure it's a fresh actor, so we can see the bug's effects clearly.

  2. Set Their HP: Next, head over to the HitPointsConfig dialog for the actor you just created. You'll find this in the actor's character sheet. Here, you'll set the actor's hit points (HP). This is a crucial step, as it's where the damage threshold might get initialized incorrectly. Enter a value for the maximum HP, and let's assume they haven't taken any damage yet.

  3. Simulate Healing or Damage: Now, try to apply some healing or damage to the actor. You can do this through a spell, item, or any other method you typically use in your game. The goal here is to trigger the healing or damage calculations.

    • If you're testing healing, try casting a healing spell or using a healing potion. Observe whether the healing is applied correctly, or if the character's HP doesn't change as expected. This is where the bug will rear its ugly head.
    • If you're testing damage, try hitting the character with an attack. This will also give us insights into how the damage threshold is being calculated. Check if the damage is being applied as it should or if something is interfering with the calculations.
  4. Observe the Results: Pay close attention to the results. If the healing isn't working, or if it's being applied incorrectly (e.g., healing is being blocked unexpectedly), you've likely encountered the bug. If the damage isn't applied, then you are experiencing the issue. This is a critical step, as it allows you to confirm whether the bug is present in your game.

By following these steps, you'll be able to see the bug in action and understand how it affects your gameplay. Knowing how to reproduce the bug is the first step toward finding a solution or applying a fix.

The Root Cause: Precedence and the Nullish Coalescing Operator

So, what's really going on under the hood? As we mentioned earlier, the main culprit is the order of operations in that problematic line of code. In JavaScript, the less-than operator (<) has a higher precedence than the nullish coalescing operator (??). This means the comparison (damages.amount < this.system.attributes?.hp?.dt) happens before the nullish coalescing. It's like JavaScript is saying, "Let's compare these numbers first, then deal with what happens if something is null or undefined." It's the order of operations that creates the problem. The way the code is written, when dt becomes null, the comparison can unexpectedly evaluate to true, even if the damage amount is positive. This means the healing calculation might be blocked or applied incorrectly. The null value essentially tricks the comparison, leading to the incorrect behavior. The ?? -Infinity part is meant to handle cases where dt is null or undefined. It's supposed to provide a default value to prevent unexpected behavior. However, because of the precedence issue, the default value isn't always used as intended. Understanding this precedence issue is key to understanding why the bug occurs. When the comparison is done before the nullish coalescing, the system is going to make the wrong call. This ultimately leads to the incorrect application of healing or damage.

The Simple Fix: Parentheses to the Rescue

Luckily, there's a quick and easy fix for this bug: add parentheses. By enclosing the entire condition within parentheses, you force the nullish coalescing operator to be evaluated first. This ensures that if dt is null or undefined, the comparison is done with the default value of -Infinity, as intended. With this simple change, the code will correctly handle null or undefined values for the damage threshold. This also means healing and damage should work as expected.

Here's how the fix looks: Change damages.amount < (this.system.attributes?.hp?.dt) ?? -Infinity to damages.amount < ((this.system.attributes?.hp?.dt) ?? -Infinity). The change is adding an extra set of parentheses. This might seem like a small change, but it makes all the difference! By adding parentheses, you prioritize the nullish coalescing operation.

This simple adjustment clarifies the code's intent and ensures that the damage threshold is correctly handled, regardless of whether dt is null, undefined, or a valid number. It's a small change that can make a big difference in the stability and reliability of your D&D5e games in Foundry VTT. This ensures that the healing or damage calculations are performed correctly. If you're comfortable with editing code, this is a quick and straightforward way to resolve the issue. If you're not comfortable editing code, then consider making a feature request so the code can be corrected.

Implementing the Fix: A Quick PR

So, if you are familiar with how to do a PR (Pull Request) on GitHub, you can do it for the Foundry VTT project. A PR is a way of submitting changes to a code repository. If you are not familiar with how to do a PR, you can learn by doing some searches online. It's a great way to contribute to open-source projects. For those who are not familiar, creating a Pull Request (PR) is a straightforward process.

  1. Fork the Repository: First, you'll need to fork the repository on GitHub. This creates a copy of the original repository in your account, where you can make and test changes without affecting the original. It's like having your own playground to experiment with the code.
  2. Clone the Repository: Next, clone the forked repository to your local machine. This allows you to work on the code using your preferred code editor. Open up your terminal or command prompt, navigate to the directory where you want to store the project, and use the git clone command. You'll now have a local copy of the code on your computer, ready to be modified.
  3. Create a Branch: It's good practice to create a new branch for your changes. This keeps your changes isolated from the main branch. Run the git checkout -b <your-branch-name> command. Now you are working on your isolated branch, so all changes you make will be specific to your fix.
  4. Apply the Fix: Now, you can actually implement the fix. You'll need to find the specific code file where the bug is located. Then, apply the change we discussed earlier, using parentheses to ensure the correct order of operations. Save the file. Ensure that you make only the minimum necessary changes, as it will make reviewing your PR easier. The goal is to address the issue in the code.
  5. Commit the Changes: After making the necessary changes, commit them to your local repository. This saves your changes and allows you to track them. Use the git commit -m "Fix: Damage threshold precedence issue" command. It is also good to describe your commit to make it easier for others to understand your changes. Write a clear and concise message to describe the changes you've made. This helps to provide more context.
  6. Push the Changes: Now, push your changes to your forked repository on GitHub. Use the git push origin <your-branch-name> command. This uploads your changes to your remote repository, where they can be reviewed and merged.
  7. Create a Pull Request: The final step is to create a pull request (PR). Go to your forked repository on GitHub, and you should see a prompt to create a PR. Follow the instructions to create the PR, and explain the changes you've made. Explain why you've made these changes. Provide any supporting information to help reviewers understand your fix.

These steps will help you submit a fix for the bug. Your contribution will improve the D&D5e game for all Foundry VTT users. This bug is a simple fix. But it underscores the importance of fixing issues that may occur, no matter how small. It shows how even minor errors can lead to unexpected behavior and impact the user experience. By fixing the bug, you'll be contributing to a better gaming experience for everyone.

Conclusion: Keeping the Healing Flowing

So there you have it, folks! The damage threshold bug in Foundry VTT D&D5e, explained and fixed. Hopefully, this helps you out. Remember, the core of the problem comes down to the order of operations in a single line of code. By adding a couple of parentheses, we can ensure that healing and damage work as intended, keeping your games running smoothly and your players happy. If you are experiencing this issue in your game, then now you know how to fix it! If you know how to do a PR, go do it. If you don't know how to do it, then hopefully, you learned something from this article. If you don't want to fix it, just know the work around. Ultimately, ensuring that your games run smoothly is the goal! Happy gaming!