Users browsing this thread: 1 Guest(s)
NPC actions
01-16-2012, 07:21 PM
So I have one or two question regarding an NPC "automatic" action. In FF6LE there are 16 possible action that can be used on an NPC. A lot seems to do nothing and the most commonly used is action 3, which makes the NPC walk pseudo-randomly. I don't know what each of the 16 is suppose to do.
So how could I make action for a npc that would follow a pattern or act in a random way? If I do them thru events I could maybe make one infinite loop with a pattern of actions for a NPC and enable the movement of the party while the event is executed. However the game would read the same portion of code over and over so I wouldn't be able to assign other actions to other NPCs or simply continue the event.
The second option would be to edit some of the action numbers. Those actions must be executed when the npc data is read when a map is loaded. I found where the data is read:
This is part of the map loading subroutine and at C0/52A8, it seems each byte of each NPC data are read and the function loop as long as there is NPC to be loaded. Byte 8 of the NPC data hold the movement of the NPC if I'm right and it seems it would be loaded here:
This is where I'm stuck. I don't know where the NPC action is loaded/executed. There should be a subroutine with 15 branchings depending on which action has the NPC or 16 small subroutine, so one for each action. If I could find them I could study them and eventually modify them.
Let's just think of scenarios where I would have a panic event where everyone is running in a different direction or a drunken guy that would do a pseudo random moving pattern while jumping once in a while but those movements would be executed as long as the party is on the map.
So is there an assembly god or a event master to help me solve this issue? Plus, custom NPC moves would be a neat addition for any event creator...
So how could I make action for a npc that would follow a pattern or act in a random way? If I do them thru events I could maybe make one infinite loop with a pattern of actions for a NPC and enable the movement of the party while the event is executed. However the game would read the same portion of code over and over so I wouldn't be able to assign other actions to other NPCs or simply continue the event.
The second option would be to edit some of the action numbers. Those actions must be executed when the npc data is read when a map is loaded. I found where the data is read:
Code:
C0/BFB8: 20A852 JSR $52A8 (Load NPC data)
This is part of the map loading subroutine and at C0/52A8, it seems each byte of each NPC data are read and the function loop as long as there is NPC to be loaded. Byte 8 of the NPC data hold the movement of the NPC if I'm right and it seems it would be loaded here:
Code:
C0/5373: BF171AC4 LDA $C41A17,X (Load byte 8/Graph. action of the NPC data ?)
C0/5377: 290F AND #$0F
C0/5379: 197C08 ORA $087C,Y
C0/537C: 997C08 STA $087C,Y
C0/537F: BF171AC4 LDA $C41A17,X
C0/5383: 2930 AND #$30
C0/5385: 0A ASL A
C0/5386: 0A ASL A
C0/5387: 998C08 STA $088C,Y
C0/538A: BF171AC4 LDA $C41A17,X
C0/538E: 29C0 AND #$C0
C0/5390: 4A LSR A
C0/5391: 196808 ORA $0868,Y
C0/5394: 996808 STA $0868,Y
This is where I'm stuck. I don't know where the NPC action is loaded/executed. There should be a subroutine with 15 branchings depending on which action has the NPC or 16 small subroutine, so one for each action. If I could find them I could study them and eventually modify them.
Let's just think of scenarios where I would have a panic event where everyone is running in a different direction or a drunken guy that would do a pseudo random moving pattern while jumping once in a while but those movements would be executed as long as the party is on the map.
So is there an assembly god or a event master to help me solve this issue? Plus, custom NPC moves would be a neat addition for any event creator...
02-12-2012, 04:36 PM
It seems the byte contains three parts of information:
00001111 bits 1-4 ?? (joined with another value)
00110000 bits 5-6 ?? (written as 40, 80 or C0)
11000000 bits 7-8 ?? (joined with another value; written as 20, 40 or 60)
The first part seems to be the one you are looking for based on FF6LE providing 16 possibilities available.
Then you need to find where in the main loop "LDA $087C,Y" happens (with Y at the same value as in this code snippet). That will reveal what happens to the 4 bit value.
00001111 bits 1-4 ?? (joined with another value)
00110000 bits 5-6 ?? (written as 40, 80 or C0)
11000000 bits 7-8 ?? (joined with another value; written as 20, 40 or 60)
Code:
C0/5373: BF171AC4 LDA $C41A17,X (Load byte 8/Graph. action of the NPC data ?)
C0/5377: 290F AND #$0F mask leaving 4 bits (01, 02, 04 and 08)
C0/5379: 197C08 ORA $087C,Y join with $087C
C0/537C: 997C08 STA $087C,Y written to $087C
C0/537F: BF171AC4 LDA $C41A17,X
C0/5383: 2930 AND #$30 mask leaving 2 bits (10 and 20)
C0/5385: 0A ASL A
C0/5386: 0A ASL A shift << by 2 bits
C0/5387: 998C08 STA $088C,Y written to $0868
C0/538A: BF171AC4 LDA $C41A17,X
C0/538E: 29C0 AND #$C0 mask leaving bit 7 and 8 (40 and 80)
C0/5390: 4A LSR A shift >> by 1 bit
C0/5391: 196808 ORA $0868,Y joined with $0868
C0/5394: 996808 STA $0868,Y written to $0868
The first part seems to be the one you are looking for based on FF6LE providing 16 possibilities available.
Then you need to find where in the main loop "LDA $087C,Y" happens (with Y at the same value as in this code snippet). That will reveal what happens to the 4 bit value.
02-12-2012, 05:04 PM
(02-12-2012, 04:36 PM)m06 Wrote: The first part seems to be the one you are looking for based on FF6LE providing 16 possibilities available.
Then you need to find where in the main loop "LDA $087C,Y" happens (with Y at the same value as in this code snippet). That will reveal what happens to the 4 bit value.
Well this is what I call unexpected help! I almost gave up all hope so I neglected that project but to be honest I didn't thought of your solution. The value at $087C, Y is loaded in many instance in bank C0 and with a really quick look I couldn't find the right spot. I could probably find the solution by using a debugger and setting up a break point at a NPC data (C41A17,X) and see like where action 3 (moving pseudo randomly) leads too. I'll try that when I have more free time.
You have a good understanding of assembly! Thanks again!
02-14-2012, 11:58 AM
Well thank you for an interesting find.
I liked the idea of having better control of the NPC's so I dived a bit deeper into the C0 bank and entity related routines. I made a RAM map I believe for the loaded entities. It's not complete and might be faulty but it's a fair reference atm.
Let me know if you figure out more detailed information about these bytes.
I also noticed a couple of routines you should check out:
First of all I found some branching for $087C at C0/763A:
This happens at the end of a routine that loops for all loaded entities. I'm guessing it's a general update loop to animate entities.
Sadly this chunk only checks for 4 actions so I'm guessing the other values or bits are used at other places, although I did not spot much of notice.
But check out the branches and jumps, a lot of stuff done to the entities.
Let me know what you find
I liked the idea of having better control of the NPC's so I dived a bit deeper into the C0 bank and entity related routines. I made a RAM map I believe for the loaded entities. It's not complete and might be faulty but it's a fair reference atm.
Code:
$0803 First entity? (the player character)
# The following are relative values for each loaded entity
$0867 0xC0 for NPC (party char?? used with setup of current parties.
Checked against active party and set to party setup)
$0868 Entity info:
bit 0: Set entity to walk when moving
bit 1-3: Layering priorities
bit 5-6: Chocobo / Magitek / Raft
bit 7: ?? horizontal position bit 7 (used: CO/525A)
$0869 Horizontal position low bit counter?
0 on change map position (TDC)
counter uses $0871 as incrementor
$086A Horizontal position low bit
$086B Horizontal position high bit
$086C Vertical position low bit counter?
0 on change map position (TDC)
counter uses $0873 as incrementor
$086D Vertical position low bit
$086E Vertical position high bit
$086F Data at $C059AD,X with X=$0887,Y aka. NPC Action (jump) used with $7F?
Perhaps sprite pointer for jump action?
$0870 set to 0 (unused)
$0871 horizontal speed for $0869
$0872 horizontal speed high byte? (set to 0 but unused)
$0873 vertical speed for $086C
$0874 vertical speed high byte? (set to 0 but unused)
$0875 Pointer offset to data
(offset from: C07ECA, C07ED4, C07EF4, C07F14 and C07F34
data starts at: C0/7ED7)
bits 0-1: ?? Vertical bits 6-7
$0876 Pointer offset for direction
(offset from: C0CD3A, C0CDBA, C05B5B,
data starts at: C0CD3A)
$0877 Pointer offset for direction (current sprite frame?
for directions values: F9, 04, 47, 01 )
$0878 Sprite set
$0879 Character data index
$087A ?? related to horizontal position (calculated from $086A)
$087B ?? related to vertical position (calculated from $086D)
$087C Mystery byte.
bit 0: Entity is playable? (low bits are cleared and this one set for "Assign Properties to character"
bit 0-3: Graphic Index / Movement action?
bit 4: ?? Set in C0/547E
bit 5: ?? Checked a number of times (C0/54D0, C0/6606 ...)
bit 6: Does not turn to face character when spoken to.
bit 7: NPC byte 2 bit 5 (??)
$087D ?? copy of mystery byte $087C
$087E ?? loaded with $B3 (C0/4F0A)
$087F Direction facing (0-3)
$0880 Palette index
$0881 Palette index
$0882 ?? some counter for NPC action 1, on 0 goto C0/76F8
$0883 ?? queue related counter
$0884 ?? counter?
$0885 ?? loaded from $E7 (C0/9BD5)
$0886 ?? counter?
$0887 Entity action
bit 3: jump
bits 4-6: jump height?
$0888 ?? counter?
$0889 NPC Event address low byte
$088A NPC Event address mid byte
$088B NPC Event address high byte
$088C ?? Layering
bits 0-5 ??
bits 6-7 Walk on top / behind character
$088D Character data $1F81 and/or $1F64
$088E ?? High byte for $088D?
$088F ?? X index for data at C0/5B5B
Let me know if you figure out more detailed information about these bytes.
I also noticed a couple of routines you should check out:
First of all I found some branching for $087C at C0/763A:
Code:
C0/763A: B97C08 LDA $087C,Y end: Load the NPC random walk bits and branch accordingly?
C0/763D: 290F AND #$0F
C0/763F: 3A DEC A
C0/7640: D003 BNE $7645
C0/7642: 4CE976 JMP $76E9 If A was 1 : Action 1
C0/7645: 3A DEC A
C0/7646: D003 BNE $764B
C0/7648: 4CDE76 JMP $76DE If A was 2 : Action 2
C0/764B: 3A DEC A
C0/764C: F014 BEQ $7662 If A was 3 : Action 3
C0/764E: 3A DEC A
C0/764F: F016 BEQ $7667 If A was 4 : Action 4
C0/7651: CC0308 CPY $0803
C0/7654: F011 BEQ $7667 If NPC is $0803 (player) : Action 4
This happens at the end of a routine that loops for all loaded entities. I'm guessing it's a general update loop to animate entities.
Sadly this chunk only checks for 4 actions so I'm guessing the other values or bits are used at other places, although I did not spot much of notice.
But check out the branches and jumps, a lot of stuff done to the entities.
Let me know what you find
After asking a reliable source, there is not 16 functioning npc actions and it remains unsure if there is 16 to start with, although FF6LE let you choose between 16. The npc data can produce randomness but not defined patterns unless you do heavy modification to the code.
However patterns can be done by setting one loop per npc action queue with the action command FC like in the following example. The npc action queue must be placed in the entrance event of the map.
Those are the action queues for the three soldiers in the Albrook pub after the opera segment and prior to the esper attack on Vector.
However patterns can be done by setting one loop per npc action queue with the action command FC like in the following example. The npc action queue must be placed in the entrance event of the map.
Code:
CC/5E72: 12 Begin action queue for character $12 (NPC $12), 9 bytes long
CC/5E74: 4A Do vehicle/entity graphical action $0A, flipped horizontally
CC/5E75: E0 Pause for 4 * 8 (32) frames
CC/5E77: 4B Do vehicle/entity graphical action $0B, flipped horizontally
CC/5E78: E0 Pause for 4 * 8 (32) frames
CC/5E7A: FC Branch 6 bytes backwards ($CC5E74)
CC/5E7C: FF End queue
CC/5E7D: 13 Begin action queue for character $13 (NPC $13), 9 bytes long
CC/5E7F: 0E Do vehicle/entity graphical action $0E
CC/5E80: E0 Pause for 4 * 4 (16) frames
CC/5E82: CF Turn vehicle/entity left
CC/5E83: E0 Pause for 4 * 8 (32) frames
CC/5E85: FC Branch 6 bytes backwards ($CC5E7F)
CC/5E87: FF End queue
CC/5E88: 14 Begin action queue for character $14 (NPC $14), 9 bytes long
CC/5E8A: 50 Do vehicle/entity graphical action $10, flipped horizontally
CC/5E8B: E0 Pause for 4 * 8 (32) frames
CC/5E8D: 51 Do vehicle/entity graphical action $11, flipped horizontally
CC/5E8E: E0 Pause for 4 * 8 (32) frames
CC/5E90: FC Branch 6 bytes backwards ($CC5E8A)
CC/5E92: FF End queue
Those are the action queues for the three soldiers in the Albrook pub after the opera segment and prior to the esper attack on Vector.
04-02-2012, 09:13 AM
I had a small find relative to this case, haven't seen this documented anywhere:
How to change the speed of NPC's
The two highest bits of the Y coordinate byte of NPC's in the NPC Data define the speed of the NPC.
So the structure of the Y coordinate byte (in bits) is:
SSYYYYYY
* S: Speed * Y: Y coordinate
0x00 Slow
0x40 Medium
0x80 Fast
0xC0 Very fast (rapid)
So Y can have a value of 0x00 - 0x3F with 0x40 - 0x7F being the same y coordinates with a higher speed respectively.
Check it out!
How to change the speed of NPC's
The two highest bits of the Y coordinate byte of NPC's in the NPC Data define the speed of the NPC.
So the structure of the Y coordinate byte (in bits) is:
SSYYYYYY
* S: Speed * Y: Y coordinate
0x00 Slow
0x40 Medium
0x80 Fast
0xC0 Very fast (rapid)
So Y can have a value of 0x00 - 0x3F with 0x40 - 0x7F being the same y coordinates with a higher speed respectively.
Check it out!
« Next Oldest | Next Newest »
Users browsing this thread: 1 Guest(s)