View unanswered posts | View active topics It is currently Thu Mar 28, 2024 8:20 am



Post new topic Reply to topic  [ 8 posts ] 
 A few questions (Nodes, creating Dieroller, Python) 
Author Message

Joined: Fri Jun 25, 2010 12:54 am
Posts: 18
Post A few questions (Nodes, creating Dieroller, Python)
Hello again,

I have a few more Questions (for Traipse):
1) When making Nodes it is possible to call die-roller, use placeholders for other parts of the gametree as variables und even make a limited "dialogue" system using the ? in your strings.
My question now is: Are simple control-Strukutres such as if...else useable? Or is this, as I suppose, only possible by using real python code?

2)I want to make a Dieroller for a relative new RPG: Nova (since the Material is only availible in german right now, I doubt you know it).
The Basic Dieroller isn't the problem (I can use a slightly modified d20). The problem is all the things the dieroller "could" caculate while he is trowing.
I.e. the game mechanics use a psychical energie (PE; how much stress your character can sustain). When the stresslevel set by the gm is above your relevant atribute, you start losing PE with every single throw (equal to the difference). Even this part would require 2 aditional variables to be given to the dieroller (using a selfwirtten option like .dc/.minroll/.extra).
It is even worser when I would try to implement optional Modules like the one that gives you a malus when you are hurt/stressed (one bool to see if the module is used, both actual and lost HP and PE). And this has to be called everytime a throw is made from a prepared node. Also the information for the option doesn't change: If you are making a attack (skill-)throw or a skillthrow to repair something - stress and injury affects every throw the same way. Small exception is the initiative, but this one exra node is acceptible.

I can think of some ways to do this and would like your opinion on each one (posibility, feasibility and good programming style). Ecept for c) and d), it's only about printing out what hapened beside the throw-result/what modified it:
a) "One Node to throw all this". In this concept throws from the nodes (mostly skillthrows; a normal "3d6+3" dieroller-string) don't go to the "real" roller. Instead it goes to one Node that contains the bulk of the complex dieroller-string and the main part of the roll is placed in the complex formula.
Something like "Attack with Laser ("Pew-Pew"): [3d6-2]" is rolled as "Attack with Laser ("Pew-Pew"): [3d6-2.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]".
Advantages: Easy to implement in the charsheets. Still relatively easy to upgarde (the skillroll needs no update, only one node to change).
b) "Extracting Nodes-Values in Python code" In this idea I just call the the dieroller normaly ([3d6-3]), but the unchanging values are extracted by the python code from the nodes without need to give them as arguments.
Possible Problems: Identifying the right charsheet, when more than one is loaded.
c) "Write back" Nothing I would try to implement from the start. For example when a roll is made and PE is lost, the new loss is added to the current loss so that the PE is always up to date.
d) "Less Variables with more variables": Best shown as an example: In the Grid where I store the currentStresslevel and the maxStresslevel I also store the difference between them (which is the effective loss of PE per throw). The same goes for Injury so I only have three additional variables instead of Seven per throw (strongly shortening the dieroller calls).
Disadvantages: I need at least one "CheckModifiers" python-function and a node to call it with all necessary variables to know if the Modifiers are set acording to the rules.
When combined with c), the setting of the new modifiers (if any) could be done automatically when the new values are stored.

3)Could a python code, added by a plugin, check incomming chat-messages for certain strings and react to them? Or would this require modification of some core files (could be usefull for an advanced Nova initiative-tool, even though easier ways are possible).

4)How known must a game be, to have "its" dieroller added to OpenRPG/Traipse. Or do you just take everything as long as someone writes it. Or to be more specefic: Would you implement a Nova Dieroller when it is finished or would I have to realize it as a Plugin?

About my Python skills: I have read through "A byte of python" to the point where classes are explained, but I already know the basics of classes and GUI/CLI from C++, so you can use some technical jargon in answers.


Sun Aug 22, 2010 10:29 am
Profile
User avatar

Joined: Wed Dec 09, 2009 9:39 pm
Posts: 712
Post Re: A few questions (Nodes, creating Dieroller, Python)
1) Not yet. This is one reason why I moved all of the gametree reference material to InterParse and it is half of the name InterParse. (Interpretor Parser) SO while planned, at the moment there is no language that allows that.

2) I am not sure what you are asking.

3) Yes. In the plugin_incoming_msg function

4) To get into Traipse? If you give me a dieroller code I will look over it, make any changes I feel are needed by the software, and add it. If you want me to code one you can, but as I am pretty swamped right now I would ask you to fill out a premium support ticket.

_________________
I ate your Death Knell.
The Traipse Movement
Please show your support for Traipse OpenRPG http://www.facebook.com/MadMathLabs
Send me Traipse OpenRPG Ideas, Bugs, Complaints, Praises here: https://getsatisfaction.com/mml


Sun Aug 22, 2010 4:38 pm
Profile YIM WWW

Joined: Thu Dec 10, 2009 6:37 am
Posts: 335
Post Re: A few questions (Nodes, creating Dieroller, Python)
Quote:
Are simple control-Strukutres such as if...else useable?


Hmm. I think I put some simple ones in. The dieroller works on an eval but accepts only limited format text so reducing hack potential. But I think there might be a triple operator usable there. Hm. What conditional do you want to apply? I thought there was something else but it might have been unimplemented.

Quote:
Instead it goes to one Node that contains the bulk of the complex dieroller-string and the main part of the roll is placed in the complex formula.
Something like "Attack with Laser ("Pew-Pew"): [3d6-2]" is rolled as "Attack with Laser ("Pew-Pew"): [3d6-2.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]".


Sounds best as it doesn't involve the die roller having to mess with the tree/nodes. The die rollers are all currently string manipulation functions. String in, string out. Basically they are a text manipulation of chat strings. But is it possible to get your problem solved that way? It seems like you want more than one output here. Both the die roll results and some manipulation of the node.

Quote:
Could a python code, added by a plugin, check incomming chat-messages for certain strings and react to them?


Yes. Standard hooks are there for that. Hmm. An example would be.... hmm. I'd have to look that up. The example plugin has an example of a lot but maybe not that, although it probably does have the function named.

Quote:
How known must a game be, to have "its" dieroller added to OpenRPG/Traipse.


There was talk but I don't think it was done, of making the dierollers work like plugins so you just add the file in the right directory and it's suddenly callable. If that's not happened then certainly adding it using code is simple and if the die roller works and you're willing to give up the code to the GNU license then it can be checked in.

---------------------

I will have to think more about these questions.


Tue Aug 24, 2010 8:31 pm
Profile

Joined: Thu Dec 10, 2009 6:37 am
Posts: 335
Post Re: A few questions (Nodes, creating Dieroller, Python)
I was considering an if...else... thing but in the end -- so far at least -- I've found that implementing min(x,y) and max(x,y) works for my purposes. This was enabled at the level of evaluating a node contents value when fetching it by a reference. For example in my D&D sheet I have this calcualtion for "Dodge":

Code:
min(!@MaxDex@!,!@Dex_Base@!)


MaxDex is the maximum dexterity permitted by the armor worn and Dex_Base is the base dexterity bonus. The Dodge bonus to AC is whichever is the least of those two. This is instead of saying something like,

Code:
if Dex_Base > MaxDex:
    Dodge = MaxDex;
else:
    Dodge = Dex_Base;


Or whatever. So it wasn't implemented in the dieroller, and it wasn't a triple operator and even this I think only works with the dev version of OpenRPG -- 1.8.1.0 I think. You can get it through the updater which you can call up with /update from the chat if it doesn't come up as you start up OpenRPG.


Wed Aug 25, 2010 12:29 am
Profile

Joined: Thu Dec 10, 2009 6:37 am
Posts: 335
Post Re: A few questions (Nodes, creating Dieroller, Python)
Hmm. Now I think of it there might have been a ternary operator added -- the new Python one, as in

Code:
x = a if b else c


I know I had to calculate the size bonus to AC given the size "number" and that would need a conditional I think. I'll check.

{-4,-3,-2,-1,0, 1, 2, 3, 4} to {8, 4, 2, 1, 0, -1, -2, -4, -8}

I think it was something like "(-1*!@size@!) if !@size@!^2 <=4 else (-4*(!@size@!-2))"

That would be the text in a text or grid node somewhere and it is evaluated as a number when the node is fetched as a reference from elsewhere. Something like that.


Wed Aug 25, 2010 5:43 pm
Profile

Joined: Fri Jun 25, 2010 12:54 am
Posts: 18
Post Re: A few questions (Nodes, creating Dieroller, Python)
to 1) Like I said, I already feared something like that. No stable way to do this outside of of real python code. Well, no mayor hinderance for now.

to 2) I try to make it a littlebit clearer
a) I think something like this would work:
My example optimal string: "[3d6-2.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]"
Node "Roller" contains the string: ".stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]"
And the Skill-Rolls are done using a string such as: "Athletics [3d-2!=Roller=!".
There are better ways to do this, but at least it's a begining and much easier than my other ideas.
All that the roller has to do is print out in this version is something like "your roll is ???. \nYou lost X PE due to stress\nYou had a malus of -4 due to injury and stress". It's more a reminder to not forget the PE loss (happens a lot). Perhaps saying "by the way, you are down to zero now, so don't forget to make the sanity check"

b) was an alternative to a) and the question I wanted to ask: "Can I take the value of a node in the gametree, from inside a python function?". My Idea was to to just write a dieroller Nova that would be called normal ([3d6+2]) and it would just retrieve the PE, the Stress, the HP, the damage and all those other variables from the gametree without having to give it as an argument. So that a said "[3d6+2]" would do the same as: "[3d6-2.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]" without this long list of arguments.

c)This is a extension of b: Instead of just taking the values from the gametree, the function would also change them. i.E. not just printing out "you lost 2 PE" but actually setting !&Charsheet::Energies::LostPE&! to the retrieved value+2.

d)This a littlebit different thinking. Instead of using ".stress(int currentStresslevel, int maxStresslevel)" I would use a grid "PE" (1x3 or 3x1) containing Curent HP, Lost HP and the modifier you get for those losses. So I only have to give the Modifier instead of the two other values.
Of course, the GM has to call for players to run a check function to see if all the values are set corretly. i.E. "PE loss should be 4, but is set to 4" and "Not using the wounding module" or "using Wounding Module and wounding modifiers are correct (-0 currently)".

f)An alternative to c just crossed my mind:
[3d6-2] with the nova-dieroller would not make a roll at all. Instead it would put out the string "[3d6-2.realRoll.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]" that would then be interpreted as the "Real" dieroller call. But I would not try to put this in the main dieroller - an Alternative version perhaps.

Like I said, b-f are just faster ways to do the excalty same thing as a). Basically a way to hide all this stuff in a simlpe [3d5-2], that is easier to use than this long string I used so often in this post. Of course all of these ideas might not work when you have more than one Charakter-Sheet in your gametree - like when you are a GM.

to 3)Actually I didn't hoped for this to be possible, but it is a good thing I asked. This enables a way to make nearly automated rule using possible, but not without making the charsheet as a plugin and storing the values in the plugin instead of the gametree. Just imagine a session running like this:
GM makes the attackroll for a creeper aginst a player, and it succseds. Prints the results to the chat and waits for player response.
Players-Client detects "My char is under attack" and waits for the player to choose a defense, then makes the throw
GM's Client detects: "Defense throw was made, compare it to the attack". If sucessfull, roll damage.
Player Client's detects: "I'm hit, oh the pain", reduces the the current HP (not forgeting protection) and makes other apropirate checks (ist there a roll to make due to the amount of damage?, is the char unconcius now?, what about wounding modifiers?).
But thats just daydreaming. The amount of scripting nessesary for doing this would be suficcient to make your own fork - for each game system. And just making variant 2a will keep me busy for a while.


Thu Aug 26, 2010 8:38 pm
Profile

Joined: Thu Dec 10, 2009 6:37 am
Posts: 335
Post Re: A few questions (Nodes, creating Dieroller, Python)
Christopher wrote:
Can I take the value of a node in the gametree, from inside a python function?


Certainly it is possible. The whole gametree is accessible anywhere in the code. You'd need to identify the right node in the case of several character sheets. I recently added the concept of a context to the chat parser that knows which PC sheet it is "in". But that information is not given to the die roller currently. It is given to all the slash commands (/commands) and the reference parser (that translates the !@foobar@! stuff). Of course if you only had one PC sheet you don't need that.

For option (c) the dieroller can access the nodes to set their values as easily as reading them. Saldy it wouldn't be able to just type out /commands such as "/setnodevalue PE 10" or whatever because the chat parser replaces all the /commands and the references and then after that considers the dieroller.... at least I think it does. But you can still access the nodes directly.

OpenRPG 1.8.1 still doesn't allow for direct references of all colums within a grid but just the main column though Traipse can do that. I haven't added it because every time AI think I find a use for it I figure I can do it better without grid references.

Quote:
f)An alternative to c just crossed my mind:
[3d6-2] with the nova-dieroller would not make a roll at all. Instead it would put out the string "[3d6-2.realRoll.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]" that would then be interpreted as the "Real" dieroller call. But I would not try to put this in the main dieroller - an Alternative version perhaps.


"[3d6-2!@stress_modifier_string@!]" perhaps? where "stress_modifier_string" is the name of a node which contains, ".stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)" or whatever (those variables would be references and look like eg. !@currentStressLevel@!). That way if you have to modify the formula it happens in just one palce.

Quote:
Of course all of these ideas might not work when you have more than one Character-Sheet in your gametree - like when you are a GM.


Just the stuff my recent updates have been trying to address. It may be that the chat parser context object can be passed to the die roller. Then any die roller could extract what PC is requesting the die roll (if any). Traipse now does something similar with reference parsing (the !@foobar@! stuff) but not with parsing /command stuff. Not that many /commands use it. The /input command does. The context carries a list of the whole multi-line chat which it uses to substitute. And /bonus will extract the player's name so it knows who to give a bonus to.

Code:
/bonus _dexterity 4


would add 4 to dexterity. Alternatively you could specify,

Code:
/bonus Inigo::_dexterity 4


but that is not necessary if the context is Inigo's PC. Either because the text issued from a node inside his sheet or because it came from the chat text box while Inigo's alias was selected or ... there are other ways.

Quote:
GM makes the attackroll for a creeper aginst a player, and it succseds. Prints the results to the chat and waits for player response.
Players-Client detects "My char is under attack" and waits for the player to choose a defense, then makes the throw
GM's Client detects: "Defense throw was made, compare it to the attack". If sucessfull, roll damage.
Player Client's detects: "I'm hit, oh the pain", reduces the the current HP (not forgeting protection) and makes other apropirate checks (ist there a roll to make due to the amount of damage?, is the char unconcius now?, what about wounding modifiers?).
But thats just daydreaming. The amount of scripting nessesary for doing this would be suficcient to make your own fork - for each game system. And just making variant 2a will keep me busy for a while.


Any game with a lot of back and forth has a harder problem when you are not face to face. On option is to handle the back and forth through chat. In D&D Grapple is almost as complex. The attacker rolls their Grapple check, then the defender rolls their opposed grapple check (or they might elect for an escape artist check). GM compares both rolls and announces the result which may then mean rolling some damage....

But grapple isn't that often. Typical attacks involve an attack roll and damage and the habit is to roll both at once to save time. Instead of "roll attack' then wait for DM / player to say if it hit their AC and then follow up with damage roll the damage roll is rolled ahead of and in anticipation of a success. Just saves a little time.

Now if you wanted to you could program something more complicated as a plugin. The example plugin covers the idea of a messaging system -- a custom message. You can send data to and from the clients. You could write a plugin that pops up a dialog prompt for the attack roll details, closes, sends a message to the other guys, pops up a dialog on their machine saying "you were attacked so now you need to roll defence" etc etc and ends up sending a string to chat (which appears at all clients of course) detailing all the back and forth.


Thu Aug 26, 2010 10:16 pm
Profile

Joined: Thu Dec 10, 2009 6:37 am
Posts: 335
Post Re: A few questions (Nodes, creating Dieroller, Python)
davidbyron wrote:
Christopher wrote:
Can I take the value of a node in the gametree, from inside a python function?


Certainly it is possible. The whole gametree is accessible anywhere in the code. You'd need to identify the right node in the case of several character sheets. I recently added the concept of a context to the chat parser that knows which PC sheet it is "in". But that information is not given to the die roller currently. It is given to all the slash commands (/commands) and the reference parser (that translates the !@foobar@! stuff). Of course if you only had one PC sheet you don't need that.

For option (c) the dieroller can access the nodes to set their values as easily as reading them. Saldy it wouldn't be able to just type out /commands such as "/setnodevalue PE 10" or whatever because the chat parser replaces all the /commands and the references and then after that considers the dieroller.... at least I think it does. But you can still access the nodes directly.

OpenRPG 1.8.1 still doesn't allow for direct references of all colums within a grid but just the main column though Traipse can do that. I haven't added it because every time AI think I find a use for it I figure I can do it better without grid references.

Quote:
f)An alternative to c just crossed my mind:
[3d6-2] with the nova-dieroller would not make a roll at all. Instead it would put out the string "[3d6-2.realRoll.stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)]" that would then be interpreted as the "Real" dieroller call. But I would not try to put this in the main dieroller - an Alternative version perhaps.


"[3d6-2!@stress_modifier_string@!]" perhaps? where "stress_modifier_string" is the name of a node which contains, ".stress(int currentStresslevel, int maxStresslevel).injury(bool ModuleIsUsed, int maxHP, int lostHP, int maxPE, int lostPE)" or whatever (those variables would be references and look like eg. !@currentStressLevel@!). That way if you have to modify the formula it happens in just one palce.

Quote:
Of course all of these ideas might not work when you have more than one Character-Sheet in your gametree - like when you are a GM.


Just the stuff my recent updates have been trying to address. It may be that the chat parser context object can be passed to the die roller. Then any die roller could extract what PC is requesting the die roll (if any). Traipse now does something similar with reference parsing (the !@foobar@! stuff) but not with parsing /command stuff. Not that many /commands use it. The /input command does. The context carries a list of the whole multi-line chat which it uses to substitute. And /bonus will extract the player's name so it knows who to give a bonus to.

Code:
/bonus _dexterity 4


would add 4 to dexterity. Alternatively you could specify,

Code:
/bonus Inigo::_dexterity 4


but that is not necessary if the context is Inigo's PC. Either because the text issued from a node inside his sheet or because it came from the chat text box while Inigo's alias was selected or ... there are other ways.

Quote:
GM makes the attackroll for a creeper aginst a player, and it succseds. Prints the results to the chat and waits for player response.
Players-Client detects "My char is under attack" and waits for the player to choose a defense, then makes the throw
GM's Client detects: "Defense throw was made, compare it to the attack". If sucessfull, roll damage.
Player Client's detects: "I'm hit, oh the pain", reduces the the current HP (not forgeting protection) and makes other apropirate checks (ist there a roll to make due to the amount of damage?, is the char unconcius now?, what about wounding modifiers?).
But thats just daydreaming. The amount of scripting nessesary for doing this would be suficcient to make your own fork - for each game system. And just making variant 2a will keep me busy for a while.


Any game with a lot of back and forth has a harder problem when you are not face to face. On option is to handle the back and forth through chat. In D&D Grapple is almost as complex. The attacker rolls their Grapple check, then the defender rolls their opposed grapple check (or they might elect for an escape artist check). GM compares both rolls and announces the result which may then mean rolling some damage....

But grapple isn't that often. Typical attacks involve an attack roll and damage and the habit is to roll both at once to save time. Instead of "roll attack' then wait for DM / player to say if it hit their AC and then follow up with damage roll the damage roll is rolled ahead of and in anticipation of a success. Just saves a little time.

Now if you wanted to you could program something more complicated as a plugin. The example plugin covers the idea of a messaging system -- a custom message. You can send data to and from the clients. You could write a plugin that pops up a dialog prompt for the attack roll details, closes, sends a message to the other guys, pops up a dialog on their machine saying "you were attacked so now you need to roll defence" etc etc and ends up sending a string to chat (which appears at all clients of course) detailing all the back and forth. The messaging is the tough part and that's all done for you. Well, except parsing the string sent. That structure is 100% up to you. XML maybe? Simple space delimited string? You are carrying several pieces of data. Then you'd just need the code which says, "OK you just got this kind of message, so do this".


Thu Aug 26, 2010 10:19 pm
Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 


Who is online

Users browsing this forum: No registered users and 24 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.