Author Topic: Do characters have something similar to a WalkToPoint?  (Read 368 times)

artium

    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with story design
    •  
If a WalkToPoint of a hot-spot is set, every interaction with that hot-spot will automatically make the player walk to that point.

I do not see similar property for characters. Interacting with characters will make the interaction immidiate, without walking the player first to face the character.

It is of course possible to add some code:

Code: Adventure Game Studio
  1. function cNPC_Look()
  2. {
  3.   // Walking and orientation boilerplate
  4.   cPlayer.Walk(cNPC.x, cNPC.y + 15, eBlock, eWalkableAreas);
  5.   cPlayer.FaceCharacter(cNPC);
  6.   cNPC.FaceCharacter(cPlayer);
  7.  
  8.   // What I actually want to happen
  9.   cPlayer.Say("I have no idea who is this");
  10. }
  11.  

This approach has problems:
  • Every interaction (look, talk, interact etc) type of every character needs to have this boilerplate code.
  • The "15" magic number needs to be separate for each character and updated after every change to the position of the character.
  • If a mistake is made, there is no way to catch it before testing. Even indirect changes can have effect. For example a walk area can be reduced to exclude this point.
  • If the character can move during the game, it requires "15" to be calculated dynamically (how?)

Is there a better way doing the same thing?

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: Do characters have something similar to a WalkToPoint?
« Reply #1 on: 16 Dec 2017, 10:31 »
1. Every interaction (look, talk, interact etc) type of every character needs to have this boilerplate code.

You can make it a function and reduce the boilerplate to one line:

Code: Adventure Game Studio
  1. void ApproachCharacter(this Character*, Character* npc, int xOffset, int yOffset)
  2. {
  3.   this.Walk(npc.x + xOffset, npc.y + yOffset, eBlock, eWalkableAreas);
  4.   this.FaceCharacter(npc);
  5.   npc.FaceCharacter(this);
  6. }

Now you can call it like so:

Code: Adventure Game Studio
  1. function cNPC_Look()
  2. {
  3.   cPlayer.ApproachCharacter(cNPC, 0, 15);
  4.   cPlayer.Say("I have no idea who is this");
  5. }

If that's still too much work, you can write some helper functions, e.g. for Say():

Code: Adventure Game Studio
  1. void SayToCharacter(this Character*, Character* npc, int xOffset, int yOffset, String message);
  2. {
  3.   this.ApproachCharacter(npc, xOffset, yOffset);
  4.   this.Say(message);
  5. }

And now the whole function is a one-liner again:

Code: Adventure Game Studio
  1. function cNPC_Look()
  2. {
  3.   cPlayer.SayToCharacter(cNPC, 0, 15, "I have no idea who is this");
  4. }

2. The "15" magic number needs to be separate for each character and updated after every change to the position of the character.

Does the "magic number" depend on the character (e.g. with cAlice you should always be 10 pixels away), on where they are on the screen (e.g. if you're talking to a character who's behind the desk, you should always stand in a certain position), or both? Does it need to change depending on the character scaling? Do your characters stand in one of a number of pre-defined locations, or do they wander about anywhere on the walkable area?

If it just depends on their position on the screen (from some limited list of possible positions), you should define a lookup table from each position to the corresponding WalkTo point. If characters can be anywhere on the screen, with different WalkTo behavior in different parts of the screen, you might need to define regions, and a lookup table from each region to its WalkTo point/offset. If it just depends on the Character, you should make a custom property. If it depends on both, you need to do both, and define the formula to calculate the combined value. If it depends on scaling, you need to include that in the calculation.

3. If a mistake is made, there is no way to catch it before testing. Even indirect changes can have effect. For example a walk area can be reduced to exclude this point.

If a WalkTo point falls outside a walkable area, the character should walk to the closest point it can reach. If that's not acceptable, what is it that you want to happen?

4. If the character can move during the game, it requires "15" to be calculated dynamically (how?)

See above.
« Last Edit: 16 Dec 2017, 10:35 by Snarky »

artium

    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with story design
    •  
Re: Do characters have something similar to a WalkToPoint?
« Reply #2 on: 16 Dec 2017, 14:05 »
Thanks, "SayToCharacter" function does makes it more simple.

Quote
Does the "magic number" depend on the character (e.g. with cAlice you should always be 10 pixels away), on where they are on the screen (e.g. if you're talking to a character who's behind the desk, you should always stand in a certain position), or both? Does it need to change depending on the character scaling? Do your characters stand in one of a number of pre-defined locations, or do they wander about anywhere on the walkable area?

This question is not for a specific game, I just experiment with AGS and try to see what is possbile, so it can depend on any of the things you listed.

I just thought about additional problem. If the player character is already near the NPC character, but the offset makes it walk to a different position, the player will walk to it instead speaking to the NPC from the current position.

Quote
If characters can be anywhere on the screen, with different WalkTo behavior in different parts of the screen, you might need to define regions, and a lookup table from each region to its WalkTo point/offset.

This part I do not understand.


Quote
If a WalkTo point falls outside a walkable area, the character should walk to the closest point it can reach. If that's not acceptable, what is it that you want to happen?

Great! Did not know about this.

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: Do characters have something similar to a WalkToPoint?
« Reply #3 on: 16 Dec 2017, 14:29 »
This question is not for a specific game, I just experiment with AGS and try to see what is possbile, so it can depend on any of the things you listed.

And that's why it's not built in to AGS: Unlike hotspots, which are stationary and easy to deal with, there's no one standard behavior that is right for characters. It depends, and you have to decide what you want to happen before we can figure out how to make that happen.

I just thought about additional problem. If the player character is already near the NPC character, but the offset makes it walk to a different position, the player will walk to it instead speaking to the NPC from the current position.

So put a test for that in ApproachCharacter().

Quote
If characters can be anywhere on the screen, with different WalkTo behavior in different parts of the screen, you might need to define regions, and a lookup table from each region to its WalkTo point/offset.

This part I do not understand.

OK, imagine that there's a game where you're a prisoner in a prison. There's a room with other characters (prisoners and guards) walking around dynamically. You want to have a rule like:

-If you try to talk to a prisoner or guard who's in the main hall, you just walk up to them.
-If you try to talk to a a guard who's on the catwalk above (where you can't go), you walk to a point beneath them to the side.
-If you try to talk to a prisoner who's in one of the locked cells, you walk to the nearest ventilation duct.

(All of this is in one big, scrolling background.)

One way to do this would be to define different regions on the background. The hall would be one region, the catwalk another region, the cells a third region. When you try to talk to a character, the game checks what region they're in, and looks up the x and y offset for that region in the lookup table. E.g. for the hallway that could just be x+10 (you stand next to them). For the catwalk it might be y+150, x-20 (you stand below them to the side). For the locked cells it might be x-40 (you stand by the ventilation duct outside the cell).

In extreme situations such as this you might want to use different logic/calculations for each case, not just different values, but hopefully you see the point.

artium

    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with story design
    •  
Re: Do characters have something similar to a WalkToPoint?
« Reply #4 on: 16 Dec 2017, 20:04 »
Ok, now I understand what you meant regarding the regions.

I have one more question.

The "ApproachCharacter" function now looks like that:

Quote
function ApproachCharacter(this Character*,
                           Character*    npc,
                           int           offsetX,
                           int           offsetY
                           /*BlockingStyle blockingStyle, 
                           WalkWhere     walkWhere*/)
{
  int trueOffsetX = 0;
  int trueOffsetY = 0;
 
  // Facing npc allows calculating direction of approach
  this.FaceCharacter(npc);
 
  switch (this.Loop) {
   
    case eDirectionUp:
      trueOffsetY = offsetY;
      break;
    case eDirectionDown:
      trueOffsetY = (-1) * offsetY;
      break;
    case eDirectionRight:
      trueOffsetX = (-1) * offsetX;
      break;
    default:
      // fall through to eDirectionLeft
    case eDirectionLeft:
      trueOffsetX = offsetX;
      break;
  }
 
  this.Walk(npc.x + trueOffsetX, npc.y + trueOffsetY, eBlock, eWalkableAreas);
 
  this.FaceCharacter(npc);
  npc.FaceCharacter(this);
}

It is working fine as is, but I want to change it a little. I want to be able to interrupt the walking sequence and move the character to a different location.

For this to be possible, this.Walk should be non-blocking.

My question is, how do I determine that the player finished walking and reached it's destination so that a dialog can start?

I had an idea that it is possible to busy-wait for the "Moving" property of the player to become false, but how do I know that it became false due to the player reaching it's destination and not because the walking was interrupted?

Snarky

  • Global Moderator
  • Mittens Earl
  • Private Insultant
    • I can help with proof reading
    •  
    • I can help with translating
    •  
Re: Do characters have something similar to a WalkToPoint?
« Reply #5 on: 16 Dec 2017, 22:31 »
I'm not sure how to do those kinds of walks off the top of my head, but I know it's part of the Tumbleweed Verbs template (see "Semi-blocking movement functions").