It looks like you're new here. If you want to get involved, click one of these buttons!
Set: att1 = 18 set: att1a = {1d7 - 1} set: att1b = {!{$att1} - {$att1a}} set: att2a = {1d7 - 1} set: att2b = {!{$att1b} - {$att2a}} set: att3a = [when] {$att2b} > 6 [do] {1d7 - 1} [else] {1d{$att2b}} [end] set: att3b = {!{$att2b} - {$att3a}} set: att4a = [when] {$att3b} > 6 [do] {1d7 - 1} [else] {1d{$att3b}} [end] set: att4b = {!{$att3b} - {$att4a}} set: att5a = [when] {$att4b} > 6 [do] {1d7 - 1} [else] {1d{$att4b}} [end] set: att5b = {!{$att4b} - {$att5a}} set: att6a = [when] {$att5b} > 0 [do] {$att5b} [else] 0 [end] Set: Str = {6 + {$att1a}} Set: Kno = {6 + {$att2a}} Set: Mec = {6 + {$att3a}} Set: Per = {6 + {$att4a}} Set: Dex = {6 + {$att5a}} Set: Tec = {6 + {$att6a}} # The following is just so I could total up the point usage and see it at a glance during my trials and errors. Set: att2 = {!{$att1} - {$att1a}} Set: att3 = {!{$att2} - {$att2a}} Set: att4 = {!{$att3} - {$att3a}} Set: att5 = {!{$att4} - {$att4a}} Set: att6 = {!{$att5} - {$att5a}}
Comments
You've got some pretty impressive code there; I think mostly you're getting stymied by the peculiarities of IPP, particularly that 1d0 does not equal zero. For some reason, it always equals one (for what it's worth, I only just now discovered this). Worse, after the 1d0 = 1 happens, your next $attXb will be negative. And 1d-1 is taken as 1d6-1!
I couldn't replicate the situation where one attribute was below minimum.
There is one logical error in your code. In the event that the first five rolls were low, $att6a -- which gets the final remainder -- could be quite a bit higher than than 6.
All that said, I've found that when doing semi-complex stuff like this, the best thing to do is to work the way IPP wants you to work, i.e. using tables. This code does what you're looking for: Hope that helps!
My logic error wasn't the remainder on that final variable, I knew I didn't have a way to cap it. My logic error was that I thought I would be able to come up with an answer on my own!
My problem is that I don't know what IPP can and can't really do, yet. I've had it for a few years, messed around with it pretty heavily for about six months (and got fair at using it), then life interrupted all of my gaming/hobby activities and I stepped away. Now that life has stabilized, I'm getting back into gaming and the prep work for it. So I'm having to relearn to the point I was at, and with any luck exceed it this time around. The help file is decent for doing the basics, but sometimes I'm kind of clueless what it's trying to say so trial and error has been my main tutor.
Again, thanks so much for the code!
This I understand. It sets my initial variables at 6.If I need to adjust for different racial mins/maxs I start with this and then modify the 18 below.
So the first table call out is for 18 times to increment a stat. They're random pulls and each one increments by 1 and doesn't display it (the ==), correct? It just does the internal math and holds it in place. What does the [@showstats] table call out do? And say I want a race that is typically smarter/stronger/technical/etc., I can weight the different items on the IncrementAStat table, right?
What part of this stops the progression at 6 for an individual attribute? How does it cap it?
And could you talk me through the actual syntax of {XXX=={{XXX}+1}}?
1 --- {Str=={{Str}+1}} --- is saying create/change some variable and do something on the right of the == but just hold it in place and not display it. I understand that from the help file but what does the "not display it" really mean. I don't understand that concept fully. If you don't want to display it, you just don't show it in a different table like ShowStats below, right?
2 --- {Str=={{Str}+1}} --- is the math expression or do something that is about to happen
3 --- {Str=={{Str}+1}} --- is the variable or table or item that you're doing whatever it is to to get the overal result in line 1.
Am I understanding that stuff correctly?
I understand this part, this displays the final results and gives me my sum total so I can rapidly verify.
One last observation, what happened to table: endtable:? I assume that it's what one of the other posts was talking about due to the IPP3 upgrade being more free with the language? So in this case, if there is a break in the rows the program assumes that the table is finished. That's why you put the \n& between Tec and Sum, right?
Right on. A single "=" would display the new value of the variable.
Just calls ShowStats, so I could verify that the code was working correctly.
That would work, although setting up a different IncrementAStat table for each race sounds really tedious. I'll be happy to help you look for alternative methods if you want to familiarize me with the system you're using.
Whoops! No part does; I completely forgot about that restriction. This code deals with that, although I suspect it will raise a few more questions:
Looks like you understand it perfectly!
You got it! I very rarely use EndTable anymore; it's handy when the stuff following a table isn't another table, which happens in my files during the creation process, but in the final product I don't think I use it at all.
I hate you. In a completely grateful, mind-blown way. I struggled for three days with that convoluted mess I initially posted.
Okay, I see where this is getting used in the next table.
Okay...I see the when/do/else/end...I understand that. Talk me through the rest, please.
We're creating an inline variable of stat (which is starting as a constant of the set:) and assigning a table call for one of the attributes and at the same time applying a conditional with the & symbol, correct?
It's checking if that inline variable already is equal to 12. If it is, then it's picking a different attribute from the GetStat table. Because of the earlier 18 calls of IncrementAStat, it's going to do this 18 times, giving me my total of 54 points spent.
Okay, most important question I'm going to ask. Where is a document that tells me how to do all of these combinations and shortcuts?!
Okay, please explain the "not display" part of the function. I understand the English of what it means, but what does it mean in IPP-language? I'm lost.
It may not be obvious at first blush, but IncrementAStat only has one selectable row in it. The "&"s let me break up that single row into several lines of text to improve readability.
Looking at each line:
Many parts of this syntax are worth noting:
[when]{Str}=12&
[when]10=12&
{Str=={{Str}+1}}
{Str=={10+1}}
{Str==11}
... which is just standard inline variable assignment.
Well I'll be! Within just hours of writing this, I reread the documentation and learned that I'm seriously over-bracing. Color-coding the line of code {{stat}=={{{stat}}+1}}:
First is {stat=='[@GetStat]'}, which is identical to the first line of IncrementAStat.
Next comes [@IncrementAStat], which just says "call IncrementAStat again".
(an aside on probability) If Str were 12, and IPP chose "Str" as the stat 10 times, the loop would still complete faster than humans can notice. And the chance of IPP choosing the same 1 out of 6 stats 10 times in a row is 1/6^10, a.k.a. "1 in 60,466,176", a.k.a "pretty unlikely".
Whew, ok, that got a little long, and sorry for boring the experts out there. Hopefully coders new to IPP will find some value in it.
Possibly you found your answer in my previous post. If not, consider this sample code:
This code assigns a value of 1 to 3 to variable roll, then uses roll as the die roll on the Animals table. Because the value of roll was assigned with double-equals, you don't see the value, so the results might look like:
mouse
cat
cat
dog
...
But! If you chose to just use a single equal sign, the new value of roll would be displayed immediately, right before the call to Animals. And you'd see results like this:
3mouse
2cat
2cat
1dog
...
As I maybe mentioned earlier, I almost never want this kind of result, and therefore almost never use single-equals for inline variable assignment.
Exactly what I needed. Now it's a "duh" moment for me. Crystal clear.
If we ever meet, I owe you a few beers!
Hey folks, resurrecting this because I need some assistance with it. I've moved on to more advanced interaction with different species in this generator. I've reached out to largando but someone else might have a solution also.
The problem I'm trying to solve is ultimately to put a variable cap on an attribute, based on both species and stat name.
As such, I have a prompt to specify species on the generator. For now, I have two to get it working, then I'll add more - human and wookiee. Select the species, it looks up a dictionary table to call a subtable roll for the species stats/sex/name/etc.
I have the minimums for each attribute working perfectly using largando's code above as part of this subtable roll.
The actual increment a stat portion I left separate and standalone of the species subtables (I'd like to move the species to external generators ultimately).
The capping portion of the code is the '12' in this code:
I need to turn the 12 into the two factor based variable I mentioned. I have two subtables in the Start table that run and don't display to set the variables through the rest of it - [@allnames][@{poolvar} IncrementAStat], this part seems to be the only way to get them to set if I keep them external to the generator.
For humans, the cap for an attribute is 12 points always. That was simple (hence the 12 in largando's original code). When you get into alien species, it can vary widely from as little as 7 in some cases to 18, in the same species. For instance, wookies have a max Str of 18 (6D) and Per of 7 (2D+1).
I don't know that I follow exactly haw you are calculating your values, but let's assume that you have calculated values for each attribute and they meet or exceed the racial minimum values. I'd have a table (for instance Table: StrMax) setup for each attribute and call it like this:
{Str={min({$Str},{[#{@Race} StrMax with {@Gender}})}}
I haven't run it to check the brackets, @'s, and $'s... but what it's doing is this: assuming you have already calculated and stored a value for Str, it is resetting Str to the lower value of either what you have calculated, or the maximin allowed value for the race-gender combination. To have it lookup that race-gender combo max Strength value, have a table for each attribute that looks something like this (and you can easily add more races to the table as time goes on):
Table: StrMax
Type: Dictionary
Human: 12
Wookie: [when] {$1}="male" [do] 18 [else] 16 [end]
So here, we're looking up Race in the dictionary table AND passing the value Gender into the table as {$1}. This is in case, for instance, a male wookie is allowed up to an 18 Str, but a female wookie is only allowed a 16 Str as a max value.
(Ha! I'm assuming that wookies have binary gender and females are less strong than males. How boomer of me!)
So, for instance, if you calculated the female wookie's strength as 22 (somehow... with you other bits of complicated code above), then it would compare the lookup max of 16 with the calculated 22 and set Str to the lowest of the two: 16. If the calculated value is 13, then it would set it to lowest of 13 or 16: 13.
Hope I understand the question correctly and that this helps a bit.
Thanks for replying levendor.
I'll try to help you understand the calculations. The old West End Games Star Wars uses d6 dice codes for all attributes and skills. Most species have 12D to divide amongst 6 attributes as a NPC and then "special" NPCs (or if the species gets picked by a player for a PC) get to add 6D for a total of 18D divided amongst the six attributes. Each 1D breaks down into 3 pips (+1, +1, +1 or +1, +2). A +3 would just go to the next full die, example 3D+3 is just 4D.
IPP and numbercrunchers like Excel don't exactly like 2D+1 and 3D+2, etc. So I made the math easy. So I took the 3 pips/dice and just renamed them "points"/"steps". It's essentially a point-buy character system. Now IPP can math it's heart out. Multiply 12D and 6D by 3 each and we get 54 points total for character generation. Then I just take whatever number gets mathed and do a [#{mathednumber} table call] for the dice code to look pretty.
Largando's code randomly increments the attributes for me to a maximum of 54 points. Hard-coded in is a second, individual attribute cap of 12 points (4D), which is the maximum for all humans. Like I said, now I want to go further with it and have different maximums for different species.
So that's what I'm trying to accomplish - 54 points get used total, but different attributes don't exceed their specific maximums also. The 12 in the quoted code needs to be a variable based on whatever gets passed to {stat}. I created the attribute max dictionary tables and tried to merge your two codes -
It hasn't worked for me yet and I think it's because I changed your code from StrMax to {stat}Max to try and get whatever is being set from the stat==GetStat call at the start of the line. If I don't do that though, I can't figure out how to increment correctly. Maybe I need to create six individual Increment tables and have them called separately, IncrementStr, IncrementDex, etc.
Sidenote:
As I've thought about it the last couple of days, I don't think I need to concern myself with an external generator for racial attributes. I've been on a big external generator kick lately for commonality across NPCs from different settings (but I really use the GURPS system for them all), mainly so I'm not opening up 15 different files and adding whatever new additions/changes I'm making. But this system is unique so I think I'm going to stop worrying about that aspect.
Maybe a bit closer now. I don't think I changed too much in this version. Biggest change - of course - is that call in Table: IncrementAStat. But before we get there:
I added a Set: KnowMax = 5 to swwookiemale (and =6 to female wookie). This is arbitrary for testing, of course. You should go to each table and set all 6 attribute max values in the same way (unless there are no limits for a particular stat). I also moved set race and set gender to the top of the table (wanted those set immediately, but later realized there was no reason to move them).
So back to Table: IncrementAStat... simply put, every time you enter this table, it selects a random stat (as you know... you wrote that part). Then a pretty simple [when] [do]. I'll write it here in simple syntax, and let's assume that [@getstat] returned 'Kno' for our random stat.
[when] {Kno} < {$KnoMax} [do] {Kno={{$Kno}+1}}[else] [@IncrementAStat] [end]
So, as long as the knowledge max has not yet been reached, it adds 1 to knowledge. If not it runs the increment routine again, selecting a new random attribute at the start of the rerun. Now the rerun doesn't count against your point pool because the rerun is being called by IncrementAStat itself, and it loops until it adds a point to some attribute that is not maxed out. Only then does it do another draw from [@{poolvar} IncrementAStat] command in Table:Start. (at least that's what I think... that may be the next thing we work on if I'm wrong.)
And the real code below just replaces the three characters Kno with the six characters {stat} so that it works for every attribute.
Here's the code:
Thanks, Levendor! I plugged it in and ran about 30 iterations. So far it seems like it's working. I think you solved my problem. Thank you!