Game Mechanics And Codes

If you are stuck in the Dunan Unification Wars; or wish for more details on the gameplay systems, this is the place.
User avatar
BadPotato
Posts: 170
Joined: Mon Feb 09, 2009 10:07 am
Location: Canada - Québec

Re: Game Mechanics And Codes

Post by BadPotato »

Last year, I think I managed to find one of the main RNG in the game without realizing, while trying to get an "huh" event with Viki to teleport in the raddat shop, when using the PSX debugger with breakpoint. Sadly, I just can't manage to understand how to get around with "creating" some raw disassembling, I would need to do some easy exercise... but anyway :

Code: Select all

"Freeze the RNG and get no random battle
80109960 FFFF
80109962 FFFF
This RNG(random number genrator), have several affect on the game :
  • It affect what gonna be next random battle such as what kind of enemy and how many of them.
  • If your already in a random battle and try to flee, the RNG is rolled in order to see if it work(same code at top for auto-success)
  • This RNG have a minor effect on battle pattern when confirming for an action turn, but I believe there some other (random)factor, that affect an action turn.
  • When talking to Viki for teleport and menu pop up, the RNG is already rolled to see if your gonna be teleported at some random location.
  • Also, locking the RNG might have several drawback effect such as delaying Tai ho from playing on Chinchirorin.
  • From my test, this code isn't aera specific
Also, some people might be interested about what is the % of getting in second floor of the raddat shop, when talking to Viki. But, I'm unsure about what kind of method could be used to find this kind of info, without having to somehow bruteforce 0xFFFFFFFF(in decimal) different values.
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

One of the script files surely handles the teleporter, and the function that tries to throw you off course ought to be in there. It's probably governed in a manner similar to drops.

Freezing RNGs is usually driving a nail with a bazooka. If you want to make a no random encounters code that has a bit more finesse to it, I suggest you start with the Champion's rune digit from the guide on the site. I took a quick look, and I'm pretty sure there's something to be discovered there.

What you've frozen is the running value of the library rand() function, which is used for everything. Maybe you know where the function is, because that'll help. If you compare calls to rand() with instances of the Champion Rune digit, you should know when you've found it.
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

OK, I'm going to turn this into a little bit of a class, unless somebody tells me to shut up.

My preferred method of hacking/reverse-engineering is to treat it like any other investigation (somebody once called it the "No Method Method"). I know a lot of people who get caught up in a "I want to do X. Where's the step-by-step method for doing that?" mentality, and it seems so limiting. When you're investigating, rather than following instructions, you take what you already know, and apply it to find out what you don't. Using the "No Random Battles" code mentioned previously as an example, here's the approach I took.

What is known:
  1. You randomly encounter enemies when walking in dungeons or the world map.
  2. There is an item in the game that prevents or lessens random encounters, the Champion Rune.
  3. The Champion Rune only blocks encounters if the enemy party can be let go, rather than run from.
  4. The ID of the Champion Rune is 0x40 when equipped.
  5. The game breaks its functionality down into files, and only loads them when necessary. However, random encounters can occur almost everywhere, and on every type of map. The code for it will need to be loaded most of the time, if not all the time.
Given that, I started by searching the main executable for Immediate values of 0x40. An "immediate value" is a concept in low-level programming. It means that the operations data values are either contained in the operation itself, or inline with the code. "Immediate" is a type of "addressing mode". The MIPS RISC processor that the PSX uses can handle immediate values of up to 16-bits, and good high-level compilers will tend to optimize such values so that they're immediate rather than stored in memory as variables. So, since the ID is a small amount of data, immediate values seems a good place to start.

This search returns about 600 results. That's a lot, but I can pare it down further. I'm only interested in operations that place the value 0x40 on a register, so I can exclude places where 0x40 is the index in a load operation, where the zero register is not the first operand, AND operations, Set Less Than operations, etc. Note that the "zero" register is special-purpose. It's hardwired to be zero at all times, so it fills in when you need to compare to zero, or when you just need one of the operands to be zero. It cannot be modified, and any attempt to do so is an illegal operation.

After narrowing it down, I'm left with less than 50 operations to look at. Most of them can be dismissed. How this is done is a matter of experience. I know that places where the value is loaded and immediately dumped into memory aren't likely, I have an idea what graphical subroutines look like, and so on. I can't really say with 100% certainty that they're not what I'm looking for, but the chances seem slight enough that I can ignore them for now.

After a minute or so, the following pops up.

Code: Select all


TEXT:80093BA0                 jal     rand
TEXT:80093BA4 addiu $s1, $v0, 1
TEXT:80093BA8 sll $v1, $v0, 9
TEXT:80093BAC addu $v0, $v1, $v0
TEXT:80093BB0 bgez $v0, loc_80093BBC
TEXT:80093BB4 nop
TEXT:80093BB8 addiu $v0, 0x7FFF
TEXT:80093BBC
TEXT:80093BBC loc_80093BBC: # CODE XREF: sub_80093ADC+D4j
TEXT:80093BBC sra $v0, 15
TEXT:80093BC0 slt $v0, $s1
TEXT:80093BC4 beqz $v0, loc_80093C78
.......
TEXT:80093C0C li $a2, 0x40
TEXT:80093C10 jal sub_80074CFC
TEXT:80093C14 sw $v0, 0x1260($v1)
TEXT:80093C18
TEXT:80093C18 Has_ChampionRune:
TEXT:80093C18 beqz $v0, loc_80093C30
TEXT:80093C1C nop
TEXT:80093C20 jal sub_800BAA00
TEXT:80093C24 nop
TEXT:80093C28 bnez $v0, loc_80093C78
TEXT:80093C2C nop
TEXT:80093C30
TEXT:80093C30 loc_80093C30: # CODE XREF: sub_80093ADC:Has_ChampionRunej
TEXT:80093C30 lw $v0, 0x2C4($s0)
TEXT:80093C34 nop
I added the Has_ChampionRune label, so I could find this place later. I also cut out a fair bit of code, because it's not necessary to this explanation.

Here we have a call to the library rand() function, followed shortly thereafter by 0x40 being loaded on $a2 and then a call (JAL) to some subroutine. Most of the registers on the PSX's main processor are general-purpose, including $a0 - $a3, but some of them have special uses by convention. In the case of the $a registers, they're argument registers, as well as being available for general use. An argument is a value passed into a function to be operated with or on. Looking at the routine at 0x80074CFC, you can see it's multipurpose. Konami didn't do object-oriented or anything close to it at this point in time. If they needed functions to look at ten different arrays, they wrote a multipurpose one that takes a "type" as one of the arguments and then does a different search based on the type. Looking through the individual functions performed by the routine, there's one that loops through up to 6 "things", checking to see if part of their data is equal to what was passed on $a2. This looks like it could search the active party for a particular Rune.

Another register with a special purpose is $v0. It often holds a "return" value from a function. In the case of sub_80074CFC, it puts 1 on $v0 if it finds what it's looking for. That's pretty typical. 1 is "found"; 0 is "not found".

So glancing at the code, this looks like a pretty solid bet for being where the Champion Rune's effect is applied. We have a hypothesis, so let's try to falsify it. You can see immediately after the call, it skips over a section of code if $v0 (the return value) is zero. We can assume that if this is where the Champion Rune does its work, then if it's "found", the skipped code should be executed. Let's make it so that the Champion Rune is always found.

Test Code
80093C18 0001

What I've done here is modify the BEQZ operation at 0x80093C18. This address actually holds the value 0x10400005, which is a machine op-code. My disassembler shorthands it to "BEQZ $v0" and a label, but it's actually, "beq $v0, zero, +5", or, "jump down five operations if $v0 is equal to register zero (0)". The code above will make it jump down 1 operation instead, which essentially makes it like the branch isn't there. The theory is that that means the game will always check to see if the enemy can be "let go" and prevent the encounter, even if you're not wearing a Champion Rune.

To test it, wander around in an area where your party outclasses the enemies for a while, and see if you get into any encounters. I tested it in two spots for about five minutes each, and didn't run into anything except one party that I could only run from. The hypothesis seems sound. We can call this a cheat for producing the "Champion Rune Effect".

This success makes it pretty likely that we've found where random encounters are checked and set, so let's try to expand on this and make a "No Encounters" code.

Looking back at the game code, there are any number of ways this might be accomplished, but let's work from the cheat code we have. Right below that BEQZ that was modified, there's a call to a function. We know that the Champion Rune only works on enemies that can be "let go", so it's reasonable to guess that this function checks that (a brief look at its code makes that seem likely). Right below it is a BNEZ op that looks at $v0 again, and jumps to the exit of the subroutine if it's not zero. Seems like that function will return 1 (or at least non-zero) if the encounter can be avoided. BNEZ is another shorthand of my assembler. It's actually "bne $v0, zero, %whatever jump gets to the exit%". So let's change that so that it always jumps to the routines exit, instead of spawning an encounter.

Test Code 2
80093C18 0001
80093C2A 1000

We include the previous cheat, to trick it into thinking there's a Champion Rune on the party. Then we just have to make it look like the enemy can always be let go. The easy way to do that is to make it so that the branch operation's condition will always be true. So we change it to "beq zero, zero, %whatever%". The zero register is always zero and any register is always equal to itself. So that means the branch will always be taken, and the code between it and its target will never be executed. Note that in this case, the jump value is untouched by the cheat, so we don't even need to care what it is. We've just modified the requested operation, and its operands.

Testing this code, in an area where the enemies are more than twice my party's current level, I don't get into any encounters for about 5 minutes. It seems like we have a working code.

Lessened Encounters (Champion Rune Effect)
80093C18 0001

No Random Encounters
80093C18 0001
80093C2A 1000

The "No Random Encounters" code can actually be shortened to one line, or expanded with type D conditional cheat codes to make it activate and deactivate when different buttons are pressed. You can also make it so that the Champion Rune is a legitimate "No Encounters" item.
User avatar
BadPotato
Posts: 170
Joined: Mon Feb 09, 2009 10:07 am
Location: Canada - Québec

Re: Game Mechanics And Codes

Post by BadPotato »

Thanks for your explanation. Now, I'll try to get around with IDA 5.5(I'm don't know about how good is this version, but I'll see that later), so at least I can perform task like search the immediate value and all these other "investigation" tool :o

Ok, so I did some trial and error and searched for info on google, but I'm kinda confused about how to set up IDA.

First when I open IDA 5.5, I select go, then I drag and drop my ISO file. So far, I'm already unsure about this, since it's a CD that contain some file not related to MIPS. So I did some try with some random individual file, but then since I had no clue of what was going on in the folder aboresance, I just assumed that I should use the ISO.

Then, IDA ask me for what kind of CPU. After a quick search, I think the playstation use "MIPS & RSP big endian". I'm not too sure about it, so I just select "mipsr".

Anyway other than that, I just keep going in the default setting and and it ask me the "dissambly memory organization"... I try these setting that I saw on an another forum for a gba game. If can't load the whole iso on my "ram", I think it's just too big.

Then I'm stuck there, I tried to mess around in the view>open subview>segment, but I have no way to know if I'm in the right direction. Then I try to convert some data in instruction by pressing C at the top, but that doesn't seem right...

I've also did some search for a PSX/MIPS plugin and ended with a python plugin. I think there a special way to install it, so I just did nothing about it.

So far, my goal would be to simply been able to see the code that you keep posting on the wiki and on the previous page of this topic. But since I don't have a playstation and a cable to connect to the PC, I don't even know if at some point I'll reach a dead end to perform a "required" specific task.
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

IDA's an extremely handy tool. There are other disassemblers that work, but IDA is the Cadillac.

You don't disassemble the ISO. You disassemble the executable files within it. Every console game has a main executable, and the format of the file is determined by the system. On the PS2/PS3, they use a format called Executable and Linking Format (ELF), and on the PSX they used a proprietary format that I think was called PSX EXE (it's probably a mutation of something standard, like ELF, but I don't know for sure). IDA 5.5 should have an option for handling PSX EXE files, without you having to provide additional information like the processor architecture. I think it's under "Consoles". It only works for actual PSX EXEs. That will be important later.

The main CPU of the PSX is a MIPS R3000 processor, little-endian mode. New generations of MIPS processors (in the same series) typically extend the capabilities of previous versions. As such, IDA has only one option for this series of processors, so you'd want to select "MIPS R5900l". That last character is an "L". It represents the endian-ness of the architecture. R5900 is the core of the PS2, and its instruction set is a super-set of the R3000. That is, it contains all the R3000 instructions. The "endian-ness" of a system simply describes how it stores numerical data. Say you have a 16-bit value, 03E8. If you handle it little-endian, that means the lowest address contains the least significant byte of the value. So looking at it as individual bytes in memory, you'd find the E8, and then the 03 in the following byte, or E803. Big-endian is naturally the reverse. You'd find the 03 followed by the E8, 03E8. The reasons why these differences exist aren't worth getting into. You may have also noticed that endian-ness only matters for data larger than one byte. So things like one byte numbers and strings of ASCII characters will be found in the order you'd naturally expect.

Now, IDA will expect something with a .exe extension if you tell it you're loading a Playstation Executable file, but those almost never exist in games. The executable file is renamed according to the game's Sony Serial, which for the US version of Suikoden 2 is SLUS_009.58. That's the main executable on the disc. If in doubt, the executable loaded when the game boots can always be found in the SYSTEM.CNF file in the root directory of the disc.

Getting back to the PSX EXE option only working on actual executables: Suikoden 2, and a lot of the Suikoden games, rely on code overlay files. You can think of them as being sort of like DLL files, except they have to be loaded into a particular place in memory. Most the V<letter><number>.BIN files in the area directories are this type of file. They're not valid PSX EXEs, and can only be treated as binary files. You still specify MIPS 5900l, but you have to tell it how to load the file. I usually create a RAM segment, because we're not dealing with ROMs. Unfortunately, ROM is the default. With these overlay files, in order for the disassembly to be useful, you need to provide a loading address that will target some part of the RAM segment. For our purposes, that will always be the start of the RAM segment. In order to determine what that is, the easiest thing to do is hex edit the file. The first word should be a pointer to some control data. It'll have a value something like 0x801121B4 (B4211180 as you're looking at the file). If the value is less than 0x80150000 then the file will be loaded at 0x8010DC50, and that's your RAM start/load address. If it's more than 0x80150000, then it should be 0x8015DC50. Once one of these files loads, you have to tell IDA what's code, by selecting or placing the cursor on addresses and pressing "C". Doing that is kind of a matter of experience. You kind of have to know what the op codes look like, and what sequences of bytes are likely to be op codes. One easy thing to look for is instances of 0x27BD, which are usually operations modifying the stack pointer.

Note that if the file you're disassembling is in a recognized, executable format, most of this will be done for you. IDA will be able to distinguish code and data segments pretty well, and it even has FLIRT signatures for the PSX that will name most of the library functions for you (FLIRT is Fast LIbrary Recognition...something). Since it seems like you're just starting out, disassembling the SLUS file will be the easiest place to start.
User avatar
BadPotato
Posts: 170
Joined: Mon Feb 09, 2009 10:07 am
Location: Canada - Québec

Re: Game Mechanics And Codes

Post by BadPotato »

Alright, I managed to see the code the code of the rand fonction, thanks to your post... Now, if I try to get around with loading the V<letter><number>.BIN. I think I missed an important step, how do you actually add an ram segment from another file in IDA?

I looked at VA01.BIN(first bin file for the first folder) and the first word is 0x80113C28, since it's lower than 0x80150000, the loading address for this file is 0x8010DC50 ?

Now, once I have the "main executable" open with R5900l and the default setting(it doesn't even ask me for the disassembly memory management), if go in "View>Open subview>segements" and I right click for adding a segment it won't ask me a folder, ok.. it sound like I should try to load the file by some other way. I try "file>load file>addional binary file". Then I select VA01.BIN, I these setting. This create some unrecognized raw data at beginning of the top bar, wich seem to be somekind of loaded rom data info.

After this if I try to return in "View>Open subview>segements"... but it just doesn't seem to work well. I think I didn't do something right with these ram segment.
Pyriel wrote:Once one of these files loads, you have to tell IDA what's code, by selecting or placing the cursor on addresses and pressing "C". Doing that is kind of a matter of experience. You kind of have to know what the op codes look like, and what sequences of bytes are likely to be op codes. One easy thing to look for is instances of 0x27BD, which are usually operations modifying the stack pointer.
This part seem horrible to get around, I don't know if I can get that far, since there doesn't seem to be an "undo" button once you pressed C at some point in the whole file. Could you post an "instances of 0x27BD" example in disassembly, once I'm at that part? This might be easier for getting some idea about it work.
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

I don't usually load the files in like that, but that's just me. I'm fine with navigating separate disassemblies, and I just use comments to keep track of things between different files. That's just my personal preference, though, and it mainly grew out of not being able to merge the disassemblies in other tools I've used.

If you're going to do it that way, I'd suggest setting the segment to zero, and using the "Loading Offset" setting to load the data in a particular spot in your RAM segment. If you disassemble the EXE/SLUS file first, it should create the entire 2 MB of main RAM to load the executable into it, so 0x8010DC50 and so on will just exist as initialized space. You should also clear the two check-boxes at the bottom. Otherwise, IDA may do you a "favor" and create a new segment at the bottom of your file, with an adjusted segment address.

Yeah, marking things as code can get a little tedious, if you're doing it all manually. Look at the edit menu for the different definitions available. The "C" key is tied to the "Code" define, and you can use "D" (Data) and "U" (Undefine) frequently as well. If you mistakenly identify something as code, you can just highlight all the code it created and undefine it to fix the problem. If you define something as "Data" with this architecture, it first becomes a ".byte", which mainly removes any character interpretation offered, and then becomes larger, if the address is appropriate. The second press will create a ".half" (16-bit/2-byte variable), provided the address is even (0,2,4,6,8,A,C,E), i.e. "halfword-aligned", and the third press will create a ".word" provided the address is word-aligned (0,4,8,C). Alignment is an important concept in this architecture. Some processors don't care, but this MIPS series does. One reason is that it makes the operations more efficient than allowing unaligned memory reads would.

With the 0x27BD, this is what you're looking for in a nutshell.

Code: Select all


RAM:8010DCEC                 .byte 0x90  # É
RAM:8010DCED .byte 0xFF
RAM:8010DCEE .byte 0xBD # +
RAM:8010DCEF .byte 0x27 # '
Here is defined as a ".word".

Code: Select all


RAM:8010DCEC                 .word 0x27BDFF90
Here are the first few instructions that result, after I tell IDA this is code.

Code: Select all


RAM:8010DCEC                 addiu   $sp, -0x70
RAM:8010DCF0 sw $s2, 0x50($sp)
RAM:8010DCF4 move $s2, $a0
I usually just do a binary search for "BD 27". This is the uppermost half of any stack-pointer add, and those instructions occur frequently at the beginning and ending of subroutines. Instructions are always word-aligned, so what you'll want to find is a 27BD on a halfword-aligned address, that isn't also word-aligned (2,6,A,E). Preceding it will be an immediate value that is added to the stack pointer. In the case above, it's 0xFF90 (-70). At the beginning of subroutines, the stack pointer is decremented, and at the end, it is incremented by the opposite amount (restored), so I'd expect to find 0x27BD0070 somewhere further along. I don't usually look for it though. If it looks this much like an "addiu sp, sp, %number%", it most likely is.

This is just my own quick and dirty method for identifying most of the code in a file. All of it is typically clustered together, so I'll just start from the earliest occurrence, select the line, and then click the lowest line in the search results I want to chance (sometimes it's the last result, sometimes there's too big a gap between results to risk it). Then I just hit "C" and force the code conversion when prompted. Most times, this shortcut gets me 90%-100% of the code in a binary file I've loaded, without my having to analyze every little bit of the data.

Here's an example binary search (Alt+B) for VA01.BIN:
Image

I'd be comfortable selecting all of this, and marking it code. If you load this into the same disassembly as the EXE, you'll just have start from where you loaded it, because the search will find every occurrence in the EXE as well. Those occurrences should already be defined as code, and will show up as "addiu sp, sp" instructions in the search results, though.
User avatar
BadPotato
Posts: 170
Joined: Mon Feb 09, 2009 10:07 am
Location: Canada - Québec

Re: Game Mechanics And Codes

Post by BadPotato »

Just a quick question, I played a bit with your explanation from your post about the champion rune/no encounter and I managed to understand that you can directly hexedit the address 0x80093C18 and IDA will update right away disassembly code, wow... Thought, I'm still confused how about this:
Pyriel wrote:So, since the ID is a small amount of data, immediate values seems a good place to start.

This search returns about 600 results. That's a lot, but I can pare it down further. I'm only interested in operations that place the value 0x40 on a register, so I can exclude places where 0x40 is the index in a load operation, where the zero register is not the first operand, AND operations, Set Less Than operations, etc. Note that the "zero" register is special-purpose. It's hardwired to be zero at all times, so it fills in when you need to compare to zero, or when you just need one of the operands to be zero. It cannot be modified, and any attempt to do so is an illegal operation.

After narrowing it down, I'm left with less than 50 operations to look at.
Basically, how can you add these kind of additional "complexes" argument for searching in IDA? I guess that having a well commented disassembly help, but for around 600 result there certainly a better way to search.

Now about loading VA01.BIN in 0x8010DC50 after letting the SLUS been disassembled.. I tried several workaround that I didn't work very well, but I managed to get it work this way: First drag the SLUS, then set 5900l. After, since there doesn't seem to be anything in the 0x80109800-0x80200000 ram segment, I just deleted it. Thought, I think, this isn't enough to complete remove it. So I had to close IDA, save the database and restart while restoring the latest work. Then in file additional binary, I left "loading segment at 0" and I used 0x8016DC50 for the offset. Before pressing OK, I tried mark the "Create segment" as checked and I let "code segment" unchecked. After confirming this, IDA created the segment at the right place with the right size, my last step was to edit the segment name to "RAM", select 32 bit segment and uncheck "move adjacent segments", like this.

Now I'm unsure if this is a normal result, but the sequence with 0x27BD along with the 0xFF90 part doesn't to appear in my first result of binary search... but after pressing on C every 2 line before 0x27BD I managed to get this(pastebin). There I don't know if this look wrong so far, but when I right-clik I can't switch to "Graph view", so I guess that maybe I should work with separate instance of IDA, just like you said.
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

Well, what you've got there for code in VA01 looks right, so far.

Filtering the search results is a matter of preference. You can do text searches with regular expressions, but they're slow. Any of the numeric searches, like binary and immediate, are much, much faster. All I did to filter down the 600 results was sort the results list by instruction, and only look at the instruction types that I thought had a shot at being what I wanted. Basically, I just sorted it, and scrolled right to the "li" section for a start. If I hadn't found it that way, I'd have moved on to another instruction type.

There's always going to be a lot of data to sift through. How narrow you make your searches is case-by-case, and a matter of personal preference. Earlier versions of IDA didn't allow you to sort results on different columns, so I used the text/regex search a lot back then. The data's formatted consistently, so regular expressions are fairly easy to write. This was when I was doing a lot of PS2 hacking too. With the much larger files, the regex searches took forever, but I could walk away and come back to 80 possibilities instead of 4,000.

Oh yeah, here's the Instruction Set Reference for the PS2. The PSX is just a subset of this, so only use it as a reference for what an op is in a disassembly. If you try to write assembly code, you won't be able to use about 50% of the op codes in this guide, so it's not a perfect reference for generating new code. Most of the time, I don't need to use anything but the instructions that exist for both processors anyway, but I do miss the "branch likely" instructions from time to time.
User avatar
Pesmerga VS. Yuber
Posts: 330
Joined: Mon Jan 16, 2006 3:38 pm

Re: Game Mechanics And Codes

Post by Pesmerga VS. Yuber »

Question: Is it possible to make Riou walk diagonally like they did in the PSP version?
Power?
Am I looking for Power?
Ever since...The first day I saw you...
I somehow knew...That we would be friends.
I was never lonely...Because you were there.
We chose...Life and death together.
I believed in you...Always...
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

Possible? Maybe. Easy? Probably not.
kuroi_shinigami
Posts: 8
Joined: Sun Apr 25, 2010 7:19 am

Re: Game Mechanics And Codes

Post by kuroi_shinigami »

Pyriel wrote:Enemies Always Drop (Random)
D002E124 F809
8002E12C 0012
D002E124 F809
8002E12E 93A4
D002E124 F809
8002E130 0002
D002E124 F809
8002E132 1080
D002E124 F809
8002E134 0001
D002E124 F809
8002E136 2403
D002E124 F809
8002E138 1821
D002E124 F809
8002E13A 0004
D002E124 F809
8002E13C 001B
D002E124 F809
8002E13E 0043
D002E124 F809
8002E148 1810
D002E124 F809
8002E14A 0000

Enemies will always drop a random item from their drop table. The chances are still relative to the rarity of their individual drops. Using my hypothetical example above, you'd now have about a 16% chance of the antitoxin dropping, 16% for the Mega Medicine, and a 68% chance of getting the medicine.

I had partially written a code to enable you to change the drop number with button presses, but due to the limitations of most PS1 devices, it's just impractical to enter. Once I realized it was going to be about 60 lines long, I just stopped, and let it die.

I also wrote a code to change critical hit chances. The problem I've discovered is that the game has multiple logic paths for damage, and it seems like it follows a completely different one after the first round. Not sure what that's about yet.
Edit : NVM, I found out that in game battle code is different for Japanese version and US version of the game although the out of battle code is the same.
oops
Posts: 197
Joined: Fri Jul 02, 2004 10:35 pm

Re: Game Mechanics And Codes

Post by oops »

Pyriel, you mentioned something about changing the value of the enemy's hp in another thread but I can't find it. I'm looking to make the game harder and perhaps multiplying the value a few times would make things much harder. Any ideas?
leiaruchiha
Posts: 2
Joined: Wed Oct 03, 2012 9:41 am

Re: Game Mechanics And Codes

Post by leiaruchiha »

Pyriel wrote:I did this in response to a request from suiko2fan2, and thought it was pretty cool.

Image
The Fire Rune has been upgraded a touch.

Image
Note that only the Hero is casting the spell.

The actual request was to edit the White Fang rune or some similar rune and turn into a Beast Rune. I'm still not sure if that's possible, but there are a bunch of skills with mangled names in the data. I think they'll all turn out to be effects mappings for the Alert Rune and such, but maybe not. The Champion Rune is pretty much just a flag that gets searched for in the encounter routines, and likewise for the Prosperity and Fortune Runes. Perhaps enough of them are of the hard-coded sort, and the Beast Rune skills will have enough availability to make this feasible.

sir Pyriel, how did u do this??

EDIT: plss share if this can do in gameshark codes.. plss
User avatar
Pyriel
Webmaster
Posts: 1229
Joined: Wed Aug 18, 2004 1:20 pm

Re: Game Mechanics And Codes

Post by Pyriel »

It's possible with the GameShark, but much simpler and stabler if you edit the files. The way the game manages the data, it's liable to crash if you used a code for this and disabled or enabled it at the wrong time.

Regarding a HP multiplier, it's possible. It's hard to say how easily it could be done, though. I'm reasonably certain that the battle modules or the main executable will handle loading Enemy instances from the base data, but there's still a real chance that each area module is responsible for it, and does it somewhat differently. I'd have to look into it more. A "hard-mode" patch is something I've considered, so something like that may happen.
Post Reply