• 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

Trying to Puzzle out Advances

Duggan

Well-known member
In Planet Mercenary, the system I'm working on, there are essentially two advances. Either you gain a point in three distinct skills (two of which you're supposed to have used in the course of the scenario, but of course that's not really part of the program logic), or you buy a skill specialty. I'm working on the latter right now, and hitting some issues.

Background info
  • Specializations exist as picks in a gizmo on the related skill. That was the easiest way to set up dialogs to pick specialties off of character creation so that only Specialties related to a skill where displayed.
  • Most Specialties are unique, but there are two that are not and have a domain.
  • You cannot have more Specialties than you have ranks in a skill.

Exclusion expression
The skeleton code has code for excluding unique items we've already added before:
Code:
foreach pick in hero where "component.Skill"
  foreach pick in eachpick.gizmo where "component.Specialty & !Hide.Specialty"
  
    if (each.isunique <> 0) then
      tagexpr &= " & !Specialty." & each.idstring
      endif
    nexteach
  nexteach

For my character with two specialties already, that means an exclusion expression like "& !Specialty.spLongBeam & !Specialty.spMechJury" which is neat and tidy and works.

That works just fine, but I want to only display skills where it's possible to add a specialty, so I have code to try to exclude specialties which can't be added because there aren't sufficient skill ranks. I wound up with the following:
Code:
foreach pick in hero where "component.Skill"
  var skillID as string
  var skillrank as number
  var speccount as number
  skillID = eachpick.idstring
  skillrank = eachpick.field[trtFinal].value
  speccount = eachpick.tagcount[User.HasSpec]
  debug skillrank & ", " & speccount
  if (speccount < skillrank) then
    foreach pick in eachpick.gizmo where "component.Specialty & !Hide.Specialty"
      debug eachpick.idstring
      if (each.isunique <> 0) then
        tagexpr &= " & !Specialty." & each.idstring
      endif
    nexteach
  else
  ~  debug skillID
    foreach thing in Specialty where "Skill." & skillID
      tagexpr &= " & !Specialty." & eachthing.idstring
    nexteach
  endif
nexteach

That, for the same character, produces an exclusion string of "& !Specialty.spAirEvad & !Specialty.spAirNav & !Specialty.spAirPurs & !Specialty.spAirStnt & !Specialty.spAthClmb & !Specialty.spAthFlght & !Specialty.spAthJump & !Specialty.spAthPurs & !Specialty.spAthRun & !Specialty.spAthStr & !Specialty.spAthSwim & !Specialty.spCarbBeam & !Specialty.spCarbNL & !Specialty.spCarbProj & !Specialty.spDecBluff & !Specialty.spDecDisg & !Specialty.spDecDist & !Specialty.spEconLcl & !Specialty.spEconPlan & !Specialty.spEconSec & !Specialty.spEmpGamb & !Specialty.spEmpGInfo & !Specialty.spEmpInfl & !Specialty.spEmpRSoph & !Specialty.spEngArch & !Specialty.spEngHab & !Specialty.spEngPlVeh & !Specialty.spEngVess & !Specialty.spExpBld & !Specialty.spExpDet & !Specialty.spExpDearm & !Specialty.spExpPlac & !Specialty.spGrndEvad & !Specialty.spGrndNav & !Specialty.spGrndPurs & !Specialty.spGrndStnt & !Specialty.spHvyBeam & !Specialty.spHvyNL & !Specialty.spHvyProj & !Specialty.spHistMil & !Specialty.spHistPoli & !Specialty.spHistRel & !Specialty.spHistSoph & !Specialty.spInspLead & !Specialty.spInspOra & !Specialty.spInspSed & !Specialty.spIntCoer & !Specialty.spIntInter & !Specialty.spIntTort & !Specialty.spLarcBE & !Specialty.spLarcPLoc & !Specialty.spLarcPPoc & !Specialty.spLarcSlgt & !Specialty.spLongBeam & !Specialty.spMechJury & !Specialty.spMedBatt & !Specialty.spMedFAid & !Specialty.spMedSurg & !Specialty.spMeleeCom & !Specialty.spMeleeEx & !Specialty.spMeleeUn & !Specialty.spMeleeWr & !Specialty.spNegBlck & !Specialty.spNegHagg & !Specialty.spNegPers & !Specialty.spPercHear & !Specialty.spPercMag & !Specialty.spPercSght & !Specialty.spPercSmll & !Specialty.spPercTste & !Specialty.spPercThrm & !Specialty.spPercTch & !Specialty.spPerfAct & !Specialty.spPerfCom & !Specialty.spPerfDnce & !Specialty.spPerfSong & !Specialty.spPistBeam & !Specialty.spPistNL & !Specialty.spPistProj & !Specialty.spScatBeam & !Specialty.spScatNL & !Specialty.spScatProj & !Specialty.spSpcEvad & !Specialty.spSpcNav & !Specialty.spSpcPurs & !Specialty.spSpcStnt & !Specialty.spStaWBall & !Specialty.spStaWBeam & !Specialty.spStaWMiss & !Specialty.spStlthHid & !Specialty.spStlthTai & !Specialty.spThrwAero & !Specialty.spThrwGren & !Specialty.spThrwImpr & !Specialty.spWatrEvad & !Specialty.spWatrNav & !Specialty.spWatrPurs & !Specialty.spWatStnt & !Specialty.spWillFort & !Specialty.spWillTena & !Specialty.spXenoWrld", which is long, but looks to hit all of the points. Except, well, it's not working. Every Specialty shows up, including the ones that were excluded before. Am I running into a limit on how large the field can be? It still prints without being cut off in the debug window. Maybe a limit for using it for tag exclusion? If I manually input a value of about half of those, it does work, which is suggestive.

I suppose I could rewrite the code as being "here's the list of things you can pick," but then I have the opposite issue of someone with 1 in each skill having every non-picked specialty on the list.

Or is there perhaps a way to set up subsequent changer tables so that they pick a skill, and then pick a relevant Specialty, like how the character creation does it?

Where does the Advance go?
Right now, the specialty isn't showing up, presumably because it didn't get added to the relevant skill. Where does it get assigned to? The Gizmo? The Advance thing? I'm having little luck figuring it out via the documentation and the debug window, although I'm still plugging away.

----

I previously had a small issue with how to display Specialty values differently (since they're not specifically being brought up from the skills), but a look at the Savage World code provided a solution there.

Thank you.
 
I'm fairly certain for the latter, I need something with pushtags, or maybe pulltags, but I haven't quite figured out where yet.
 
I'm an idiot. That field explicitly sets a size limit of a 1000 characters, but that's 2,355 right there. Expanding the size creates a different error, where I'm getting picks that have nothing to do with Specialties, but I also haven't touched this code in a while, so this is likely a side effect from somewhere else.
 
And... not quite the idiot I thought I was. I expanded the field. It's still not working over a certain amount of characters. 990 characters goes through. I will keep experimenting to see what that upper limit is.
 
Last edited:
I'm sorry I haven't been able to give you much help recently, with so much to do for Starfinder, but the limit is 5000 characters, and this problem is why the <needtag> and <denytag> options were added to tables, because even at 5000 characters, you're eventually going to run into something that breaks that limit.
 
1058 doesn't work. Somewhere between 990 and 1012 is where it seems to ignore the entire tag expression. That's also the line between 43 and 44 conditions inside the expression if that makes a difference. I guess I have hit some sort of internal limit. I'll probably try a different approach tonight.

@Matthias: I figured something had drawn you away. No worries.
 
Incidentally, I found a partial solution. Because every Specialty is tagged with the skill it applies to, I was able to instead bar individual skills when there were no possibilities (which is the case when the number of ranks in the skill are not greater than the number of specialties the character has in that skill). Since most characters have many skills they have no ranks in, this will work for now, but I feel like this is bound to break again at some point.

Code:
<!-- Add Specialty advance -->
  <thing
    id="advSpec"
    name="Add Specialty"
    compset="Advance"
    description="Add a skill specialty">
    <fieldval field="advAction" value="Add Specialty"/>
    <fieldval field="advDynamic" value="component.Specialty & !Hide.Specialty"/>
    <tag group="Advance" tag="AddNew"/>
    <eval value="1" phase="Render" priority="1000">
      <before name="Assign Dynamic Tagexpr"/><![CDATA[
      ~get the list of all unique specialties on the hero and assemble it as a list of precluded tags
      debug "Assign Dynamic"
      var tagexpr as string
      foreach pick in hero where "component.Skill"
        var skillID as string
        var skillrank as number
        var speccount as number
        skillID = eachpick.idstring
        skillrank = eachpick.field[trtFinal].value
        speccount = eachpick.tagcount[User.HasSpec]

        if (speccount < skillrank) then
          foreach pick in eachpick.gizmo where "component.Specialty & !Hide.Specialty"
            ~ debug eachpick.idstring
            if (each.isunique <> 0) then
              tagexpr &= " & !Specialty." & each.idstring
            endif
          nexteach
        else
          tagexpr &= " & !Skill." & skillID
        endif
      nexteach
      ~ debug "Precluded: " & tagexpr
      
      ~if there are any tags to exclude, append them to the tagexpr appropriately
      if (empty(tagexpr) = 0) then
        field[advDynamic].text &= tagexpr
        debug "advDynamic: " & field[advDynamic].text
      endif
      ]]></eval>
<child entity="Advance">
<tag group="Advance" tag="MustChoose"/>
</child></thing>

Next step is to figure out if there's a nice way to define three independent skills for the "Advance 3 different skills by 1 point" Advance without having to define a custom portal for each.
 
I couldn't find a way to avoid the separate portals. *shrug* Small things. Now, to prevent the form from validating if the same skills are picked for two or more of the choices.
 
Would it not be simpler to just display the specialties, regardless of skill ranks, and use the validation rules to warn about insufficient skill ranks?
 
That's a possibility. I partly limited the list because otherwise it's just way too much.

I also got it to avoid allowing skill duplication.
 
That's a possibility. I partly limited the list because otherwise it's just way too much.

I also got it to avoid allowing skill duplication.

Not trying to be facetious here, because there are some things I still don't grasp very well, but can't you avoid skill duplication by designating each skill as "add once" or "is unique" or something like that?
 
Not trying to be facetious here, because there are some things I still don't grasp very well, but can't you avoid skill duplication by designating each skill as "add once" or "is unique" or something like that?

Ah, well, in this system, everyone has every skill at the start, just at 0 ranks. There's no such thing as a "Trained skill". The system for Advances is that, at the end of a successful job, every player chooses to either gain a new Skill Specialty, or to advance three different skills (two of which are supposed to be skills that they used) by one point each. Anyhow, because every skill chosen is a Pick on the Advance, I just modified the code so that it excluded any skill that already existed. So, when in the dialog, if you set two of the skill choices to Athletics and Xenobiology, the selection logic for the third one is "Skill.? & !skAthlete & !skXeno". ^_^ It works pretty well.
 
Ah, well, in this system, everyone has every skill at the start, just at 0 ranks. There's no such thing as a "Trained skill". The system for Advances is that, at the end of a successful job, every player chooses to either gain a new Skill Specialty, or to advance three different skills (two of which are supposed to be skills that they used) by one point each. Anyhow, because every skill chosen is a Pick on the Advance, I just modified the code so that it excluded any skill that already existed. So, when in the dialog, if you set two of the skill choices to Athletics and Xenobiology, the selection logic for the third one is "Skill.? & !skAthlete & !skXeno". ^_^ It works pretty well.

But you shouldn't have to do it that way ... I don't think. Unless we're talking past each other, which is quite possible. Regardez vous:

Code:
  <thing
    id="skCQC"
    name="Close Quarters Combat"
    compset="Skill"
    isunique="yes"
    description="\n\n{b}Source:{/b} Core Rulebook">
    <fieldval field="trtAbbrev" value="CQC"/>

    <!-- If this skill should be shown as an out-of-combat skill on the TacCon, assign this tag
    <tag group="DashTacCon" tag="NonCombat"/>
    -->

    <!-- Specify the attribute to which this skill is linked -->
    <link linkage="attribute" thing="trSta"/>
    </thing>

You see that line that says isunique="yes"? That means that the skill can only be picked one time. It can't be chosen multiple times. That should be all you need to prevent skill duplication.
 
Huh. I wasn't thinking of it that way. That said, it doesn't work for me because the skills were all marked as unique and, until I made the change to the selection logic, it was possible to select the same skill for multiple Choice boxes, adding multiple copies of the pick to the advance, and causing errors when you tried to remove one of them.
 
Huh. I wasn't thinking of it that way. That said, it doesn't work for me because the skills were all marked as unique and, until I made the change to the selection logic, it was possible to select the same skill for multiple Choice boxes, adding multiple copies of the pick to the advance, and causing errors when you tried to remove one of them.

Well, foo. I thought I had a working example of this, but I can't find it. So maybe I was just imagining things.
 
:) Ah, were you the other person working on something like this? I found a reference on the boards, with Mathias advising just making it a Validation thing, but I couldn't remember who it was, or which system.
 
:) Ah, were you the other person working on something like this? I found a reference on the boards, with Mathias advising just making it a Validation thing, but I couldn't remember who it was, or which system.

I have asked a question in the past where I've received that type of answer. I wasn't too keen on it at the time, but I realized it was the right answer. In general, it's less work, and it allows for instances where a GM might grant an exception to a rule, regardless of validation errors.
 
Back
Top