News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Wayne Greztky 3D hockey - fixing overtime rules  (Read 1655 times)

starfishmaster

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Wayne Greztky 3D hockey - fixing overtime rules
« on: February 04, 2016, 02:38:21 am »
In Wayne Gretzky 3D hockey (N64), the game ends after 1 overtime even if it's a tie. I would like to try and modify the game so that it only ends when a player wins. Is this possible? I was thinking that one could change the gameplay so that it will give overtimes until someone actually wins.

FAST6191

  • Hero Member
  • *****
  • Posts: 2465
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #1 on: February 04, 2016, 06:04:56 am »
First I should say I have no clue about US/Canada ice hockey rules, or indeed anything other than field hockey rules, and especially none about how extra time is handled (set period, sum of stoppages during play or something else).

Higher level rules changes can be harder to implement in games. This however could be doable.

Personally I would first go for implementing a sudden death mode instead of adding more set intervals of extra time but that should be doable as well.

I do not know how familiar you are with the general idea of programming loops (if, if else, while and though nobody ever uses it any more then goto -- https://xkcd.com/292/ ) and how they appear in code (usually some kind of compare or interrupt). You would then have to find the routine that checks for extra time to have finished and then add a set period for the extra interval. For the sudden death you would instead stop it from doing anything at the end of extra time and add a check to see if the scores are equal and then quit out if they are not.
This will be an assembly hack, probably not a massively involved one and a project you probably could learn with but still definitely an assembly hack.

starfishmaster

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #2 on: February 04, 2016, 12:21:39 pm »
This is exactly how I was thinking it would need to be done! You're right - it would be best to just have another sudden death (which is what it is in the game anyway, just with 1 extra time period) until someone finally scores.

I'm familiar with loops, however finding and interpreting them in assembly is another thing! I've been working on another hack that has made me understand it quite a bit more, but I'm far from proficient. What would you say is the best way to find this in the assembly? In previous hacks I have made adjustments to player speed/low gravity, so I was able to use Cheat Engine to watch variables change depending on what action the play was doing. I'm thinking I maybe able to find the timer function that counts down, where it may trigger some code when no one scores. If there are any other tools out you know of that would be awesome.

RyanfaeScotland

  • Sr. Member
  • ****
  • Posts: 348
    • View Profile
    • My Brill Game Site
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #3 on: February 05, 2016, 02:41:55 am »
If it is already in sudden death mode couldn't you just stop the count down timer for that extra period?

starfishmaster

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #4 on: February 05, 2016, 09:43:11 am »
that's actually a great idea, and should be much easier too. Thanks for the suggestion!

RyanfaeScotland

  • Sr. Member
  • ****
  • Posts: 348
    • View Profile
    • My Brill Game Site
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #5 on: February 08, 2016, 07:13:03 am »
How did you get on with this? Have you had a chance to look into it?

You actually inspired me to make a similar change to Speedball 2 on the Sega Megadrive. In that game you can knock people out and they get stretchered off the pitch and then a sub comes on. When doing up your player's stats you get 3 subs you can work on and I was curious what would happen if you stopped the timer and then just wailed on your opponent till everyone was stretched off. Results will appear in another topic but it was a fairly easy change to stop the timer.

Of course you are looking to only stop it in the extra period which will be a bit more difficult since the countdown routine is undoubtedly the same routine used in all periods so just blatting it altogether won't work as then it would never count down for normal periods.

I haven't worked on N64 stuff before but keep us posted with your progress none the less.

FAST6191

  • Hero Member
  • *****
  • Posts: 2465
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #6 on: February 08, 2016, 07:29:26 am »
Speedball - good version you say... I would be interested in seeing that. I think speedball was one of the first "on paper I should like this but the reality differs" games. Not sure why it took that long after starting games to happen, though probably something to do with me going by labels (or in the case of the amiga a hand scribbled name on a floppy) before then.
Nice link for those not so familiar with the series
https://www.youtube.com/watch?v=HPT73JEqfu4

starfishmaster

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #7 on: February 08, 2016, 10:32:05 am »
I haven't had much time to mess around with it recently (I was getting in some last minute modifications to NFL Blitz for a superbowl party I went to), but I did indeed find the address for the timer. Freezing it  stopped time from running, but this was also just in regulation, not overtime. Like you said, this address is most likely going to be the same one for each period, just that what it's being set to is different depending on if regulation or overtime.

The other issue is that for some reason the ROM I have doesn't open in nemu64...it gives me some error. this is a problem because it undoubtedly has the best debugging tools. It runs fine in project64 which is what I was able to use to find the timer address (using cheat engine to watch for a decreasing variable), but tracing how it's set will be a problem if I can't get it to work in nemu. Hopefully this week I can figure it out and get working on it. I will keep you posted as I (hopefully) figure it out.

February 10, 2016, 12:10:44 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I found the function that writes to the time variable (that if viewed as a float is the exact amount of seconds left in the period), however I haven't  been able to find out how to modify the value that it is set to for overtime. Before any of the periods begin (and overtime), a BEQ command writes to it checking to see if R0, R0 = some address. I assume this is what is checking to see the time needed and sets it.

The timer starts out at 41F00000 (30 seconds) in overtime, and as soon as the puck drops it gets written to by a SWC1 F16 command. I would think I just need to find what is setting the timer to 41F0000. In regular periods where the timer is at 2:00, the value is 42F00000 (120 seconds). Therefore, the function is checking to see what value is necessary and fetching that number from somewhere. Problem is I just haven't been able to find where that somewhere is.

I was thinking that because it's a float, the starting time (30 seconds in the case of overtime) would be set by LUI XX $41F0, where XX is a register (AT maybe)? I did a search for LUI AT, $41F0 to see if I could find anything that affected the gameplay but was unsuccessful. I would just do a search for 41F0, but there are hundreds of possible addresses related to this string.

February 10, 2016, 12:10:56 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
I found the function that writes to the time variable (that if viewed as a float is the exact amount of seconds left in the period), however I haven't  been able to find out how to modify the value that it is set to for overtime. Before any of the periods begin (and overtime), a BEQ command writes to it checking to see if R0, R0 = some address. I assume this is what is checking to see the time needed and sets it.

The timer starts out at 41F00000 (30 seconds) in overtime, and as soon as the puck drops it gets written to by a SWC1 F16 command. I would think I just need to find what is setting the timer to 41F0000. In regular periods where the timer is at 2:00, the value is 42F00000 (120 seconds). Therefore, the function is checking to see what value is necessary and fetching that number from somewhere. Problem is I just haven't been able to find where that somewhere is.

I was thinking that because it's a float, the starting time (30 seconds in the case of overtime) would be set by LUI XX $41F0, where XX is a register (AT maybe)? I did a search for LUI AT, $41F0 to see if I could find anything that affected the gameplay but was unsuccessful. I would just do a search for 41F0, but there are hundreds of possible addresses related to this string.
« Last Edit: February 10, 2016, 12:10:56 pm by starfishmaster »

RyanfaeScotland

  • Sr. Member
  • ****
  • Posts: 348
    • View Profile
    • My Brill Game Site
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #8 on: February 10, 2016, 05:12:17 pm »
I'm afraid I don't know the N64 tools well enough to give specific advice but you could always try and brute force it with some targeted corruption. Change all the 41F0 values to something else and run the game, you might get lucky and it still runs (albeit with some funny behaviour). If you can get as far as extra time then you can see if that was enough to change the clock. If it was change half of the values back and try again, if it has reset back to normal then you need to change the other half, if it hasn't then repeat again with the new half. If there are 100 41F0 values it'll only take 6 tries (best case) to narrow it down.

It's not very classy, but it works (sometimes).

starfishmaster

  • Jr. Member
  • **
  • Posts: 28
    • View Profile
Re: Wayne Greztky 3D hockey - fixing overtime rules
« Reply #9 on: February 24, 2016, 11:39:53 am »
Well, after about 2 weeks or so of off and on attempts at figuring this out, I finally got it. Here's the story:

The address for the timer is first set by the floating point register F12. Once it's in game, F16 does all the work, so really what I needed was to find how F12 was being set. The problem was that this function that initially sets the timer is being jumped to from all over, so it wasn't easy to find how F12 was being set.

I was able to follow it back a bit, and found an address loading a value (41F00000; 30 seconds for the amount of time in OT). NOPing this out made the timer not function (was always 00:00), so I knew this had to be where the value was coming from. I also saw that registers F22 and F24 had values of 42F00000 and 41F00000 respectively (120 seconds and 30 seconds respectively), so I figured that somehow these registers were where F12 was pulling values from and would chose which to use depending on if OT or regulation. I spent way too long trying to find out how to modify the value in F24, my efforts leading to a dead end.

However, I found that there was a jump (from somewhere unknown to me at the time) to the function that was initially setting F12 (bringing in either F22 or F24 depending on OT or reg), that would then be loaded into the timer address. I was able to find the address within the function that was being jumped to (it was a few lines up from the address setting F12), and did a search for a JAL to that address. Doing so thankfully only yielded about 5 addresses, each of which had a MOV.S command as seen below:

Original Code:
address      opcode                 hex value         comment
8003AB18   MOV.S F12, F24      4600C306   this uses the value in F24 (41F00000 = 30 seconds) for time
0x39F18 (in ROM)

to:

New Code:
8003AB18   MOV.S F12, F22      4600B306   this uses the value in F22 (42F00000 = 120 seconds) for time
0x39F18 (in ROM)

where in the first case, it would set whatever is in F24 to F12, and in the second case, F22 to F12. The game would determine which was needed (if in OT or regulation), and jump to these addresses to move the value in F22/F24 into F12.

So I simply changed F24 to F22. This simple change increased the OT time from 30 seconds to 120, more than enough time for someone to score. I never actually found out how F22 and F24 were set, but at this point I don't care.. it was too much work just to figure all this out. I was thinking of uploading a patch (probably the smallest patch known to mankind) in case others were interested as well.