Long term use of regs?

Currently viewing this thread:

jik

Knight
I am seeing a need for my self of some global (short term) variables, which I believe the reg and s variables are used for, but I want to make sure I'm not stepping on toes.

For example, reg0 usually holds the value of a spawned object.  But in general, are regs (and string regs) just a short term holding spot?  In the case with string regs, I see that quest seem to hold values till the quest ends.  Or is this value reset each time the quest is checked or a dialog comes up?

As I have been starting to use them, I try and search for a reg that is not used in native (such as reg40-45) when doing stuff to not step on toes, but that is a bit frustrating, and it would be nicer to know the answers to the above questions.

(info I would add to the tutorial update in the appendix)
 

Highlander

Marquis
WB
I'm pretty sure that reg0... are not global variables. Not sure about the string variables (s1...).
I personally prefer not to use regs, but instead just something like ":whatever" or for global "$whatever". Complicated pieces of code get very unclear, if you use just reg0-reg65.
 

jik

Knight
Highlander said:
I'm pretty sure that reg0... are not global variables. Not sure about the string variables (s1...).
I personally prefer not to use regs, but instead just something like ":whatever" or for global "$whatever". Complicated pieces of code get very unclear, if you use just reg0-reg65.

regs aren't global?  I thought they were.  I see what you are saying and I might go that route, but I was trying to optimize early on.
 

Twan

Sergeant Knight
Regs are globals.

Look at the scripts returning regs value, and these regs values then used everywhere.
 

kt0

Knight
Does anyone know if registers get saved with save games?  If they don't, it would exclude them from normal global usage.  If no one knows (and I remember when I get home) I'll check tonight.

If you do want to use a register as a short term global and are worried that someone's going to step on it, rename it in header_common.py (or wherever it is that it's declared; can't check cause I'm at work).  That way if anyone does use it, you'll get a compiler error right away and can either fix all the references or pick a different reg.  Course, such hackeries make code notably not-particularly-portable.  YMMV.
 

jik

Knight
kt0 said:
Does anyone know if registers get saved with save games?  If they don't, it would exclude them from normal global usage.  If no one knows (and I remember when I get home) I'll check tonight.

If you do want to use a register as a short term global and are worried that someone's going to step on it, rename it in header_common.py (or wherever it is that it's declared; can't check cause I'm at work).  That way if anyone does use it, you'll get a compiler error right away and can either fix all the references or pick a different reg.  Course, such hackeries make code notably not-particularly-portable.  YMMV.

I can already check (using notepad++'s search files in a folder thingie) and I see that reg40 (and a few others) are not used except where they are first declared. 

This thread is more for the merging of kits and other mods.  Think about it.  If I make a kit that carries regs over long term (days or weeks of game time), there is a chance that another person might have used the same reg in their kit/mod/scripts.  This is kind of a fact finding thread so that people creating kits to be merged with other kits don't step on each other.

I still think that if the regs are there they should be used instead of creating 100s of global vars.
 

kt0

Knight
jik said:
I can already check (using notepad++'s search files in a folder thingie) and I see that reg40 (and a few others) are not used except where they are first declared. 
Indeed you can.  But six months down the line, will you remember that you use reg40 as a global?  I can't remember such things reliably and I've been bitten by these kinds of issues in the past.  I want the compiler on my side. 

jik said:
This thread is more for the merging of kits and other mods.  Think about it.  If I make a kit that carries regs over long term (days or weeks of game time), there is a chance that another person might have used the same reg in their kit/mod/scripts.  This is kind of a fact finding thread so that people creating kits to be merged with other kits don't step on each other.
All the more reason that renaming a register used in this way is a good idea.  You turn any such issues into compile time issues rather than "holy crap, something's stomping on my data" issues.  I'll always pick the former rather than the latter if I have a choice.  The very people who would most benefit from having ready-to-use kits are the same people who are least likely to be able to resolve the latter kind of issue.

jik said:
I still think that if the regs are there they should be used instead of creating 100s of global vars.
Depending on what I find out tonight, I reserve the right to disagree :wink:
I will say that anyone who's done any reasonable measure of assembly programming will tell you that symbolic variable names are way better than generic labels (like Highlander says).  I'm not certain that there's any prohibitive cost to using lots of globals other than save game compatibility. 
 

jik

Knight
I have a 20 page (and growing) game design document that I update as I work on my mod.  There I store information on what I want to accomplish, and as I work through it, I put important information (like slot usage and other variable stuff) in the section corresponding to what I am working on.  I find this a good practice so that if I am force to take time away from my project, I can easily jump back in.  So for me, I have that stuff written out.

I know that for debugging and code checking, good variable labels are key, but for optimizing, the less you use the better.  For example:
I need about 4 variables to manage my jousting.  I can use reg40-43, or make global vars.  Now I need 4 for archery, 4 for javelin, 4 for melee.  Each is only used in a short bit of code, but they never over lap.  I can use the same reg40-43 for each one without conflict, or I can use 16 new global vars.

In my case it might be up to 8 variables each event.  I won't believe that defining 16 new variables is more (machine) efficient than using 4 that already exist.

And this goes into how big of a mod you are working on.  Later down the road, I will most likely change out the global vars I am declaring for regs if they are not held long.
 

Twan

Sergeant Knight
My personnal favorite variable is the slot value.

Instead of using 4 or 16 global variables you can use one unit to store thousand(s ?) of named global variables, and use any automated process on these variables with a try_for_range if needed.

If you have variables with similar functions (ie if you store the same kind of variable for different style of tournaments in your mod), it looks far more eleguant to store them in slots than in regs, imo.
 

kt0

Knight
jik said:
I have a 20 page (and growing) game design document that I update as I work on my mod.  There I store information on what I want to accomplish, and as I work through it, I put important information (like slot usage and other variable stuff) in the section corresponding to what I am working on.  I find this a good practice so that if I am force to take time away from my project, I can easily jump back in.  So for me, I have that stuff written out.
I'm not saying this isn't a good practice.  I'm just saying that I take every chance I can get to put the odds of not screwing something up in my favor.  As a corollary to that, I take every chance I can get to make it obvious when I do screw something up.  Most of my career has been spent dealing with/optimizing legacy systems so I've spent a lot of time thinking about how to make these kinds of issues go away :wink:  YMMV.

I won't debate your efficiency argument here beyond saying that I think you overstate it.  Personally, I wouldn't trade readability and potential future bugs for what's most likely 64 bytes and I wouldn't change my mind if it was 64KB.  On the flip side, if you move to registers and rename them in the appropriate header, you trade a little header hackery for early detection of data stompage issues and peace of mind.  The choice is yours  :mrgreen:
 

Yoshiboy

Count
M&BWB
As you know registers are global and non-descript memory. Before local variables were implemented by armagan you had to use them extensively so they shouldn't really break anything except in really rare cases. I can't remember any problems from them. Saying that I would still stay away from reg0 as it has special uses like you've found.

Common uses for registers are things like when you need to hold a variable from a script in a scene to the world map, once the script finishes. Something a normal local variable can't do. In this case you should be confident no outside script will interfere with your register in the short jump between scene and world map.

Another use is for the shuffle command, which can shuffle a range of registers.

If you're still worried about breaking things, why not set up a ton of global variables: "$r1", "$r2", "$r3", "$r4", etc..
This is essentially the same thing.

As long as you use them responsibly it should work fine.

The only benefit of using registers over global variables is that they may be slightly faster. Both are globally stored in memory.

As far as string registers are concerned, they are handled differently. Typically you set up the register just before the string is used in a menu or display_message

Quests are done differently too, if I recall correctly the "setup_quest" command (or similar name) makes the storage of the quest string permanent. Changing a string register involved in setting up a quest wont break the quest.

In my mind, I wouldn't get too hung up about them. Instead of trying to keep track of every variable, try to keep track of your overall design.
 

jik

Knight
Thanks all, this has been very helpful.  Maybe I'm going on overkill for early optimizing.

The idea of using slots (such as a temp party to hold the data) is all and good, but I'd have to assign high up slots not to interfere with the native slots.  Not much of a problem, unless you have overlap from other kits, but that can be worked out (just change the slot numbers).

Globals are easiest to use cause you can define them as you need them.


In this case I may go with slots.  I'll just make a temp party called tourney_array and use that.
 

kt0

Knight
kt0 said:
Does anyone know if registers get saved with save games?
Answer:  no.  If you save and exit, then quit the game, they'll be initialized to zero when you come back. 
 

MartinF

Squire
I think that was also what Twan meant, jik.

And I think that would still be the best option as long as we can't directly use arrays for data storage. Although using a hundred global vars is not necessarily as bad as it would seem as their memory footprint is very small.
 

jik

Knight
MartinF said:
I think that was also what Twan meant, jik.

And I think that would still be the best option as long as we can't directly use arrays for data storage. Although using a hundred global vars is not necessarily as bad as it would seem as their memory footprint is very small.

If that's really the case and making 100 global vars has little to no effect, I may just go that way.  The benefit of the slots is (like an array) I can go through it with a loop.
 

foxyman

Sergeant Knight
M&BWB
As to using slots, you can spawn new parties to create temporary arrays and use them however you like, not even caring the native slots. They're also preserved by savegames. You can refer to the Mod Community for some great guys' array code.
Using long-term registers to me is definitely a bad idea. But within code managed by your own(here I mean the scope never goes out during their life time), you can use them as substitution of arrays.
 

MartinF

Squire
exaclty... as long as the temp troops/items/parties are not in any of the native loops (something_begin, something_end) their native slots would never be used or set so it wouldn't matter which slot nrs you use.

From a good coding point of view it might still be a good idea to declare the slots in module_contants, just so you (or someone else using the code) know what each slot does for that array unit.

You could define say, troop_array_1 through however many you need and then define

slot_array_whatever = 1

and so on, so you have a reference for what is actually defined in each slot for the array troop.

And yeah, the biggest benefit over using global vars would be that you can loop.  Since there's an eq and a ge operation for slots, you've got most of the functionality you'd have when comparing vars and when you need to do more complicated stuff you can get_slot and set_slot which are hardly very processor intensive operations.
 

jik

Knight
MartinF said:
exaclty... as long as the temp troops/items/parties are not in any of the native loops (something_begin, something_end) their native slots would never be used or set so it wouldn't matter which slot nrs you use.

From a good coding point of view it might still be a good idea to declare the slots in module_contants, just so you (or someone else using the code) know what each slot does for that array unit.

You could define say, troop_array_1 through however many you need and then define

slot_array_whatever = 1

and so on, so you have a reference for what is actually defined in each slot for the array troop.

And yeah, the biggest benefit over using global vars would be that you can loop.  Since there's an eq and a ge operation for slots, you've got most of the functionality you'd have when comparing vars and when you need to do more complicated stuff you can get_slot and set_slot which are hardly very processor intensive operations.

I keep forgetting how the slot defs work.  I could still call "slot_item_food_bonus" for a check for slot 1 in an agent and it would work (finding the agent slot "slot_agent_target_entry_point").


thanks again MartinF.  You have a good way of making things seem much more clear.

BTW: What is the upper limit of slots?
 

kt0

Knight
The slot values we define are just offsets in the slot array.  You could use integers if you like (in fact, you can use ID values from the ID headers and integers for most things if you like).  So as long as two things aren't putting different data into the same slot on the same object you should be fine. 

As for how many slots max are there, I don't know.  I suspect there's a hard limit somwhere.  A previous discussion can be found here:  http://forums.taleworlds.com/index.php/topic,8652.msg1334439.html#msg1334439.  I haven't had a need for that kind of storage (yet) so I haven't done any testing.
 

jik

Knight
well, I have seen some mods with slots numbered over 1000 (not 1000 total, but using slot 1001,1002,1003, etc)

What I meant to ask was the value of a slot.  as in what is the largest/smallest value that a slot can hold (I have some big numbers! :wink:  OK, maybe not, but I need to store up to, maybe 50,000)
 
Top Bottom