• 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

Creation Scropt and derived field?

TCArknight

Well-known member
Is there anything special I need to do to have a creation script set the default value of a field with a pick is added?
Code:
    <creation><![CDATA[
      var career as string
	  var careerspec as string
	  var speccost as Number
	  var speccount as Number
	  
	  careerspec = tagids[CareerSpec.?]
	  career = hero.findchild[Career].tagids[CareerSpec.?]
	  
	  speccount = 1
	  speccount += hero.tagcount[HasSpecialization.?]
	  speccost = 10 * speccount
	  
	  notify speccost
	  
	  field[stXPCost].value += speccost
	  notify field[stXPCost].value
	  
      ]]></creation>
The notify shows as expected, but when I check the field histories the value is ) and says unchanged since creation.

Thoughts?
 
A creation script is not the correct place to change a derived field - it will not stick. There is no way around this. Only use creation scripts to set the default values of user fields. Use regular eval scripts to change derived fields.


If this is a value you need to set at the time the user adds it, based on what the state of the character is at that point, you'll need to change that field to a user field (or add a user field into that component, and set up the derived field to add the user field's value to itself so that you incorporate the changes from this creation script). But are you certain that permanently recording that state is the right way to go? What if the user changes their mind about how to build their character - like takes different career specs? It seems like HL should adapt to that, and that's what an eval script will do.
 
Thank you Mathias. I saw it being used to set the fields and now that you mention it it is for user fields each time.

Is there a best/preferred way to get an eval script to only run once? Every time I run it, it does a re-eval and resets the cost to the new value.

I came across a state.creation check in one dataset, would that be the thing to use?
 
state.creation only matters in games like Shadowrun, where there's a creation mode and an advancement mode. If you haven't enabled that mode, state.creation will always be true.

Let's talk about what you're setting up here - I find that run-once eval scripts should be a last resort, so I'd like to know what game rule is being implemented to make sure this is the right way to go.

The normal method for doing so is to add a new field with
type="derived"
persistence="full"

And your run-once eval script is bracketed by:


doneif (field[stHasRun].value <> 0)

and

trustme
field[stHasRun].value = 1

Those two settings make the field act in a lot of ways like a user field - persistent derived fields can be set in creation scripts and trusted eval scripts, but unlike a user field, you couldn't set up an incrementer portal to let the user control it.
 
That does make sense.

The issue I’m trying to resolve involves the cost of the Specialization increasing with each additional one taken.

1) Each career has three Specializations that are associated with it. One, tagged with Career.InitSpec, is no cost.
2) An additional Specialization is 10XP * Number of Specializations Taken (including the new one). So taking a second Specialization would be 20XP, a third one would be 30XP, etc.
3) If the new Specialization is not associated with the Career of the hero, it costs an additional 10XP.

Given that, setting the cost of the Specialization as it was added seemed to make the most sense.
 
A creation script or a run-once eval script isn't how I'd accomplish that, but how to implement this depends on how XP spending works. Is spending XP in this a matter of subtracting the XP cost of each pick from a field value - for example, is there an XP resource, where the maximum is added to by journals, and the "amount used" is the XP spent, or is this a game where the XP cost is subtracted from a usagepool at the time of purchasing the item?

If this is the latter, then I'm assuming you're using the skeleton files and using creation/advancement mode, and that this item can only be added in advancement mode.


If it is the latter, somewhere in this forum, I know I explained how the Shadowrun XP system works - someone else was building a game that like yours, and like shadowrun, has costs that increase with each purchase of a thing. I don't have time to find that thread right now, though - sorry, but look back a couple years for when other people have asked about XP costs. The key is that adding the advancement bonus to the value of the thing must be in the same script that calculates the cost, so that each copy, when running the cost calculation script, sees the correct number of copies to calculate its own cost, and then the next item sees a different number of copies, so it calculates its cost as higher.
 
Last edited:
Assuming that XP costs are always just subtracted from something, or always just added to an "XP spent" total, like on a resource, this is all a standard eval script - the script that calculates the cost of this item needs to also be the script that reports the presence of this item to the hero with a hero tag. So copy #1 runs - it assigns the hero a copy of the "we have this specialty identity tag", and then sets field[xpCost].value += 10 * hero.tagcountstr["HasSpecialization." & idstring], leaving it with a cost of 10. A later script then applies that cost to the hero's total "XP spent". Ok, so copy #2 runs this same component script after copy #1 - it assigns the identity tag, and so when it calculates field[xpCost].value, it ends up with a cost of 20.

This way, if the user deletes one of these specialties, regardless of whether it's copy 1, 2, or 3, the cost of what's left just recalculates based on what's currently present.
 
Last edited:
Mathias, thank you very much! Your comments had me dig deeper and I came across the answer to my issue(s). :)

I'm including my solution in case anyone might come across a similar issue. The solution lay in adding orderfield="stOrder" to the Specialization component. Each specialization is unique, so all I have to know for the cost determination is what specialization number it is and the stOrder field will then contain that.

As such, I can do: field[stXPCost].value = 10 * field[stOrder].value

Since the initial specialization is free I just need this to decrement the XP available:
Code:
<!-- Accumulate the XP cost for specializations when user-selected -->
    <eval index="4" phase="Setup" priority="110"><![CDATA[	
      ~ initial specialization is free	
      doneif (tagis[Career.InitSpec] <> 0)	
	  
	  #resspent[resXP] += field[stXPCost].value
      ]]></eval>
 
Back
Top