Users browsing this thread: 1 Guest(s)
NPC actions

#1
Posts: 3,970
Threads: 279
Thanks Received: 236
Thanks Given: 58
Joined: Oct 2011
Reputation: 65
Status
Tissue-aware
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:

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...
  Find
Quote  

#2
Posts: 127
Threads: 8
Thanks Received: 21
Thanks Given: 12
Joined: Jan 2012
Reputation: 13
Status
None
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)

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.
  Find
Quote  

#3
Posts: 3,970
Threads: 279
Thanks Received: 236
Thanks Given: 58
Joined: Oct 2011
Reputation: 65
Status
Tissue-aware
(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!



  Find
Quote  

#4
Posts: 127
Threads: 8
Thanks Received: 21
Thanks Given: 12
Joined: Jan 2012
Reputation: 13
Status
None
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.

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 Smile
  Find
Quote  

#5
Posts: 3,970
Threads: 279
Thanks Received: 236
Thanks Given: 58
Joined: Oct 2011
Reputation: 65
Status
Tissue-aware
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.

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.
  Find
Quote  

#6
Posts: 127
Threads: 8
Thanks Received: 21
Thanks Given: 12
Joined: Jan 2012
Reputation: 13
Status
None
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!
  Find
Quote  



Forum Jump:

Users browsing this thread: 1 Guest(s)


Theme by Madsiur2017Custom Graphics by JamesWhite