NPC location data

Make games! Discuss those games here.

Moderators: Bob the Hamster, marionline, SDHawk

User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

NPC location data

Post by Willy Elektrix »

I would like to make my game so that it when the player saves their game from the ESC key menu, the NPCs retain their current position on the map when the game is reloaded.

However, if the player leaves the map and comes back, I want the NPCs to reset into their start positions. Where do I even start with this? My experience with plotscripting is limited to about a dozen basic commands.

Any suggestions as to a section of the wiki that might be useful? Has anyone written their own script to do this already?
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

There is a plan to add this feature directly into the engine, unfortunately it is not finished yet.

However, you can fake this feature if you save the X, Y, and direction of all the NPCs on the map into global variables. There is a maximum of 300 NPC instances on a map, so this takes 900 global variables. You can do this in a loop with the "write global" and then load them back with "read global". It helps to know that NPC reference numbers are negative numbers from -1 to -300

Here is an example script that stores NPC information starting at global variable ID # 3000

Code: Select all

plotscript, save all NPCs, begin
  variable(ref, where)
  for(ref, -1, -300, -1) do(
    where := abs(ref + 1) * 3
    write global(where + 0, NPC X(ref))
    write global(where + 1, NPC Y(ref))
    write global(where + 2, NPC direction(ref))
  )
end
then you can load them back with a script like this:

Code: Select all

plotscript, restore all NPCs, begin
  variable(ref, where)
  for(ref, -1, -300, -1) do(
    where := abs(ref + 1) * 3
    set NPC position(ref, read global(where + 0), read global(where + 1))
    set NPC direction(ref, read global(where + 2))
  )
end
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

James Paige wrote:There is a plan to add this feature directly into the engine, unfortunately it is not finished yet.

However, you can fake this feature if you save the X, Y, and direction of all the NPCs on the map into global variables. There is a maximum of 300 NPC instances on a map, so this takes 900 global variables. You can do this in a loop with the "write global" and then load them back with "read global". It helps to know that NPC reference numbers are negative numbers from -1 to -300
I read the wiki article about remembering vehicle locations and figured it would be something like this. I'll try to implement this code later this week and see what happens.

Thanks for your help.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

James:

I'm incorporating your script but I'm unsure of how exactly to implement it. How do I cue the script to run when the player saves the game from the ESC key menu? Or do I have to make a save point that opens a text box so that I can run the script? Vice versa, how do I make the "reload" script load every time you open your save game?
User avatar
mjohnson092088
Metal Slime
Posts: 428
Joined: Sun Jan 09, 2011 9:33 pm
Location: earth.

Post by mjohnson092088 »

Willy Elektrix wrote:James:

I'm incorporating your script but I'm unsure of how exactly to implement it. How do I cue the script to run when the player saves the game from the ESC key menu? Or do I have to make a save point that opens a text box so that I can run the script? Vice versa, how do I make the "reload" script load every time you open your save game?
this is why i like to use customized menu screens. you can have the "save" function in your menu call a script that looks something like this, instead of calling the save menu itself:

Code: Select all

plotscript, save game, begin
#insert your npc location saving script here beforehand, then...
save menu
#have the script call the save menu AFTER the npc location script so it actually saves the locations, otherwise the locations will be written AFTER the player saves game, so the locations won't actually be stored in the saved game data.
end
also, did you set the script as the "load-game plotscript" under "special plotscripts" in the "general game data section"?
Hey, I just met you, and this is crazy... So here's some lunchmeat... Sandwich, maybe?
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

Code: Select all

plotscript, save all NPCs, begin
  variable(ref, where)
  for(ref, -1, -300, -1) do(
    where := abs(ref + 1) * 3
    write global(where + 0, NPC X(ref))
    write global(where + 1, NPC Y(ref))
    write global(where + 2, NPC direction(ref))
  )
end
I think I'm starting to figure this out, but I'm still stuck. The script compiler displays an error on the line "where :=abs(ref+1)*3". It says "Unrecognized name abs. It has not been defined as a script, constant or variable."

I'm a little confused by what that line actually does. "abs" is not a command, but what the does the variable then represent? Also, what does the operator := do?
User avatar
Mogri
Super Slime
Posts: 4598
Joined: Mon Oct 15, 2007 6:38 pm
Location: Austin, TX
Contact:

Post by Mogri »

"abs" is the absolute value function. It doesn't exist natively in Hamsterspeak, but it's easy to write.

:= is the assignment operator. It assigns the value on the right to the variable on the left.
User avatar
mjohnson092088
Metal Slime
Posts: 428
Joined: Sun Jan 09, 2011 9:33 pm
Location: earth.

Post by mjohnson092088 »

the operator ":=" sets the value of the variable stated before the operator, in this case, "where", to the value after the operator.

"abs" is a command to return the absolute value of a value. basically it's there to change any possible negative values, say for example -5, to a positive value, which would just be 5.
Hey, I just met you, and this is crazy... So here's some lunchmeat... Sandwich, maybe?
User avatar
Pepsi Ranger
Liquid Metal Slime
Posts: 1419
Joined: Thu Nov 22, 2007 6:25 am
Location: South Florida

Post by Pepsi Ranger »

(You also have to have a current version of HSPEAK, and the latest nightly while you're at it, to get abs to work since it's newer than the Ypsiliform release.)

It's your best function for proximity based scripts since you can simplify distance from hero in any direction and still boil it down to a single number. It's one of those "must know about" functions. My pick for 2010's plotscripting command of the year.
Place Obligatory Signature Here
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

Sweet. Thank you for the all the help. I'm using the most recent stable build but I managed to find the ABS script in the third party utilities scripts that are on the wiki. Everything seems to be working well but I still need to do more testing.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

I decided to resurrect this old thread instead of making a new one since my current problem might be solved by a similar script to what James created above.

I use the Alter NPC script pretty extensively in the game I'm working. For example, there's a rough patch on the ground that's represented by anNPC that triggers a text box. After the patch has been dug up, the rough patch becomes a hole with a different text box.

This is easy to do, but the problem is that when the player saves and reloads the game, the NPCs revert back as if the Alter NPC script had never happened (this also happens if the player uses a door, but that's not important). Is there some way I can re-activate all those Alter NPC scripts when the player reloads the game?
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Willy Elektrix wrote:I decided to resurrect this old thread instead of making a new one since my current problem might be solved by a similar script to what James created above.

I use the Alter NPC script pretty extensively in the game I'm working. For example, there's a rough patch on the ground that's represented by anNPC that triggers a text box. After the patch has been dug up, the rough patch becomes a hole with a different text box.

This is easy to do, but the problem is that when the player saves and reloads the game, the NPCs revert back as if the Alter NPC script had never happened (this also happens if the player uses a door, but that's not important). Is there some way I can re-activate all those Alter NPC scripts when the player reloads the game?
If you only have one map, then you can do this in the "on load" script, but I assume that you have many maps, and they are set to remember changes made to NPCs. You could add a "map autorun" script on each map that would repally the changes, but then you will need to have tags or global variables that keep track of which NPC holes have been dug.

There is another approach that can accomplish what you are trying to do. You will need one tag and two NPCs for each diggable rough spot.

Make one NPC for the rough spot. Have it only appear when the tag is OFF. Have the text box turn the tag ON. The other NPC is the hole. it should only appear when the tag is OFF. Put both npcs on the same spot on the map. When you activate the first NPC, it will disappear and the hole NPC will appear. This method requires no scripts, and will automatically be stored in save games (because tags are automatically saved)
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

James Paige wrote:Make one NPC for the rough spot. Have it only appear when the tag is OFF. Have the text box turn the tag ON. The other NPC is the hole. it should only appear when the tag is OFF. Put both npcs on the same spot on the map. When you activate the first NPC, it will disappear and the hole NPC will appear. This method requires no scripts, and will automatically be stored in save games (because tags are automatically saved)
Wait a second. You can put two NPCs on a single tile? I didn't think you could do that. Is this only available on the newest version? Although this is still problematic because I have probably 50 or so altered NPCs.

More realistically, I will just change the method of saving in my game. My game is a series of 5 maps. The player will complete each map and then move onto the next map. Between each of these maps is a shop where the player can stock up on items for the next map.

I'll probably just set it up so the player can only save inside these between level shops. When the player loads, I'll trigger a script that loads the shop menu. That way they can save before they buy things in case they make poor money-spending decisions.

Ugh. This will take some restructuring of my scripts. In any case, thanks for your help James.
Last edited by Willy Elektrix on Wed Jun 01, 2011 1:34 am, edited 1 time in total.
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Willy Elektrix wrote:
James Paige wrote:Make one NPC for the rough spot. Have it only appear when the tag is OFF. Have the text box turn the tag ON. The other NPC is the hole. it should only appear when the tag is OFF. Put both npcs on the same spot on the map. When you activate the first NPC, it will disappear and the hole NPC will appear. This method requires no scripts, and will automatically be stored in save games (because tags are automatically saved)
Wait a second. You can put two NPCs on a single tile? I didn't think you could do that. Is this only available on the newest version? Although this is still problematic because I have probably 50 or so altered NPCs.
Yes, there has always been a way to place multiple NPCs, although not a very obvious one. Hold the CTRL key and press the arrow keys. This places an NPC facing in the direction you pushed without removing any NPCs who are already on that spot like the SPACE bar does.
Willy Elektrix wrote: More realistically, I will just change the method of saving in my game. My game is a series of 5 maps. The player will complete each map and then move onto the next map. Between each of these maps is a shop where the player can stock up on items for the next map.

I'll probably just set it up so the player can only save inside these between level shops. When the player loads, I'll trigger a script that loads the shop menu. That way they can save before they buy things in case they make poor money-spending decisions.

Ugh. This will take some restructuring of my scripts. In any case, thanks for your help James.
Glad to help, and sorry there isn't an easier way. NPC saving as a built in feature will come eventually, but I can't guess when.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

James Paige wrote:Glad to help, and sorry there isn't an easier way. NPC saving as a built in feature will come eventually, but I can't guess when.
No problem! I'm happy to find a work around. I don't mind working within the limitations of the engine. My problem is that I often don't understand the limitations of the engine until I've already done a lot of work that I'll end up having to redo. I've been learning that lesson a lot with my current game. :zombie:

By the way, I've been meaning to ask, how exactly do the "wait" commands work, technically I mean. For instance, I find that I have to insert a lot of waits of varying lengths when I'm switching between backdrops, menus, and text boxes in a sequence. I think I have the timing perfect after much experimentation, but if I play the game on a faster or slower computer will the waits actually be of entirely different intervals? Forgive my ignorance, but how does that work?
Post Reply