• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Newb(ish) question

Grymdal

New member
My group and I are about to start a new Campaign with Savage Worlds and are all HeroLab users/fans. I'm going to table rule a few things and I'm trying to figure it out in HL Editor but I'm not having much success.

I want to change the amount of XP it takes to go from one rank (Novice to Seasoned to Veteran...etc) from 20xp to 25xp and be able to share the file or setting with my group so we are all on the same page.

Please bear in mind I'm not a tech-guy or coder or anything like that (I work in healthcare) so feel free to dumb it down as much as you need to.

Thanks in advance.
 
Yeah, that is NOT a newbie question! In fact it's something that exists on the requested features thread to have added to Hero Lab for Savage Worlds, some method for doing that. So thanks for totally stumping me with a "newbie" question! ;)

That being said I think this is one of those situations where you wouldn't be able to just do it in the Editor. I think you would have to copy out the entire game system to a new one and then modify C:\ProgramData\Hero Lab\data\savage\source\actor.str file (that "savage" part would actually be whatever you name your new system) to change how acRank is calculated (changing the 20 in that calculation to 25).

Because acRank is an integral part of the base files I'm not so sure you can just directly change it without making a new game system to do it in. In any case I don't think that's an easy change, but there are some other far more knowledgeable folk here who might know how to do it, I'm just not one of them I'm sorry to say. :(
 
LOL - it stump me also zarlor - that's why I didn't reply until you had a look at it. I was pretty sure it would be a major pain, not sure if you could rig a mechanic to make it work, but I knew I would have to think about it real hard before giving an answer to whether it could be done without Cape having to work it into the system itself.
 
I have already whined about it a few times. Now I am just whining to get the updated Super Power Companion and Sci-Fi Companion. :D
 
I have already whined about it a few times. Now I am just whining to get the updated Super Power Companion and Sci-Fi Companion. :D

May not be a bad time. Caped is definitely going to be knee deep in the code to cover those, I think. Then again it may also mean he's swamped trying to get those done which could push something like this to the backburner. I made sure it's in that consolidate list of requested items if that helps him any. I realized that the original thread quickly became a mix of stuff being asked for and stuff already done or that was mentioned couldn't be done (or at least not in the way we might have wanted) so I'm hoping that can make it a little easier for him to find it all nicely consolidated in one place where I can easily edit it to remove things that get added in from it.

At any rate I can see were the code for this is in the actor.str file, but I don't know if you can override something like that using a script in he Mechanic tab. I think it would be pretty heavily timing dependent, but also thing it's so heavily integrated at different layers that I'm not too sure you could override it that way.

Basically it is all taken care of with this:
Code:
<field
  id="acRank"
  name="Current Rank"
  type="derived">
  <calculate phase="Final" priority="1000"><![CDATA[
    var xp as number
    xp = hero.child[resXP].field[resMax].value
    if (xp < 80) then
      @value = round(xp / 20,0,-1)
    else
      @value = 4
      endif
    ]]></calculate>
  </field>

And you'd need to get that line for "@value = round(xp / 20,0,-1)" changed to "@value = round(xp / 25,0,-1)", if I'm reading that correctly. But it's calculated at Final/1000. Maybe if you set the timing at Final,1001 you could override how it's calculated and it would still work right?
 
zarlor, this is something you can override using a mechanic:

Put this eval script on your mechanic (note the phase & priority I'm using, and how it compares to the original):

Code:
<eval index="1" phase="Final" priority="1010"><![CDATA[
    var xp as number
    var xpperrank as number
    xpperrank = 25
    xp = hero.child[resXP].field[resMax].value
    if (xp < xpperrank * 4) then
      herofield[acRank].value = round(xp / xpperrank,0,-1)
    else
      herofield[acRank].value = 4
      endif
  ]]></eval>
 
Last edited:
Ah, well there you go Grymdal. Thanks as always, Mathias!

I didn't realize it would quite work there, but Mathias is definitely a coding guru on Hero Lab without a doubt. To do that just open up the Editor and open the .user file you are using for your setting (or just a blank one if you are creating a new one. Click on the Tab labeled "Mechanic". If you are modifying an existing file and there is already a Mechanic there then you can just click on it's name to use that one, otherwise just click on the "New (Blank)" button at the bottom. Replace the ???? marks in the name with whatever you want to name this. If I were modifying my House Rules file, for example, I might called it House Rules Mechanic, for example. For UniqueID I would use something like mecHRHouse or mecHRRank (the latter is fine if you want to have separate ones for various mechanics, but I usually just stick with one and throw any mechanics changes into that one.)

You may also want to click on the Edit button at the bottom next to where is says "Sources". If you already have a source created for this setting then just select that one, or if this is something new then check the box for -New Source- and click OK. Then for Source Name you could use something like House Rules, with a UniqueID of something like HouseRules. Then click OK and that will save your new Source in this file. This also makes it easier when you are selecting what sources you want to use in Hero Lab to be able to select your own House Rules file.

I'm going to digress a moment to cover that whole Source idea. If you want the 25xp/rank to be the standard for games you run with Hero Lab then House Rules is a good enough name. But if you want to be able to just select that Mechanic separately from anything else you do, just adding it in when you want to use just that rule, then you might give it a more descriptive name for the source so you'll see it as that specific rule. So instead of House Rules you might call it "25xp per Rank", for example, and use appropriate codes above to reflect that (so a UniqueID of a 25xp and instead of "HR" in the UniqueID above use "25", or something like that.)

So back to filling out the mechanic. In the Description Text box just describe what you are doing with this mechanic so you'll know when you look at it later, something like "This mechanic makes all Rank increases cost 25xp instead of 20xp." Then click on the Eval Scripts button on the right. Change the Phase from Initialization to be Final. Set the Priority to 1010. Don't worry about the Index number.

Next in the big box under "Script" type in (or just cut and paste from here) the following:

Code:
    var xp as number
    var xpperrank as number
    xpperrank = 25
    xp = hero.child[resXP].field[resMax].value
    if (xp < xpperrank * 4) then
      herofield[acRank].value = round(xp / xpperrank,0,-1)
    else
      herofield[acRank].value = 4
      endif

Click OK, then click Save at the bottom left and save your .user file. That's it. After that just select the source on your Configure Hero screen for the character your making to include your new House Rule (or whatever you name it) source and it should apply from there.

NOTE: I haven't actually tested the above, but I trust Mathias' coding so you should be good there. However if you do run into any issues just let us know and I'm sure one of us will do our best to help out!

Thanks again, Mathias!
 
Thanks for the help. While the code looks like it should work, it didn't. It is probably a timing issue. It would probably be better if it were more like Pathfinder, where having a built in "replaces XP table" thing were built in.
 
Please be more specific than "should work, it didn't". Without details, I can't help you figure out what went wrong.
 
OK, I created the mechanic as described. But when I tested it by putting XP on the character it retained the use of the original XP table. The mechanic had no apparent effect.
 
Did you add a source to the mechanic?

If so, did you make sure the corresponding checkbox in configure hero was turned on?
 
Yes, I did. I had a source that was checked. I also took out the source so that it is always active if the .user is in the folder, just to see if somehow it didn't like having a source.

phase=Final
priority=1010

eval script:
Code:
     var xp as number
    var xpperrank as number
    xpperrank = 25
    xp = hero.child[resXP].field[resMax].value
    if (xp < xpperrank * 4) then
      herofield[acRank].value = round(xp / xpperrank,0,-1)
    else
      herofield[acRank].value = 4
      endif

The code SHOULD work. It is creating a number variable for xp and xpperrank. Then it is assigning them values. It is also supposedly redefining the value for acRank, which is the whole point of the mechanic.

I also tried it with a "hard" value, just in case it did not like doing the math or referencing xpperrank. So it had the if(xp < 100) then... But it still didn't work. I doubted that the compiler would care, but you never know and it was worth trying.

So it seems to me that either it is a timing issue, or for some reason the acRank does not like being redefined. Or again with the timing, maybe it is redefining it but not recalculating the change after it was made.
 
Try Final/5010 - looking at the code for Savage Worlds, the rank calculations seem to have been moved around a bit, and are no longer at the same phase & priority that zarlor posted (and that I copied - sorry, I had not tested the code I posted). It appears that in this script, you should use xpvalue = field[acFinalXP].value

Also, you may need a second script, at Setup/4010, that uses xpvalue = #resmax[resXP], but is otherwise identical
 
Sorry, I posted the timing off of the Wiki. I should know better since it doesn't seem to get updated like the actual code does, but is more of an example of how the game system was built. SeelyOne, let me know what you get to work and I'll update the Common Code thread with all the details to make this work.
 
YAY! The Final/5010 was the issue. I did not need to add the possible other portion. I will post the answer in that other Common thread.
 
There is one problem. The XP per Advances does not change. At 80 it goes to the 10/advance. I know that is in a separate place, but I will have to look for it (unless someone else already has done so).
 
OK, I found how the Advances are figured out. Line 769 of actor.str
Code:
 [FONT=Consolas][SIZE=5][COLOR=#808080][FONT=Consolas][SIZE=5][COLOR=#808080][FONT=Consolas][SIZE=5][COLOR=#808080]~calculate the total number of XP necessary for all of the advances
 var xp as number
 if (advances <= 16) then
 xp = advances * 5
 else
 xp = 80 + (advances - 16) * 10
 endif
 [/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
Going up before it, it appears to be in the
phase="Final"
priority="2000"
name="calc acFinalXP">
<
after name="Calc resLeft"
 
I have not been able to locate how/where Advances are calculated by looking through the files in the source folder.

But I do have another possible solution in mind. Maybe add another eval to the same mechanic that adds +1 advance for XP at each of 85 and 95.
 
Yay, I figured out a way to make it work. It is easier just to manually add it so that 85 and 95 will give XP. Just add in an eval such as this:
Code:
     var xp as number
    xp = hero.child[resXP].field[resMax].value
     if (xp >= 85) then
      hero.child[resAdvance].field[resLeft].value += 1
      hero.child[resAdvance].field[resMax].value += 1
      endif
     if (xp >= 95) then
      hero.child[resAdvance].field[resLeft].value += 1
      hero.child[resAdvance].field[resMax].value += 1
    endif
 
Back
Top