inb4 crit scales differently with WS and AA's.
Printable View
inb4 crit scales differently with WS and AA's.
Crit increased by 1% if party includes at least 1 lalafel.
Crit decreased by 1% if party includes more than 2 lalafel.
Crit increased by 1% if the last attack prior to your attack was a blunt attack.
Crit decreased by 1% if there are between 8 and 10 debuffs on the target.
Update on this, I've been busy playing steam sale games.
Had a chance to read documentation on the yacc clone, so planning on the parser is progressing slowly.
All my free time has been completing the tedious storyline quests so I can go play on friday. Since maintenance all day tomorrow, I'm hoping to get some work done and maybe, maybe get a parser working by end of next week.
That should also give peeps time to try out new skills and get new autoattack damage formula.
Posting it here - goodbye 30% SS buffs:
https://twitter.com/charmwitch/statu...85919157456896
They are instead flat 3% off gcds/cast times. Still roughly the same, though not quite as strong.
When servers come back up, I'll have a little bit of time before my friends log on to rush through the story together. Gonna try to use that time to knock out a SS and Crit test in Whitebrim under the assumption that +X Crit chance will always tie to +Y Crit damage across all levels and the same with SS.
I've noticed I'm doing slightly more damage naturally as well...
Looks like they've done a lot of stat rebalancing... sigh
My Death Blossom (100 potency) is pretty much where it's always been. I did manage to hit one higher damage on it, but my lower bound is unchanged so it's hard to say f I just never saw that data point in my original test. My auto attacks are 3 points higher than they used to be, though, so if they really did make Det scale worse on AA they must have boosted the other stats contribution or something. . .
Since I have some free time waiting for people to log on to quest with, I'm gathering some preliminary numbers on how crit affects crit damage. So far here are my numbers:
Level 53, WD 58, AP 641, Crit 509, Det 371. . . Base 345 Crit and 207 Det, since who knows if that matters?
100 Potency damage: 217-240 non-critical, 329-364 critical
AA damage: 190-211 non-critical, 288-319 critical
Crit chance: 227/2013 swings, or about 11.27%
Crit ratio: 329/217=1.516, 364/240=1.516repeating, 288/190=1.515, 319/211=1.511.
That last one looks like an outlier, but. . .
211/190=1.111, which is a big spread
190.5 x 21/19=210.55, which makes 210.55 our upper bound for max AA damage, with 211 being the rounded value. Dividing 319 by this value puts us back at 1.515.
I'll be doing more swings shortly to see if the 11% rate is accurate, so that hopefully we can use this % later to try to tease out the relationship at 60.
Edit: Well, second batch is 119/857 crits, for a combined 12.05 rate. I'm probably gonna hold off doing any more until I find a solution so I don't have to manually copy/paste my combat log. @_@
Is it just me, or does Skillspeed scale less now?
446 SS was 2.4GCD. I'm now 511 SS with 2.42 GCD. Anyone else noticed it?
Well, the old rate was based off of a 341 base, so. . .
I did expect the base SS to change, obviously, but I didn't expect it to change this dramatically... Interesting.
If WoW is anything to go by, the effectiveness of secondary stats got basically cut to one third or more by the time you hit the level new cap to prevent you from getting 100% crit and so when expansions hit.
The mathematical significance of base values isn't all that clear to us, other than that it counts for food buffs. Perhaps crit and speed formulas for level 60 will elucidate this; at levels 1-49 it was impossible and/or counterproductive to stack enough secondary stats to get a good reading.
Someone tell me what the new DRG skills are and what they do please!
Also more delay information.
Also new AA formula.
Also obviously new formulas in general.
Blood of the Dragoon has a 15s duration (60s cooldown), which can be extended up to a maximum of 30s. When you have the buff up and you use a Chaos Thrust or Full Thrust, you have a 50/50 chance of procing either Fang & Claw, or a Wheeling Thrust, 290 potency. It's all RNG. They both increase BotD by 15s. Geirskogul reduces cooldown by 10s, but is an off-cooldown 200 potency skill.
You open up with Heavy Thrust -> Impulse Drive -> Disembowel -> Blood of the Dragon -> Chaos Thrust.
4 = 4th Tier Combo, either F&C or WT.
The rotation is basically HT -> ICD4 -> Geirskogul -> PH -> TTT4, repeat, then use BotD at the right time again. But it's very volatile to skillspeed and that's one of the issues we have at the moment.
Well, I'll be 60 tomorrow and can start working on the damage formula in my spare time. . .
Aren't you doing Crit stuff also? I could work on the DMG formula this week. I'm 60 and I'll be grinding out a lot of gear later on today. I still need to finish off Job Coefficient's, so might as well kill two birds with one stone.
Std dev for a binomial distribution is sqrt(np(1-p)).
Confidence is std/sqrt(n)
You want this small.
If you have lower crit, you want to do more trials, because the standard error relative to the probability is higher.
Well the simplest solution is to grab ACT, which has been updated for 3.0, and autoattack a dummy.
Your crit rate is the same whether you are using weaponskills or autoattacks, so afk at the dummy for 10-20-30 minutes, that will get you several hundred if not a thousand hits.
And ACT will automatically tell you what your crit % is.
If you are looking for the crit damage bonus as well, then sort the data in ACT by whether the attack crit or not, copy it into Excel, average the 2 sets, and divide the results to get a sense of the crit bonus. Again this is best with 500-1000 data points.
You can't actually say what the rate is, but you can say there's a such-and-such chance it is within a certain range of the number you came up with. This is the confidence interval on a proportion. So if you had 2263 crits in 10000 swings and wanted a 95% confidence interval, you could say there your margin of error is 1.96 * sqrt(.2263*0.7737/10000) + 0.5/10000 = 0.00825133679 (a 95% chance that the rate is between 21.80% and 23.46%).
I'm saying this because the number of swings is but one factor here--the closer the observed rate is to 50%, the more swings you'd need to establish the same margin of error.
Edit: whoa, it's a kenji sighting
One of these days, I really need to take a statistics class. >_>
I get the second term, but just to make sure I have the first one right, that's sqrt(swings*odds(odds-not)), correct? And yeah, presumably low leveling crit is part of why I'm waiting to 60. That, and more gear means more possible crit values.
Everything you said is basically what I planned, except that the afk kick timer is still a thing for a while, so I can't just sit there :p
Besides, throwing in AOE abilities makes the swing count rise faster, even if it's mind-numbingly boring.
That's basically what I meant by "establish," since we all know there won't be any certainty until either SE gives us the real formula (I can dream!) or one of us gets hired and steals it. >_>
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 | .
/hate :p
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}
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}
I posted this in the DRG thread, but it would serve better here:
Also for any of you wondering how SS scales with GCD, it's now 0.00037735 per point of SS. So you can do 2.5-((SS-354)*0.00037735)) to calculate your GCD. Alternatively, you can use this formula 2.5-(0.01*(SS-354)/26.5)) which should do the exact same thing, just a lot more accurately.
HOLY BUTTS finally found documentation (rather, examples) of how the AST node setup works.
Now need to go through the grindy process of creating a node for each nonterminal.
My god we might actually be able to release on friday. If I do, I expect someone to come help get my char to 60, cause I haven't had any time to play >.<
EDIT: work has begun. I'd forgotten how much more work semantic is than syntax parsing. Hwarrgagahblargh.
So, just as a partial update. . .
Still collecting swings at 657 crit, because seriously screw margins of error, but I have a fun data piece on how much that boosts crit damage by. Non-critical damage of 500 potency SA with 689 AP, 260 Det, and 59 WD with Venom, B4B, and Dancing Edge up is 1793-1982. I don't have the full critical spread yet, but I do have a 3012 data point, which means at least a 1.5196~ multiplier for ~12% crit rate. And mind you, 3012 might be a few points shy of max, too. . .
Just to make sure I'm not being dumb (the heat makes me rather dumb and incapable of comprehension), 12% Chance with 1.5196% multiplier at base 354 Critical Hit Rating, right?