Modifying Gravity in Blitz 2001 (Nintendo 64)

Started by starfishmaster, September 24, 2015, 01:31:11 PM

Previous topic - Next topic

starfishmaster

Hello everyone, I am new to ROM hacking, but have already made headway in this little project of mine.

My friends and I are huge Blitz fans (specifically the 64 version). The campy graphics and absurd rules give it some great replay value.

I recently thought it would be awesome (and hilarious) if one could modify the gravity within the game. I want to make it so that when a character jumps, or dives, or basically does any event resulting in the a vertical change, the "force constant" acting on the character is relaxed so that the players appear to have lower gravity.

Using a tutorial based on finding addresses related to a certain action, I have been able to narrow down a list of ~20 addresses that I believe are related to the character's vertical height.

So this is my question: Could I somehow add a multiplier to these address values so that it increases the characters z-height? For instance, lets say that the address has a maximum value of 80 when jumping normally. If I apply a 1.5x multipler to this value, it should make his max height 120. Is it possible to do this? I was thinking I would have to add an address that writes to that value, but I don't have the slightest clue if this is possible or not.

Also, if the above is not possible, but you have some ideas on how to go about doing this, please let me know.

Thanks!

FAST6191

I usually do this for 2d games but the logic is much the same in 3d, just with another coordinate in the mix (or not depending upon how the maths is calculated -- jumps have a habit of being a rather 2 dimensional affair unless you have wind involved) and possibly not all in hardware; sprites tend to have their own dedicated hardware which tends to get called something like OAM, however 3d models are a bit more fluid as the world is probably also a 3d model and what goes where is taken care of at more of a software level. Speaking of worlds that would possibly be the one major change -- for various reasons (ease of code, hardware bugs, because it was funny) in some games they adopt the bring the mountain to approach and will instead move the entire world, even if the world otherwise has many objects (assign them all to a child or make the player character a parent or child of something else entirely and move accordingly).

Anyway most people that do this sort of thing will tend to try understand the concepts the game might pass off as gravity*, and possibly physics (does it respect the object in motion concept for instance -- not many old games will). The main exception to this is moon jump when the game has a double jump feature -- you disable the check if second jump has been done check and there you have it. In a lot of older games, and even newer ones that do not lean heavily towards proper platforming/movement in a 3d space, you may well be dealing with some kind of canned animation. Sports games vary for this one and it is not actually so bad depending upon what is done -- you may well just have a translation matrix or series of matrices that is interpolated in some way, if so then yeah there is probably scope to multiply a matrix by a number, indeed depending upon its approach to numbers it might already be using a multiplier .

*as in you would be able to recreate the relevant parts of something like http://s276.photobucket.com/user/jdaster64/media/smb_playerphysics.png.html for your game.

Anyway yeah find the memory location that is responsible for your model in a given match/game, it might change between boots or even matches games so make a savestate. You might eventually have to adapt it for other models but for now you just want one. On older systems you actually have a branch logging feature so you would actually want to do everything but jump, once you have enough there then you jump. The different branch(es) that get used for said should not have come up before and you have your culprit.

You may well break the AI if you do change this -- a lot of AI will be based on the game originally falling within a known set of variables. If it is for you and your mates it might not matter so much (though with AI controlled players...) and the real game breaker tends to be speed (if the game is not using some kind of collision vector calculation anyway), not a slightly higher jump. If the game is really good it will probably take a stats based approach anyway.

starfishmaster

Thanks for the info Fast.

So if the situation maybe is where you mention that I maybe able to multiply a matrix with a number to scale the values, how exactly would one go about doing this? Like I mentioned, I have found a few addresses that are related to the character when he jumps. Is there some way to add an address to multiply that number? Or any other way?

Thanks again for the help!

FAST6191

For various reasons/on various systems floating point, or at least non integer, maths (which you kind of need for actual 3d) works better with numbers between -1 and 1 or some predefined range, especially if you are also playing with matrices. However the world distances might be considerably higher but this is fine as you can still multiply in the end. For those games you could find where the multiplier comes in and sort something out, indeed the game may force this if the players have different stats, I imagine some modern sports games almost reflect a sports management game/complex RPG like Skyrim or something in their memory structure but the N64 can vary this a bit but at the same time look at something older like speedball 2 and that changes again. If it is not in stats it is probably still a number somewhere, maybe editable quite simply once you know but it will probably take some fun with assembly before you get there -- it is why I linked up the mario physics page as most people that do these sort of hacks will understand a game/the gravity or movement setup to that level.
Not all games will do this and some will have its actors move with values in similar orders of magnitude to the world/apparent world on screen.

So yeah the grim spectre of assembly hacking has risen up to meet you here. You can put it off for a lot of things but changing game mechanics like this will meet it early on, probably not in one of the harder forms (I would considerably rather this than some kind of font hack to add in variably width font, ascenders/descenders and the like) but still assembly.

starfishmaster

I am fairly certain the address related to the character height is  1010f7b8 (a float like you said). When the character is not in the air (such as standing there, running, etc), it is 0. When I jump, it changes to ~8.12 at my characters maximum height.

Can I somehow add a command that will multiply what ever this value is? Could I just "add" a command that will take this value and then multiply it? If so, what software would be used for doing this? I have used LemAsm a bit, but have no clue if I can just add an assembly instruction to do this multiplication step.

FAST6191

Taking a value and adding to it/multiplying it* is how a lot of action replay/gameshark cheats work and just blinding writing to it/multiplying it is a simple way of hardcoding such a cheat, however floats make things a bit more annoying if you want to do maths (blind writes are just considered arbitrary hex data if it is floats, maths in such scenarios can be more annoying). Theoretically as well if you have 0 by default then multiplying that would make life marginally easier.

What is the data either side of that address? A decent bet would be either the other height values for players or the other location data for that player but I have not got it in front of me to test. You are going to want to find the rest eventually unless you want one character to be a superman but it might change how the data gets interpreted so best to do so earlier rather than later.
Anyway if you have that address find a debugging emulator and set a break on write to it. Follow that back up the chain (the actual write is probably the last thing it does and the instructions before it will be the good stuff) and figure out what the game is doing as far as multipliers or moving through a series of premade matrices/two points. If you know how something works then you know how to break it modify it.

*probably means of a logical shift (hence a lot of multiplier cheat codes being x2,x4,x8,x16 and such like) but hey.

starfishmaster

Hi Fast,

So I have successfully modified the gravity in the game! I was able to find a command (I think it was loading a constant) above the one that was writing to the player heights, modify it, and now the characters (all) jump much higher, as well as all animations related to the player height are scaled accordingly. However, I now have a question as to how to "hard code" the change into the ROM.

Using the commands tool in Nemu64, I found that address 800A4FD0 was calling a constant from 80084218. Using the memory viewer tool, I looked at the constant located at 80084218 and modified it to make the gravity lower. Therefore, the only thing I need to do is have the value at 80084218 be what I want to get low gravity.

So now that I know what I need to change, how do I change the actual ROM so that the value at 80084218 is what I want it to be? I have seen a few examples on using lensAsm, but am not quite sure if this is how to do it.

Thanks again for your help!

FAST6191

Nice one, sounds like you dodged a lot of potential issues that some games see.

Most would probably approach this from one of two ways

1) If it is just a memory value then hardcode a cheat to do it. If the game only grabs the value at the start of the game then adding something to change that to something else more or less constantly (say add a memory change command in a vblank). Your average action replay/gameshark basically does just this and hardcoding a value to be in memory like this is usually one of the first types of assembly hack people undertake when they are learning it.

2) Figure out how the value got there and alter that. I imagine you set some kind of breakpoint already, set one to break on write to 80084218. Find out what eventually writes it there and change that so something else -- there might well be some kind of crazy routine leading up to it but if all that is rendered moot by you simply changing that to stick a number in that 80084218 memory location then it is all good.

Either way the instruction will probably still be the same write value to memory (afraid I have not got the N64 MIPS manual in front of me and I am a bit hazy whether it writes in instructions or has a dedicated memory writing instruction, nothing drastic either way though).

starfishmaster

#8
It sounds like (1) is the easier route. This is where my naivete really shows... So how do I hardcode a cheat? Here are the memory changes I need to make:

80084218: 3C23D70A
I change this to
80084218: BD01FFFF

and I get low gravity. Also, I noticed that only the first 4 characters (3C23/BD01) actually change the character height. So how would I go about making a GS or hardcode a cheat to do this modification? Do I need a specific program? Do you have a good resource (walkthrough, tips etc) for doing this?

I saw in Nemu 64 that there is a gameshark cheat tab where  you can add cheats. However, I tried adding the line I want to change (80084218), but the code value only has 4 characters. Can I use this to add the cheat?

October 31, 2015, 03:57:25 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

I think I figured it out. I just used the GS cheat code entry, and it appears to have worked. Thanks again for your help!