Git Product home page Git Product logo

simulator's Introduction

FFXIV Teamcraft

GitHub Release Date GitHub issues GitHub pull requests Discord

Collaborative crafting tool for Final Fantasy XIV

https://ffxivteamcraft.com

Discord for support, bugs discussion and contributors: https://discord.gg/r6qxt6P

Wiki for feature documentation and user guides: https://wiki.ffxivteamcraft.com/

Development

Conventional Commits GitHub license

License

MIT

Responsive tooling

We're using @angular/flex-layout for responsive tooling, their wiki is available on the link below.

https://github.com/angular/flex-layout/wiki/Responsive-API

Contribute

Contributions guidelines can be found inside CONTRIBUTING.md file.

simulator's People

Contributors

awgil avatar ayyaruq avatar caraxi avatar dependabot[bot] avatar dten avatar ff14wed avatar konaeakira avatar kyuusokuna avatar sigfalt avatar supamiu avatar turingm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

simulator's Issues

Bug: Version 1.1+ appears to break progression and quality increases

Tried executing a Hempen Yarn craft on the latest version (1.2.0) and on 1.0.5. The following is the returned object from simulation.run(). The same code and the same parameters were used in both runs, which is to say that the version was controlled for. Notably, on versions 1.1.0 and above, this craft with a 1x Focused Touch -> 2x Focused Synthesis macro returns NaN at certain points, failing the craft with an undefined fail cause. I haven't formally tested this bug on other crafts, but I did notice it return NaN values with this same macro on the Rakshasa Ring of Aiming on version 1.1.0.

Latest version:

3|prima-extra     | { steps:
3|prima-extra     |    [ { action: Observe {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -7,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedTouch {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: NaN,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -18,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: -10,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: Observe {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: NaN,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -7,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedSynthesis {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: NaN,
3|prima-extra     |        addedProgression: NaN,
3|prima-extra     |        cpDifference: -5,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: -10,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: Observe {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: NaN,
3|prima-extra     |        addedProgression: NaN,
3|prima-extra     |        cpDifference: -7,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedSynthesis {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: NaN,
3|prima-extra     |        addedProgression: NaN,
3|prima-extra     |        cpDifference: -5,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: -10,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] } ],
3|prima-extra     |   hqPercent: undefined,
3|prima-extra     |   success: false,
3|prima-extra     |   simulation:
3|prima-extra     |    Simulation {
3|prima-extra     |      recipe:
3|prima-extra     |       { id: 464,
3|prima-extra     |         job: 13,
3|prima-extra     |         rlvl: 1,
3|prima-extra     |         durability: 60,
3|prima-extra     |         quality: 312,
3|prima-extra     |         progress: 9,
3|prima-extra     |         lvl: 1,
3|prima-extra     |         stars: 0,
3|prima-extra     |         hq: 0,
3|prima-extra     |         quickSynth: 0,
3|prima-extra     |         controlReq: 0,
3|prima-extra     |         craftmanshipReq: 0,
3|prima-extra     |         ingredients: [Array],
3|prima-extra     |         yield: 1 },
3|prima-extra     |      actions:
3|prima-extra     |       [ Observe {},
3|prima-extra     |         FocusedTouch {},
3|prima-extra     |         Observe {},
3|prima-extra     |         FocusedSynthesis {},
3|prima-extra     |         Observe {},
3|prima-extra     |         FocusedSynthesis {} ],
3|prima-extra     |      _crafterStats:
3|prima-extra     |       CrafterStats {
3|prima-extra     |         jobId: 13,
3|prima-extra     |         craftsmanship: 1500,
3|prima-extra     |         _control: 1536,
3|prima-extra     |         cp: 539,
3|prima-extra     |         specialist: true,
3|prima-extra     |         level: 69,
3|prima-extra     |         levels: [Array] },
3|prima-extra     |      hqIngredients: [],
3|prima-extra     |      forceFailed: [],
3|prima-extra     |      progression: NaN,
3|prima-extra     |      quality: NaN,
3|prima-extra     |      startingQuality: 0,
3|prima-extra     |      state: 'NORMAL',
3|prima-extra     |      buffs: [],
3|prima-extra     |      success: undefined,
3|prima-extra     |      steps:
3|prima-extra     |       [ [Object], [Object], [Object], [Object], [Object], [Object] ],
3|prima-extra     |      lastPossibleReclaimStep: -1,
3|prima-extra     |      safe: false,
3|prima-extra     |      durability: 30,
3|prima-extra     |      availableCP: 490,
3|prima-extra     |      maxCP: 539 } }

1.0.5:

3|prima-extra     | { steps:
3|prima-extra     |    [ { action: Observe {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -7,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedTouch {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: 988,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -18,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: -10,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: Observe {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: -7,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedSynthesis {},
3|prima-extra     |        success: true,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 1090,
3|prima-extra     |        cpDifference: -5,
3|prima-extra     |        skipped: false,
3|prima-extra     |        solidityDifference: -10,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: Observe {},
3|prima-extra     |        success: null,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: 0,
3|prima-extra     |        skipped: true,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'NORMAL',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] },
3|prima-extra     |      { action: FocusedSynthesis {},
3|prima-extra     |        success: null,
3|prima-extra     |        addedQuality: 0,
3|prima-extra     |        addedProgression: 0,
3|prima-extra     |        cpDifference: 0,
3|prima-extra     |        skipped: true,
3|prima-extra     |        solidityDifference: 0,
3|prima-extra     |        state: 'GOOD',
3|prima-extra     |        failCause: undefined,
3|prima-extra     |        afterBuffTick: [Object] } ],
3|prima-extra     |   hqPercent: 100,
3|prima-extra     |   success: true,
3|prima-extra     |   simulation:
3|prima-extra     |    Simulation {
3|prima-extra     |      recipe:
3|prima-extra     |       { id: 464,
3|prima-extra     |         job: 13,
3|prima-extra     |         rlvl: 1,
3|prima-extra     |         durability: 60,
3|prima-extra     |         quality: 312,
3|prima-extra     |         progress: 9,
3|prima-extra     |         lvl: 1,
3|prima-extra     |         stars: 0,
3|prima-extra     |         hq: 0,
3|prima-extra     |         quickSynth: 0,
3|prima-extra     |         controlReq: 0,
3|prima-extra     |         craftmanshipReq: 0,
3|prima-extra     |         ingredients: [Array],
3|prima-extra     |         yield: 1 },
3|prima-extra     |      actions:
3|prima-extra     |       [ Observe {},
3|prima-extra     |         FocusedTouch {},
3|prima-extra     |         Observe {},
3|prima-extra     |         FocusedSynthesis {},
3|prima-extra     |         Observe {},
3|prima-extra     |         FocusedSynthesis {} ],
3|prima-extra     |      _crafterStats:
3|prima-extra     |       CrafterStats {
3|prima-extra     |         jobId: 13,
3|prima-extra     |         craftsmanship: 1500,
3|prima-extra     |         _control: 1536,
3|prima-extra     |         cp: 539,
3|prima-extra     |         specialist: true,
3|prima-extra     |         level: 69,
3|prima-extra     |         levels: [Array] },
3|prima-extra     |      hqIngredients: [],
3|prima-extra     |      forceFailed: [],
3|prima-extra     |      progression: 1090,
3|prima-extra     |      quality: 988,
3|prima-extra     |      startingQuality: 0,
3|prima-extra     |      state: 'NORMAL',
3|prima-extra     |      buffs: [],
3|prima-extra     |      success: true,
3|prima-extra     |      steps:
3|prima-extra     |       [ [Object], [Object], [Object], [Object], [Object], [Object] ],
3|prima-extra     |      lastPossibleReclaimStep: -1,
3|prima-extra     |      safe: false,
3|prima-extra     |      durability: 40,
3|prima-extra     |      availableCP: 502,
3|prima-extra     |      maxCP: 539 } }

Bug: Rotation Simulator does not properly handle 10 durability loss when less than 10 durability remains

Describe the bug
There are a few ways to end up with 5 durability remaining on your last action, with the last action causing 10 durability loss. Waste Not, Waste Not II, and a few wonky recipes that I think are meant to encourage you to use those abilities can all create this situation. Comfort Zone can also take you off of round tens, and there might be more I haven't noticed.

In-game, you can use a 10 durability loss action on your last action, and even though there are only 5 (or whatever other number under 10) left, the crafting finishes correctly. In the simulator, it throws an error, saying that the rotation will not be completed because durability will run out before the rotation is done.

To Reproduce
Steps to reproduce the behavior:
One of many ways, but this is what I used to confirm that yes, the crafting definitely finishes.

  1. Get on Culinarian, at high enough level to craft Rolanberry Cheese, with at least Careful Synthesis and Waste Not as available actions. I also used Steady Hand and Hasty Touch, but any durability-using action and non-durability-using action, neither of which add Progress, so that you can make sure your ending number is 5, will work.
  2. Begin crafting, and activate Waste Not.
  3. Perform appropriate non-progress-adding actions to bring the Durability to 5 (if one hit of Careful Synthesis will not complete the Rolanberry Cheese on your build, do all but the last Careful Synthesis as part of this).
  4. Use Careful Synthesis as your last action.
  5. Receive your three Rolanberry Cheese, demonstrating that this works.
  6. Put the precise same set of actions you just took to make cheese into the Simulator.
  7. Get error indicating durability runs out before the rotation is completed.

Expected behavior
I expected the simulator to match the game behavior, which is apparently to process Progress before deducting durability, thus not failing if the last action would cause more durability loss than there is durability left.

Desktop (please complete the following information):

  • OS: Windows
  • Version 5.8.5 desktop version

Additional context
Add any other context about the problem here.

Bug: Simulator - "Minimum stats" window does not properly reflect required CP/Control

Describe the bug
In all circumstances, the "Minimum Stats" window in the sim does not reflect the amount of CP consumed in the synth, instead it just shows the user's CP total.

Secondly, the Minimum Stats window shows the user's total control in a rotation that doesn't attempt to increase quality. It should instead show "0".

To Reproduce
Steps to reproduce the behavior:

  1. Create new rotation for iron ingot.
  2. Set Crafts/Control to 9999, set CP to 100.
  3. Complete the rotation using a single "Standard Synthesis" consuming only 15 CP.
  4. {Bug} Click the "Minimum stats" Icon and see that the craft requires "101" CP.
  5. {Bug} Also note that the Control required is set to 10000 when it should be "0" as we didn't use any control enhancing actions.

Expected behavior
Minimum CP should show the minimum amount of CP required to do the craft, taking into account Specialist CP buffs, comfort zone, and other CP restoring actions.

Minimum Control should report as "0" when no quality is 0.

Screenshots
image

Desktop (please complete the following information):

  • OS: Windows
  • Browser: Chrome
  • Version: 75.0.3770.142

Additional context
Originally reported by Tarulia in discord.

Wrong progress and quality efficiency

Hey,

hopefully I didn't see this wrong, in which case I'm sorry, but from my view it seems this line in the simulator gets wrong values:
Progress per 100% efficiency: XXX Quality per 100% efficiency: XXX

To show you what I mean here are three screenshots.
First one of the simulator showing progress efficiency 270 and quality efficiency 310.
Second one of my InGame menu showing 360 and 621.
Third one the same menu and recipe at the second last step. If you believe the simulator, I'd need 'Careful Synthesis II' two times to finish, but I actually need only one.
So I can very well put another command in between without failing the recipe.

chrome_2019-10-05_18-21-57

ffxiv_dx11_2019-10-05_18-36-11

ffxiv_dx11_2019-10-05_18-22-13

bug: inaccurate rounddown calculation in crafting simulator

Describe the bug
In a crafting process, when the actual result of "Quality per 100% efficiency" is 763.99 (float), the crafting simulator will take the value as 764 (int), while in game the value is taken as 763 (int).

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://ffxivteamcraft.com/simulator
  2. Search and select recipe "Tincture of Intelligence"
  3. Input crafter attribute: 2362 craftsmanship, 2029 control, 600 cp, 80 level
  4. Scroll down and click "Apply stats"
  5. Scroll down to crafting action section and click the icon with tooltip name "Reflect"
  6. Click the icon with tooltip name "Preparatory Touch"
  7. Scroll up to check that Inner Quiet has 5 stacks, Current Control is 3652
  8. Check the value of "Quality per 100% efficiency", it's 764 (instead of 763)

Expected behavior
When a lvl80 Alchemist with 2029 control crafts the recipe "Tincture of Intelligence", at 5 Inner Quiet stacks (3652 Control) the Quality per 100% efficiency should be round down to 763. See screenshot for in game behavior.

Screenshots
crafterAttribute

defaultEfficiencyIncrease

teamcraftResult

Desktop (please complete the following information):

  • OS: [macOS Sierra 10.12.6]
  • Browser [Chrome Version 78.0.3904.87 (Official Build) (64-bit)]

Additional context
(First time writing issue...hope my description isn't too messy

New "Good Omen" Condition

6.4 has added a new "Good Omen" condition that should be accounted for in the sim. It's used in all the new "Uncharted Course" materials. Haven't ran enough tests to get the actual probability.
image

Discrepancy in progress increase during Malleable proc

Experimentally, I've tested the simulator at 2763 craftsmanship on the r513 expert recipes and I've noticed a discrepancy in the progress increase in-game vs in simulator:

In-game:
Rapid Synth progress with no bonuses: 2355
Rapid Synth progress with veneration: 3532
Rapid Synth progress with malleable: 3532
Rapid Synth progress with veneration + malleable: 5298

Simulator:
Rapid Synth progress with no bonuses: 2355
Rapid Synth progress with veneration: 3532
Rapid Synth progress with malleable: 3530
Rapid Synth progress with veneration + malleable: 5295

I suspect it has something to do with how Math.floor is applied to the rate of progression increase before potency is applied here:

simulation.progression += Math.floor((Math.floor(progressionIncrease) * potency * bonus) / 100);

For instance, perhaps the correct formula for this follows:

Math.floor((Math.floor(progressionIncrease * potency) * bonus) / 100);

However, I also do not have enough data to determine if the inner Math.floor is even necessary.

Recommended stats

Not really an issue, more of curiosity of mine. How do you get recommended stats and real recipe levels for given recipe level in game, is there only all recipe database, datamining or could it be calculated?

Progress discrepancy at 2216 Craftsmanship

See attached screenshots.

Both Teamcraft and game are reporting 773 Progress per 100% efficiency.

I use Focused Synthesis and Careful Synthesis 3, so 200% + 150% efficiency -> 2705,5 Progress.

Teamcraft reports 2707 progress.

2019-09-02_20-52-37

2019-09-02_20-49-32

Ingenuity Accuracy Issues for HW

accuracy issues for hardsilver bangle (prob issue iwth ingen)
image teamcraft
log ingame
stats ingame

note that the image of GSM was taken at lvl 54, at the time of the log it was 53.

Estimated Progress is 407+248=655/697->unfinished item
Actual Progress is 486+262=748/697 ->finished item

Reuse might be unsafe

The simulator's safe setting currently does not, but should take into account that Reuse might not proc. It may or may not add a step to the craft, which affects buff durations (leading to durability differences with Manipulation, or the inability to refresh Ingenuity if Reuse was attempted during its last step).
At the very least, a notification should be given.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.