Page 3 of 12 FirstFirst 1 2 3 4 5 ... LastLast
Results 21 to 30 of 112

Thread: A DPS Simulator

  1. #21
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    Quote Originally Posted by EasymodeX View Post
    Err, what's the point of that? If the player is entering logic for the engine, then they'd want to wait for the DOT to drop before recasting. If the player is entering a sequence, then the engine should flag a rejected DOT so the player can fix it, IMO, and run the sim again.
    The point of the engine is to simulate the game.

    It will not prevent you from doing any actions that are not expressly illegal.

    For instance, if you wanted to you could spam windbiter all day long until you run out of TP, and it won't have a problem with it.

    Its up to the user to program (or think through) their priorities when doing the rotation. Also this way, you can compare overwriting, etc, between different rotations easily to see which is superior.

    I only give you the tools! Its up to you to use them effectively. On that note though, I will be writing a metrics program over the weekend to easily visualize your dps profile. Anyone else is welcome to do so as well.

    I do not want the base engine to throw out too much text spam, esp since it is already slow since its in Java.

    Every single event that the engine handles is exposed.

    If you wish, you could easily write a module that will warn you whenever your dot will not overwrite.
    (0)

  2. #22
    Player
    EasymodeX's Avatar
    Join Date
    Sep 2013
    Posts
    900
    Character
    Lunairetic Emx
    World
    Midgardsormr
    Main Class
    Lancer Lv 50
    It's not so much DOT overwriting: it's when you are attempting to overwrite a buffed DOT with an unbuffed DOT. To be specific, the FF14 game actually tells you that your DOT didn't take effect.

    Edit: Oh, I forgot a buff expiration for Life Surge:

    Code:
    LSURGE_END ("LSurge Ends", 0, 0, false, false),
    (0)
    Last edited by EasymodeX; 10-19-2013 at 04:29 AM.

  3. #23
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    Quote Originally Posted by EasymodeX View Post
    It's not so much DOT overwriting: it's when you are attempting to overwrite a buffed DOT with an unbuffed DOT. To be specific, the FF14 game actually tells you that your DOT didn't take effect.
    I see what you're saying, the message output of the simulation logger does actually tell you "Cannot Overwrite!" as a warning, but it has no effect on how the engine handles the action.

    To be specific the engine handles the rules, just the rules. Anything not explicitly illegal will be allowed. Very few metrics (just tp and total potency) are stored, as well as gamestate.
    The message log handles the output of messages (if turned on).
    The events store the damage, crit, buffs, etc, and by default the logger will output those as well.
    (0)

  4. #24
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    Update 6 - Release 1.0!
    The engine is finally ready for release!

    Main changes, mostly minor:
    • Added random seed. If you don't know what this means, don't worry about it.
    • Optimized math a little, should be fewer calculations, and faster simming. I am getting sub 1 second runtimes for anything up to 12000 seconds, aka 100 trials of 2 minutes each takes ~1 second. This is with printing output, so actual simming will be orders of magnitude faster. However, memory use becomes an issue with many/long sims, esp if you are creating your own metrics system to track all events.
    • Not a change, but a clarification: When DoTs can not overwrite, a status message is logged, but your attack will still go through.
    • In the same idea as above, all important events (such as consuming straighter shot for an autocrit) are also logged, but do not influence the engine.
    • Renamed everything to a BRD- prefix. This is for consistency's sake as new simulators for other jobs get created.

    You are free to use and modify these files to your heart's content, though I recommend not poking through the code, unless you know what you're doing.

    Please provide credit where it is due, is all I ask.

    Furthermore, if you are wanting to host this on a site, and/or turn it into an applet, and/or create a GUI for it, be my guest! And please contact me, so I can help you in any way possible.

    Please note that the files require you to have JDK 7 to run. If you wish, and I highly recommend, it is much easier to code and debug if you also use an IDE such as .netbeans to modify your testsimulation rotation.

    I apologize to all the noncoders out there, hopefully there will be some way to add scripting and a GUI to the sim so that it is more accessible. Those are all easy enough to add in the future however, but too much work for one person XD

    The release contains 2 files:
    BRDEngine.jar - this java archive contains the engine and event classes. I highly suggest leaving this alone.
    TestSimulation.java - this java file contains the sample code for a simple priority list, as well as basic setup for the engine. This rotation is by no way ideal, it should be pretty clear from the start. More of a starting point and example, rather than an "optimal rotation".

    You can find the links to the files on the first post, once I update it.

    Documentation

    The data exposed by the simulation engine (bs - in the TestSimulation) are:
    • setGCD(int) - sets the GCD. Number is in hundredths of seconds. 250 is default, =2.5 seconds
    • setDuration(int) - sets the duration of the fight, again in hundredths of seconds. 18000 is default, = 3 minutes.
    • setCritChance(int) - sets base critical hit chance. In hundredths of percent. 1500 is default, = 15%.
    • setRecastBuffer(int) - sets the recast buffer event. This event helps tell you when a buff/dot is about to expire. It is not required to be used, but is for your benefit. Is in hundredths of seconds, buffered from the end of the expiration time forwards. For example, if the dot lasts 1800, and you set buffer to 100, it will set an event at 1700. I know I said 0 disables it, but that is currently not the case...will be fixed soon.
    • setExecuteOffset(int) - duration of seconds till user can execute. Defaults to 80% of the way through duration. Set to duration or anything higher to never execute. Set to 0 or lower to always execute.
    • setLogMessages(true/false) - Whether you want to see the "combat log" messages. If you set this to false, currently outputs nearly nothing. Recommend true for now unless you are doing high duration/trials for simming.
    • getSeed() - gets the random seed for the sim. Note this cannot be changed once initialized, and you will have to start a new sim to use a new seed.
    • getGCD() - gets the GCD you set. Cannot be changed after start().
    • getDuration() - gets the duration you set. Cannot be changed after start().
    • getCritChance() - gets the base crit chance you set. Cannot be changed after start().
    • getRecastBuffer() - ditto.
    • getExecuteOffset() - ditto.
    • getCurrEvent() - returns the BRDEvent that is currently "on the stack", or just been processed.
    • getTrial() - gets the number corresponding to the current trial number...mostly for user's sake, is meaningless otherwise.
    • ssProc() - whether you have a Straighter Shot proc active.
    • bl() - whether you can Bloodletter or not. true - can BL, false - on cooldown.
    • misery() - whether you can Misery's End or not. Note: This only tracks if ME is on cooldown. It does NOT track whether you can execute or not. Check execute() if you want to see whether you can execute.
    • ss() - whether Straight Shot (crit buff) is active
    • wb() - whether Windbite is active on target
    • vb() - whether Venomous Bite is active on target
    • execute() - whether you are able to execute the target. Use with misery() to determine whether you can use ME.
    • bfb() - whether Blood for Blood buff is active.
    • bfbCD() - whether BfB is on CD. True means its on cd and CANNOT be used, false means it is off CD.
    • rs() - whether Raging Strikes is active
    • rsCD() - whether RS is on CD
    • he() - whether Hawk's Eye is active
    • heCD() - whether HE is on CD
    • ir() - whether Internal Release is active
    • irCD() - whether IR is on CD
    • barrage() - whether barrage is active
    • barrageCD() - whether barrage is on CD
    • flaming() - whether flaming arrow is active
    • flamingCD() - whether FA is on CD
    • invigCD() - whether Invigorate is on CD
    • getPotencyTotal() - gets a running total of how much potency has been cast so far. Use at end for total for entire encounter.
    • getTPTotal() - gets a running total of how much TP has been consumed so far.
    • getTPBalance() - gets the current amount of TP you have.
    • getLastSS() - returns the time when the last SS was cast. Useful for rotation algorithms that want finer control over when they want to recast.
    • getLastWB() - returns the last BRDEvent corresponding to the last WB cast. The event contains all the information (such as number of buffs, time cast) needed.
    • getLastVB() - same deal, but for VB.
    • getLastBL() - gets the last time BL was cast
    • getLastME() - gets the last time ME was cast
    • getLastBFB() - ditto
    • getLastRS() - ditto
    • getLastHE() - ditto
    • getLastIR() - ditto
    • getLastBarrage() - ditto
    • getLastFlaming() - ditto
    • getLastInvig() - ditto
    • getCurrPotency() - DEPRECATED, will be removed
    • currCrit() - DEPRECATED, will be removed
    • wbCrit() - DEPRECATED
    • vbCrit() - DEPRECATED
    • isGCD() - whether there is a GCD event available to consume. This is very important for rotational use, obviously. You are not required to use GCDs as soon as they come up, but you cannot use GCD actions unless a GCD is available, obviously.
    • isOGCD() - whether there is an OGCD event available to consume. This is important for rotation use, obviously. Note: You are not required to use OGCDs on OGCD events, nor are they generated unless you have consumed a GCD event prior. This is to simulate game mechanics. You are welcome to delay GCDs, and/or use oGCDs on GCD events.
    • ssRecast() - whether the SS recast buffer has become active.
    • vbRecast() - same thing
    • wbRecast() - same thing

    Phew! If you are still alive, here are the actual methods used to run the simulation:
    • start() - starts the simulation. After this point, you CANNOT change any game state variables. You can only consume events and check game state.
    • run() - Returns to you the next BRDEvent consumed, and advances the simulation. Also updates the game state. This is the primary way of advancing the simulation. Returns null in case of an error or the simulation ends.

      Recommended use is while((currEvent = bs.run()) != null){logic here!}. This will advance the simulation every loop until it expires, while passing you the current event processed for you to consume. Rotational logic would go inside the loop, as well as any personal metrics you wish to run.
    • addAction(BRDEvent.EventType e) - tells the simulation you wish to attempt to do a given action. If you try to attack when there is no gcd available, etc, your attack will fail. addAction() returns true when your action succeeds, false otherwise.
    • delay(int time) - tells the simulation you wish to add an event after a certain amount of time. This always succeeds, though doesn't do anything by itself. Useful if you wish to delay certain actions for a given amount of time, but you don't know if there will be an event to consume at that point. If this is confusing to you, don't worry about it, and just don't use this.
    • printMetrics() - Spits out ending metrics. Very barebones, only contains Potency Totals, TP Totals, and TP balance.
    • crit(BRDEvent e) - calculates whether a given event will crit. Do not actually use this, as it does nothing for you. This is more of an internally used function. I will remove it next patch.

    Woops! Here is slight documentation for the BRDEvent class

    Usage is usually currEvent.function_name();
    • he() - whether the event occurred under HE
    • rs() - ditto for RS
    • bfb() - ditto for BFB
    • ir() - yep
    • ss() - ditto for ss (the crit buff)
    • barrage() - yeaaap
    • crit() - [b]whether the attack crit or not[b]. Note this does nothing after the fact, but lets you keep track of what things did crit. This is NOT the crit chance of the attack, just whether it crit or not.
    • numBuffs() - how many buffs were active when this attack was done. Useful for figuring out whether you will be able to overwrite a DoT or not.
    • eventTime() - time at which this event occurred.
    • print() - prints info on attack, for logging
    • printPotency() - prints info and potency, crit for attack
    • getTP() - how much TP the attack used
    • getPotency() - how much (calculated, final) potency the attack did. This is after application of all buffs.
    • compareTo(BRDEvent e) - i'm just putting this here because it is techcnically public, but if you know java you know this is to implement Comparable so it can be sorted via a PriorityQueue. For normal use, ignore. For awesome use - create your own wrapper for BRDEvent that sorts by different metrics (how many buffs, whether it crit, type of attack, etc), for your dps analysis =P

    For a list of event types, please see a Page 2 of the posts.

    I will add more documentation as people ask for it and/or clarification. For now...I'm tired, and want to actually play the game XD

    Enjoy, and remember, feedback is always appreciated!
    (1)
    Last edited by pandabearcat; 10-19-2013 at 08:46 AM.

  5. #25
    Player
    EasymodeX's Avatar
    Join Date
    Sep 2013
    Posts
    900
    Character
    Lunairetic Emx
    World
    Midgardsormr
    Main Class
    Lancer Lv 50
    Quote Originally Posted by pandabearcat View Post
    the message output of the simulation logger does actually tell you "Cannot Overwrite!" as a warning,
    Oh ok, as long as it's easy to find.
    (0)

  6. #26
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    I decided to code up dragoon over the weekend because I wanted to see how much work would be involved.

    All things going well, it should be extremely easy.

    I assume combo duration is 10 seconds. Will change if necessary.

    It seems I'm going to need to add fields for "fail" potency, aka if used outside combo, or outside positioning.

    As far as I know dragoon has no abilities that require both positioning and combo. If this assumption is false, please tell me, and what attacks require both.

    Going by that assumption, I'm going to add in the "fail potency" number, which will be for either being out of position or being out of combo.

    Also going to add a "positional requirement" field as well. That field will point to an enum storing the attack or positional that it requires.
    (0)

  7. #27
    Player
    EasymodeX's Avatar
    Join Date
    Sep 2013
    Posts
    900
    Character
    Lunairetic Emx
    World
    Midgardsormr
    Main Class
    Lancer Lv 50
    Quote Originally Posted by pandabearcat View Post
    As far as I know dragoon has no abilities that require both positioning and combo. If this assumption is false, please tell me, and what attacks require both.
    That assumption is fine for Dragoons.
    (0)

  8. #28
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    I didn't end up doing dragoon over the weekend because I had too much homework T.T

    Instead, I am working on version 1.1 of the BRD (and core) engine so that it can handle multitarget scenarios and AoE.

    Current plan is to have the engine expose the list of targets, which each contain their own debuff timers.

    Going ahead with this, all attacks will now require a target (and thus user rotation code will need to change). Self buffs should use the default "0" index target and the target will be ignored by the engine.

    Targets will also have a "group" number indicating which "group" they belong to for AoE.

    For instance, if you were trying to sim a fight with 2 adds next to a boss, and then a group of 5 adds, the boss and 2 adds would be group 0, and the group of 5 will be group 1.

    When you use a targetted AoE ability, it will only aoe the group of the target. If you want to sim a multitarget fight with no cleaving/aoe, then give them all different group numbers.

    EDIT: autoattacks will always default to target 0, unless you change the autoattack target with aaTarget(BRDTarget t).
    (0)
    Last edited by pandabearcat; 10-21-2013 at 11:16 PM.

  9. #29
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    Update 7 - Release BRD 1.1
    Multitarget update.
    • Targetting is now supported.
    • Targetting is now required. This means your previous rotations will break. Please use the new template as a base for your rotations.
    • Actions and events that require no target (such as self buffs, or events such as the GCD) will take the primary target (first one added) as their "target". This info is just a placeholder.
    • To create a target: new BRDTarget("name", group)
    • Grouping of targets is now supported; AoEs will only hit targets in the same group as the primary target.
    • Users can now change autoattack target with setAATarget()
    • Users can now retrieve and loop through the list of targets with bs.getTargets()
    • Log info will now show target.
    • Events now track their targets, retrieve by using event.getTarget()
    • Targets now track their DoTs. Engine no longer tracks DoTs (but does track tick events and DoT expirations). This means the methods to retrieve DoT based information (such as getLastWB(), wb(), wbRecast()) will no longer work. These functions are now in the BRDTarget class, such as target.getLastWB(). The new functions are identical in function and usage as the previous enginewide functions, except they obviously now only work for that particular target.

    Primary page will be updated shortly with updated links and documentation.

    EDIT: oops, autocrit abilities are broken atm. Fixed internally but don't want to make an update just for that. Will probably find something else to work on (maybe finally DRG =D).
    (0)
    Last edited by pandabearcat; 10-22-2013 at 12:58 AM.

  10. #30
    Player
    pandabearcat's Avatar
    Join Date
    Sep 2013
    Posts
    1,517
    Character
    Alizebeth Bequin
    World
    Brynhildr
    Main Class
    Dancer Lv 90
    Hey @EasymodeX, what did you mean by the "ends combo" events?

    If its just that they complete or interrupt combos, thats okay, I don't need that info.

    EDIT: also, do jumps take longer than an OGCD(~1-1.25 seconds) to animate?

    If so, how long do they take?
    (0)

Page 3 of 12 FirstFirst 1 2 3 4 5 ... LastLast