Jump to content
NHL'94 Forums

Leaderboard

Popular Content

Showing content with the highest reputation on 08/30/2024 in all areas

  1. Problem: There is a bug in the SNES code responsible for calculating the Hot/Cold Bonus for every player attribute (Speed, Agility, etc.). As a result, no attribute receives a negative bonus; instead, the attribute is consistently given the maximum boost (15) if the bonus was negative. An unsigned division error caused the bug, the details can be found here. Solution: Fix the division error if the Boost is negative, preventing the Max Boost from being applied. This limits the Boost from (-3 to +3) per attribute as intended. Technical Details: We convert the negative number to positive for the division, then revert it to negative and apply the bonus. If the number was already positive, no changes are required. New Code: Special thanks to @chaos for helping with the assembly and providing GENS documentation on player attributes, bonuses etc. Patch: Download the patch tool to create your own ROM or patch an existing ROM. Hex Version: 1) Replace old hex value with new hex value. =========================== Headerless ROM (.SFC) =========================== ROM Offsets: (hex) FD224 Old: B9 12 1A 4A 4A New: 20 32 FB EA EA ROM Offsets: (hex) FFB32 Old: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF New: B9 12 1A 10 09 49 FF 1A 4A 4A 49 FF 1A 60 4A 4A 60 =========================== Headered ROM (.SMC) =========================== ROM Offsets: (hex) FD434 Old: B9 12 1A 4A 4A New: 20 32 FB EA EA ROM Offsets: (hex) FFD32 Old: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF New: B9 12 1A 10 09 49 FF 1A 4A 4A 49 FF 1A 60 4A 4A 60 NHL '94 (USA)_Hot_Cold_Patched.zip
    2 points
  2. I have documented all the Player Attributes + Team Bonuses + Hot/Cold Code in the SNES rom. Below are the details. Overall very similar except for the rescaled attribute values and the HUGE Hot/Cold bug on the SNES side. Genesis / SNES Comparison: Player Attribute Details: Bonuses / Disadvantages: · PP + : Positive (0 to +3) Applied to the team on the PP · PK - : Negative (-3 to 0) Applied to the team on the PK · Home/Away +/-: Negative or Positive (-3 to +3) based on your teams Home/Road · Rubber Band +: Positive +2 applied when losing or tied early in the third or in OT Goalies: Do not get Bonuses / Disadvantages applied to their attributes, only Hot/Cold. Hot/Cold function: 1) Takes a random number (-12 to +10) divides by 2 then divides by 2 again. 2) Adds this number back to the rescaled value. 3) Constraints the attribute to stay within the 0 to 15 range. Hot/Cold Bug: A division error on the (-12 to +10) causes HUGE fluctuations in SNES, often resulting in large positive jumps. I would say this is similar to the GENS weight bug, in terms of being a coding error Example of the Bug: 1.Starting Values: - Benoit Brunet's agility was originally 2 out of 6. - This value was rescaled to 5 out of 15. No bonuses were applied. 2.Random Number Impact: - A random number of $F5 (-11 in decimal) was generated to adjust agility due to "Hot/Cold" status. - This number should be halved (divided by 2) twice in the calculation. 3. First Division by 2: - Instead of correctly calculating -11 ÷ 2 = -5, the instruction treats the number as if it’s positive (unsigned), which gives a wrong result of 245 ÷ 2 = 122. 4.Second Division by 2: - The incorrect value 122 is halved again to get 61. - This should have instead halved -5 to get -2. 5.Adding the Original Agility Value: - The program adds the original rescaled value of 5 to the incorrect 61, resulting in 66. - The correct calculation should have been 5 + (-2) = 3. 6.Capping the Result: - Since 66 is greater than the maximum allowed agility of 15, the value is capped at 15. - In the correct calculation, the final agility value would have been 3, which is already under the cap. **Summary:** Due to the bug, Benoit Brunet's agility incorrectly increases to the maximum value (15) instead of decreasing to (3) as it should, because the negative number was mistakenly treated as a positive number during the calculations.
    1 point
  3. For those who don't want to watch me ramble for over an hour on my stream (btw stream is here - https://www.twitch.tv/videos/2120586640) Using the source code from 92 (Link - NHL Hockey Source Code), we are now able to find out how things work a lot easier than finding a needle in a haystack like we had done in the past. NHL94 has improved upon 92, but much of the code is the same (with some refinements and added things, like bonuses). The most important thing is we have an idea how the RAM is laid out (basically all the variables for the game). How does checking work in 94? Weight is involved. Where you are on the rink is involved (You're getting checked against the boards? You're getting knocked down). Checking rating is involved. Also, impact value is involved (how hard you are hitting depending on your velocity and your opponents velocity, and the distance between the 2 of you). Are you controlling the player checking, or is the AI? Also, the weight bug (lets lighter players check heavier players, regardless of a lot of factors above) - Here's the checking formula for 94: Check if checking player is in checking animation If impact value is more than 20 decimal, the check will initiate. If not, there will only be momentum transferred between the 2. Starting value for calculation (120 decimal or 240 decimal if player controlled) - Subtract (Wgt * 8) of player checking - Add (Wgt * 8) of player being checked - Divide total by 2 - Check if player will hit the wall (see below) - Subtract impact value - If the total is 0 or negative, proceed to knock down. - If total is positive, then check if player will hit wall. If he will, proceed to knock down. - If total was positive, and player is not near a wall, then randomize the result from above (the RNG will choose a number >= 0 and < result from above) - Load the checking attribute (which is Chk rating * 5 + bonuses (Hot/Cold and 3rd Period Bonus). Divide it by 2 (Value will be between 0 and 15) - Next, subtract Checking value from above from the RNG result. If the answer is <= 0, then proceed to knock down. If positive, then check Agression attribute and see if there will be a penalty from the hit. Knock down section also checks for penalty from contact, but there is slightly less of a chance of a penalty compared to them not getting knocked down. After this part of the code, it will check for toddle (related to stickhandling). This checking formula is almost the same as it is in 92, except for the fact that some math is different (there's no bonuses, attributes are on a 0-15 scale instead of 0-6), the starting value for ALL checks is 60 decimal. In 94, the attributes are stored in RAM with a 0-30 scale (which is why you see a divide by 2 in a few places here). What's the weight bug problem? Lighter player can check heavier players with ease, when player controlled. This is because of the large boost given to the starting value. The subtracting and adding of the weight in this formula is done "byte" size, which means that value can never be over 255, it will overflow and 256 = 0 (it will start over at 0). Because of this, the rest of the calculation is pretty much thrown out the window (impact value will play a very small role in a weight bug check). So how to fix the weight bug? Remove the boost to the starting value when player controlled. I believe this may have been left in during testing, since the formula itself is almost the save as in 92. If the starting value was set to 120 decimal for both AI and player controlled checks, we would see much more "realistic" results. Weight difference won't be a huge factor anymore (still a bit of a factor), but impact and checking attribute would play more of a role. What's impact value? This is something I was able to figure out using the source code. The game tracks the velocity of the players (speed + direction). When it senses 2 players are close enough for contact, it will calculate a transfer of momentum between the players (when players hit, they slow down, bump each other back, etc). So it will calculate impact based on the velocity of both players, and the distance between them. The players speed is controlled by their acceleration, which in turn is controlled by Wgt and Agl attributes. So the faster a player is going, the more impact they will cause. If 2 skaters are skating at each other, the impact will be higher. If a player getting checked is skating away from the checker, the impact will be lower. If you hit the player near the end of your speed burst, the impact may be lower (not going as fast as you originally were). Funny thing is even with the weight bug, its actually harder for Theo Fleury (3 wgt) to check Marty McSorley (14 wgt), than it would be for him to check someone like Mats Sundin (7 wgt). He needs some impact to check Marty, where as with Mats, as long as he meets the minimum impact value to initiate the checking calculation, hes knocking him down. Here are some examples with weight and impact: 4 wgt checking (player controlled) a 10 wgt with minimal impact just makes it to the knock down phase (-4). 4 wgt AI player can do it with a ton of impact though (and some RNG luck). Closer weights here. 5 wgt AI checking a 7 wgt player with 50 impact value can definitely have a shot with some RNG luck (RNG result would be between 0 and 18 here), then subtracting the Checking attribute (0-15 scale after divide by 2). Marty McSorley might be able to survive this check from Theo Fleury with the right RNG and minimal impact. AI controlled Mario Lemieux might struggle knocking down Mike Gartner with low impact. Gotta get a good RNG roll (low value here).
    1 point
×
×
  • Create New...