Statistics was both the most boring and the most useful class I ever took.
Anyway good news on the parser front, I was able to work on it for like, almost 45 min today! Woo.
I've fully defined the BNF grammar for it, and finally compiled Irony and looked through a bit of documentation.
Tomorrow will be heavy development actually translating BNF into the C# that Irony needs.
Wed will be trying to figure out how to attach rules to nonterminals.
Thurs will be crying because I'm pretty sure I need to change the engine some more to support the parser commands I want to add.
Friday will be "release" totally, yea, definitely going to happen. Yep.
That does seem to be where its documentation falls silent... so here, I saved you a few minutes of research. Or maybe an hour depending on how red-herring prone you are.
The short version: you are supposed to use the AST it comes up with.
I am willing to help with Bard simulations.
Hah, what a great language.
Thank you for the research. I'll work on it more today and see if it won't be too hard to get at least a parser going.
Junified, the most useful stuff I need is animation delays. Without that data pretty much every oGCD class is going to have a flawed sim. It isn't too necessary to be exactly precise, but we need to be precise enough that if someone is trying to stuff 2 oGCDs into a GCD that it will delay their next attack some.
So basically I need the animations delays of every ability, GCD and oGCD.
At some point we also need updated damage formulas but that is really grindy afk work so maybe talk to Dervy or Viridiana.
Yep.
So basically each crit rating gives between 0.0001977 and 0.0001749 crit (avg 0.0001863). This is pretty huge variance.
What you really want is to be able to discriminate between 657 rating and 658 rating.
To do that, you need a variance less than the avg rating diff, which 0.0001863. Which means you need something on the order of 10 million trials =DDDDDD
EDIT: oops I hit my post cap.
So here is the grammar right now. Its kinda really ugly? I'm going to have to see if it has any conflicts (probably)...maybe I can get an intern to do this for me.
Here is the FFscript grammar.
Its really bad right now. I need to resolve a lot of conflicts before it can be used, and I'm lazy.
Maybe I can get a college intern to do it for me.
Code:* script :== setup precast gcd ogcd * setup :== "[SETUP]" setupStatements * setupStatements :== setupStatement setupStatements | . * setupStatement :== actorAdd | varAssign * actorAdd :== actorList "+=" string * actorList :== "players" | "targets" * varAssign :== var "=" val * var :== string varb * varb :== "." string varb | . * val :== number | string * precast :== "[PRECAST]" actionStatements * gcd :== "[GCD]" actionStatements * ogcd :== "[OGCD]" actionStatements * actionStatements :== actionStatement actionStatements | . * actionStatement :== "(" conditionals ")" "{" actions "}" * conditionals :== conditional conditionalb | . * conditionalb :== "&" conditional conditionalb | . * conditional :== boolVar test number | "!" boolVar | boolVar * boolVar :== string boolVarb * boolVarb :== "." string boolVarb | . * test :== ">" | "<" | ">=" | "<=" | "==" | "!=" * actions :== string actionb | . * actionb :== "," string actionb | .
Last edited by pandabearcat; 06-24-2015 at 12:20 AM.
/hate
Well, I guess I can leave my comp on overnight. Bleh. Good news is that IR doesn't seem to affect the crit damage range, which is basically what we expected. Which is good because I somehow got it in my head that a buffed Sneak Attack would give really accurate numbers on how much it boosts crit damage. . .
Whee, the grammar works.
I opted for grammar simplicity and to do more of the semantic work in the backend, instead of trying to parse specific keywords.
As far as I can tell the grammar is correct. Next step is the semantic parsing and attaching actions to nonterminals.
Here is the full grammar:
Here is a sample DRG rotation, not optimal, but it works.Code:actionb (Nullable) actionb -> , string actionb actionb -> actions (Nullable) actions -> string actionb actions -> actionStatement actionStatement -> ( conditionals ) { actions } actionStatement -> comment actionStatement+ actionStatement+ -> actionStatement+ actionStatement actionStatement+ -> actionStatement actionStatements (Nullable) actionStatements -> actionStatements -> actionStatement+ actorAdd actorAdd -> actorList += string actorList actorList -> *players actorList -> *targets boolVar boolVar -> string boolVarb boolVarb (Nullable) boolVarb -> . string boolVarb boolVarb -> conditional conditional -> boolVar test number conditional -> ! boolVar conditional -> boolVar conditionalb (Nullable) conditionalb -> & conditional conditionalb conditionalb -> conditionals (Nullable) conditionals -> conditional conditionalb conditionals -> gcd gcd -> [GCD] actionStatements ogcd ogcd -> [OGCD] actionStatements precast precast -> [PRECAST] actionStatements script script -> setup precast gcd ogcd script' script' -> script EOF setup setup -> [SETUP] setupStatements setupStatement setupStatement -> actorAdd setupStatement -> varAssign setupStatement -> comment setupStatement+ setupStatement+ -> setupStatement+ setupStatement setupStatement+ -> setupStatement setupStatements (Nullable) setupStatements -> setupStatements -> setupStatement+ test test -> == test -> != test -> < test -> > test -> <= test -> >= val val -> number val -> string val -> stringLit var var -> string varb varAssign varAssign -> var = val varb (Nullable) varb -> . string varb varb ->
Code:[SETUP] #sets up an alias for our player *players+=p1 #sets up an alias for our target *targets+=t1 #load skills and traits p1.class=drg # setup attributes # nonlisted attributes are assumed to be 0 p1.attr.str=500 p1.attr.dex=200 p1.attr.sks=400 # setup server variables sim.duration=600 # execute is duration from end of sim sim.execute=200 # setup diagnostic or no - diagnostic runs 1 run with log output, for testing your rotation sim.diagnostic=true # otherwise setup sim trials sim.trials=10000 # i/o sim.output="./output.txt" [PRECAST] # place a sequential list of ogcd/gcd actions here # any action that is offensive will begin the sim timer # however, you may place as many actions as you like # if you have a set opener rotation you wish to follow, enter it here # and the [GCD] actionlists will follow once the action queue is complete (){x_potion,blood_for_blood,heavy_thrust} [GCD] # remaining is set to 0 if an aura does not exist # you do not need to test for both exists and remaining # if an action is in the queue, no further actions will be run # if a condition is satisfied, the sim will attempt to cast the action # if an action succeeds, no further actions will be run until the queue is empty # the only supported boolean operator is & # to do | actions, use multiple action lines (p1.aura.heavy_thrust.remaining<5.0){heavy_thrust} (t1.aura.chaos_thrust.remaining<12.0){impulse_drive,disembowel,chaos_thrust} (t1.aura.phlebotomize<5.0){phlebotomize} (){true_thrust,vorpal_thrust,full_thrust} [OGCD] # you'll need this unless you want to constantly clip GCDs # actionlist execution stops as soon as a successful action is entered # blank actions are automatically successful # be very careful queueing oGCDs. They will automatically be run in sequence, without regard for clipping into a gcd (p1.nextgcd<1.0){} (){blood_for_blood} (p1.nextaction==full_thrust){life_surge} (!p1.cd.jump){power_surge} (){jump} (){dragonfire_dive} (){leg_sweep}
Last edited by pandabearcat; 06-24-2015 at 02:04 AM.
Updated the grammar today. I realized I was trying to be too "generic" and ended up writing a kind of lazy grammar that is technically very extensible, but put too much work into the backend semantic parsing.
I rewrote the grammar to be much longer and restrictive, which allows me to also write the backend quicker (once I figure out how...).
The new grammar also supports multiple actors, which hilariously the sim only half-supports (it doesn't support multiple stacks of the same aura, nor does it support cross class buffs). Oh well. At least the future looks bright.
Irony's documentation sucks. I need to figure out how to overwrite the AST actions.
New grammar:
New sample script:Code:action action -> string actionBlock actionBlock -> precast actionBlock -> gcd actionBlock -> ogcd actionBlock+ actionBlock+ -> actionBlock+ actionBlock actionBlock+ -> actionBlock actionBlocks (Nullable) actionBlocks -> actionBlocks -> actionBlock+ actions (Nullable) actions -> action actions -> action , actions actions -> actionStatement actionStatement -> ( conditionals ) { actions } actionStatement -> comment actionStatement+ actionStatement+ -> actionStatement+ actionStatement actionStatement+ -> actionStatement actionStatements (Nullable) actionStatements -> actionStatements -> actionStatement+ actionVar actionVar -> nextaction actorListStatement actorListStatement -> playersAdd actorListStatement -> targetsAdd actorStatement actorStatement -> actor . actorVar = val actorVar actorVar -> class actorVar -> attrVar actorVar -> autoattack actorVar -> auraVar actorVar -> gcdVar actorVar -> cdVar actorVar -> actionVar attribute attribute -> str attribute -> dex attribute -> sks attribute -> det attribute -> chr attrVar attrVar -> attr . attribute auraVar auraVar -> aura . string . remaining auraVar -> aura . string boolVar boolVar -> actor . actorVar boolVar -> sim . simVar cdVar cdVar -> cd . string conditional conditional -> boolVar conditional -> notBoolVar conditional -> testVar conditionals (Nullable) conditionals -> conditional conditionals -> conditional & conditionals conditionals -> gcd gcd -> [ actor . GCD ] actionStatements gcdVar gcdVar -> lastgcd gcdVar -> nextgcd notBoolVar notBoolVar -> ! boolVar ogcd ogcd -> [ actor . OGCD ] actionStatements playersAdd playersAdd -> *players+= actor precast precast -> [ actor . PRECAST ] actionStatements script script -> setup actionBlocks script' script' -> script EOF setup setup -> [SETUP] setupStatements setupStatement setupStatement -> actorStatement setupStatement -> actorListStatement setupStatement -> simStatement setupStatement -> comment setupStatement+ setupStatement+ -> setupStatement+ setupStatement setupStatement+ -> setupStatement setupStatements (Nullable) setupStatements -> setupStatements -> setupStatement+ simStatement simStatement -> sim . simVar = val simVar simVar -> duration simVar -> execute simVar -> diagnostic simVar -> trials simVar -> output targetsAdd targetsAdd -> *targets+= actor test test -> == test -> != test -> < test -> <= test -> > test -> >= testVar testVar -> boolVar test val val val -> boolean val -> number val -> string val -> stringLit
Code:[SETUP] #sets up an alias for our player *players+=p1 #sets up an alias for our target *targets+=t1 #load skills and traits p1.class = drg # setup attributes # nonlisted attributes are assumed to be 0 p1.attr.str=500 p1.attr.dex=200 p1.attr.sks=400 # setup server variables sim.duration=600 # execute is duration from end of sim sim.execute=200 # setup diagnostic or no - diagnostic runs 1 run with log output, for testing your rotation sim.diagnostic=true # otherwise setup sim trials sim.trials=10000 # i/o sim.output="./output.txt" [p1.PRECAST] # place a sequential list of ogcd/gcd actions here # any action that is offensive will begin the sim timer # however, you may place as many actions as you like # if you have a set opener rotation you wish to follow, enter it here # and the [GCD] actionlists will follow once the action queue is complete (){x_potion,blood_for_blood,heavy_thrust} [p1.GCD] # remaining is set to 0 if an aura does not exist # you do not need to test for both exists and remaining # if an action is in the queue, no further actions will be run # if a condition is satisfied, the sim will attempt to cast the action # if an action succeeds, no further actions will be run until the queue is empty # the only supported boolean operator is & # to do | actions, use multiple action lines # blank conditionals are always true (p1.aura.heavy_thrust.remaining<5.0){heavy_thrust} (t1.aura.chaos_thrust.remaining<12.0){impulse_drive,disembowel,chaos_thrust} (t1.aura.phlebotomize<5.0){phlebotomize} (){true_thrust,vorpal_thrust,full_thrust} [p1.OGCD] # you'll need this unless you want to constantly clip GCDs # actionlist execution stops as soon as a successful action is entered # blank actions are automatically successful (p1.nextgcd<1.0){} (){blood_for_blood} (p1.nextaction==full_thrust){life_surge} (!p1.cd.jump){power_surge} (){jump} (){dragonfire_dive} (){leg_sweep}
|
![]() |
![]() |
![]() |
|