Setting up game variables?

This forum is for the Lua scriptable clone of DM/CSB called Dungeon Strikes Back by Sophia. Use DSB to build your own highly customised games.

Moderator: Sophia

Forum rules
Please read the Forum rules and policies before posting.
Post Reply
User avatar
meadwarrior
Journeyman
Posts: 91
Joined: Sat Dec 01, 2018 1:02 am

Setting up game variables?

Post by meadwarrior »

Hello, and a happy 2019!

What would be the best way to set up a variable that can be saved for future use, like the number of times the player talked to a specific person etc.?
Is this what gameflags are used for?

Thanks!
User avatar
Gambit37
Should eat more pies
Posts: 13720
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Setting up game variables?

Post by Gambit37 »

I store global vars as exvars within a unique dungeon object. I created a new arch, obj.datastore, then record its ID, let's say that's 123. You can then use it in your code like:

Code: Select all

exvar[123].npcspeakcount = 2
Since the ID of an item placed in ESB doesn't change unless you delete it and recreate it, this should work fine. Personally I use a dsb_insts loop upon game startup to search the dungeon for my object and store its ID but it's not strictly necessary.

The benefit of this method is that the exvars you save in your object get stored in your save games. You can of course also just generate these as global variables but then you need to use dsb_export to ensure they're saved and for some reason I found that harder to manage.
User avatar
meadwarrior
Journeyman
Posts: 91
Joined: Sat Dec 01, 2018 1:02 am

Re: Setting up game variables?

Post by meadwarrior »

Hmm, I'm not sure I understand how to set this up. Could you explain it a bit more detailed, if that's possible? (Where and how do I set up the dungeon object etc.)

Also, how would I setup a global variable?

Thanks and sorry for the beginner questions ;)
User avatar
Gambit37
Should eat more pies
Posts: 13720
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Setting up game variables?

Post by Gambit37 »

Sure, I'll do my best. By "new dungeon object", I mean a new "archetype", in DSB parlance. Do you already understand what an archetype is? If not, there's some info on the wiki here: https://dmwiki.atomas.com/wiki/DSB/Archetypes

So my new archetype is defined in my objects.lua:

Code: Select all

obj.store_data = {
	type="FLOORFLAT",
	class="MECHANICS"
}
All the properties of an archetype are themselves exvars. In the simplest sense, exvars are just variables. So for my new store_data object, there's a type exvar and a class exvar which contain the values FLOORLFLAT and MECHANICS respectively. Click for an ESB screenshot of how this shows up in the editor: https://matthill.co/filesdm/dmxtra_esb_01.png

When an archetype is placed in the dungeon, you've placed an instance of that archetype. You can have many instances of the same archetype (eg, an apple or a door). But for my store_data object, I just place ONE instance.

Note that this archetype/instance doesn't DO anything in and of itself, it's just an used as a container for storing the value of my global variables. Nothing targets it and it targets nothing.

Here's why it's useful:

DSB can add and update new exvars for any instance. So if I have a global variable that I want to store and interrogate in my code later, I can add it as an exvar to my store_data instance in the dungeon. You can't "see" that anywhere (ESB won't show you exvars stored in instances in this way). But the variable IS stored, and will be retained when the game is saved.

To give an example of how you might use this, I have a modified function for h_party_move. It includes this code which tracks how many tiles the player has walked, and will be used in a "game stats" screen at the end of the game:

Code: Select all

if (not exvar[store_data].steps_walked) then
  exvar[store_data].steps_walked = 0
end
exvar[store_data].steps_walked = exvar[store_data].steps_walked + 1
In this code, I'm saying to DSB:
* look for an exvar called "steps_walked" in the instance [store_data]
* If that exvar doesn't exist, then create it and set it to 0
* Add 1 to the exvar each time the player moves, and update the "steps_walked" exvar in the instance

Note that you always need to know the ID of any instance when you want to manipulate its exvars. When I gave the example previously, I used an arbitrary value of 123. You'll need to get the correct ID for your particular instance, which is revealed in several places in ESB. The easiest way is just to hover over the object in the dungeon view, and ESB shows the ID in square brackets in that grey panel at the bottom right of the screen.

That said, a better way to get the ID is to iterate over the dungeon in your code and assign it dynamically. That way, if you do happen to delete/re-create the instance in your dungeon, you don't need to go back to your code to update the ID. Plus it's a better practice not to hard-code values like this anyway. Here's an example of how you might do that, with some code you can place in your startup.lua:

Code: Select all

for id in dsb_insts() do
  if (arch == obj.store_data) then
    store_data = id
  end
end
The above code loops through *every* instance in the dungeon (monsters, things, doors, decorations, mechanics, etc.). If it finds one with an archetype name of "obj.store_data", it assigns its ID to my own variable store_data. I can then use that when updating exvars for that instance, ie, exvar[store_data].exvarname.

Global variables instead of exvars

As for global variables, you can just set them anywhere in any of your lua files, but typically you'd either put them in your own globals.lua or startup.lua, eg:

Code: Select all

my_global_variable1 = 0
my_global_variable2 = 0
Then later you can just update this variable in response to player input. But if you want to store it in savegames, you need to export it, and then it's possible to get into a mess between what's in the exported variable vs. the variable getting reset in your startup. At least, that's what I experienced when trying to use exported variable, so I decided to use exvars in instances instead.

Having re-read this, I think maybe I've over explained it to the point of confusion. If so, let me know, and I'll try again :)
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Setting up game variables?

Post by Sophia »

One small addition/correction. The code to search for a given arch needs to get the arch of the objects it's iterating over:

Code: Select all

for id in dsb_insts() do
  local arch = dsb_find_arch(id) -- Added this line
  if (arch == obj.store_data) then
    store_data = id
  end
end
User avatar
meadwarrior
Journeyman
Posts: 91
Joined: Sat Dec 01, 2018 1:02 am

Re: Setting up game variables?

Post by meadwarrior »

Thank you very much! Over-explaining is the exact best thing for me, the different steps made it very clear what I have to do.
Sorry again for asking the beginner questions.

Again, thanks a lot for you help! I'll try it out and see what I can do.
Have a fine day!
User avatar
Gambit37
Should eat more pies
Posts: 13720
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Setting up game variables?

Post by Gambit37 »

Ooops, thanks for the correction Sophia. I simplified that example from a longer piece of code and inadvertently deleted that line!
Glad to be of help Meadwarrior.
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Setting up game variables?

Post by Sophia »

I'll also add that there's a helper function in the base code called change_exvar that helps with the error checking involved in incrementing an exvar.

This is equivalent:

Code: Select all

change_exvar(store_data, "steps_walked", 1)
User avatar
Gambit37
Should eat more pies
Posts: 13720
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: Setting up game variables?

Post by Gambit37 »

Oooh, nice, I've never spotted that. Very helpful :)
Post Reply