Skip to content

trumully/artipy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

artipy logo

artipy

GitHub Release CI Status Docs Status License Ruff


Easily generate Genshin Impact artifacts.

πŸ“š Table of Contents

πŸ“ About

This is a Python package that can generate Genshin Impact artifacts as close to how they are in the game as possible. It is intended to be used for statistical analysis

πŸ“¦ Getting Started

To install and use the package right away, you can use pip:

python -m pip install -U git+https://github.com/trumully/artipy.git
# or if you don't have 'git' installed:
python3 -m pip install -U https://github.com/trumully/artipy/zipball/main

For development, follow the steps below:

Prerequisites

To set up a dev environment you'll need pipx & poetry. Installation instructions for pipx on your respective operating system can be found here.

Once pipx is installed, install poetry:

pipx install poetry

Installing

Clone the repository:

git clone https://github.com/trumully/artipy.git

Activate virtual environment:

poetry shell

Install dependencies:

poetry install

πŸ§ͺ Running tests

Run tests using pytest:

poetry run pytest

πŸ”§ Usage

For a broader exploration of the usage of the package be sure to checkout the documentation.

Create an artifact

Here we use the ArtifactBuilder class to create an Artifact.

from artipy.artifacts import ArtifactBuilder, ArtifactSlot, ArtifactSet
from artipy.stats import StatType


def main() -> None:
    artifact = (
        ArtifactBuilder()
        .with_level(8)
        .with_rarity(5)
        .with_mainstat(StatType.ATK_PERCENT, 0.228)
        .with_substats([
            (StatType.ATK, 19),
            (StatType.CRIT_RATE, 0.039),
            (StatType.HP_PERCENT, 0.053),
            (StatType.HP, 568)
        ])
        .with_slot(ArtifactSlot.SANDS)
        .with_set(ArtifactSet.GLADIATORS_FINALE)
        .build()
    )
    print(artifact)


if __name__ == "__main__":
    main()

This results in the following artifact:

Sands of Eon [+8]
β˜…β˜…β˜…β˜…β˜…
ATK+22.8%
β€’ ATK+19
β€’ CRIT Rate+3.9%
β€’ HP+5.3%
β€’ HP+568

We can do better than this... Let's upgrade!

We can upgrade the artifact using the aptly named upgrade method on the artifact. Let's upgrade it to +12.

from artipy.artifacts import ArtifactBuilder, ArtifactSlot
from artipy.stats import StatType


def main() -> None:
    artifact = (
        ArtifactBuilder()
        .with_level(8)
        .with_rarity(5)
        # ... other parameters
    )

    for _ in range(4):
        artifact.upgrade()
    print(artifact)


if __name__ == "__main__":
    main()

After upgrading this is what we get:

Sands of Eon [+12]
β˜…β˜…β˜…β˜…β˜…
ATK+30.8%
β€’ ATK+19
β€’ CRIT Rate+7.8%  # <- this was 3.9% before.
β€’ HP+5.3%
β€’ HP+568

Let's analyse this artifact a bit.

Firstly we'll need to import the artipy.analysis package to get started.

import artipy.analysis as analysis
from artipy.artifacts import ArtifactBuilder, ArtifactSlot, ArtifactSet
from artipy.stats import StatType


def main() -> None:
    artifact = (
        ArtifactBuilder()
        .with_level(8)
        .with_rarity(5)
        # ... other parameters
    )

    for _ in range(4):
        artifact.upgrade()
    print(artifact)

    roll_value = analysis.calculate_artifact_roll_value(artifact)
    max_roll_value = calculate_artifact_maximum_roll_value(artifact)
    crit_value = calculate_artifact_crit_value(artifact)
    print(f"Roll Value: {roll_value}")
    print(f"Max Roll Value: {max_roll_value}")
    print(f"Crit Value: {crit_value}")


if __name__ == "__main__":
    main()

Here is the output:

Sands of Eon [+12]
β˜…β˜…β˜…β˜…β˜…
ATK+30.8%
β€’ ATK+19
β€’ CRIT Rate+7.8%
β€’ HP+5.3%
β€’ HP+568
Roll Value: 5.789780576014326490600895658
Max Roll Value: 7.789780576014326490600895658
Crit Value: 15.57999982237815855823370725

Let's walk through the meaning of these values:

  • Roll Value (RV): A percentage of the current stat values over their highest potential value.
  • Max Roll Value (MRV): The artifact roll value assuming all remaining rolls are of maximum potency.
  • Crit Value (CV): The value of the artifact's crit stats (CRIT DMG + 2 * CRIT Rate)

Let's plot some data!

To start plotting let's go ahead and import the artipy.analysis.plots sub-package:

import artipy.analysis as analysis
from artipy.analysis import plots
from artipy.artifacts import ArtifactBuilder, ArtifactSlot, ArtifactSet
from artipy.stats import StatType


def main() -> None:
    artifact = (
        ArtifactBuilder()
        .with_level(8)
        .with_rarity(5)
        .with_mainstat(StatType.ATK_PERCENT, 0.228)
        .with_substats([
        # ... other parameters
    )

    for _ in range(4):
        artifact.upgrade()
    print(artifact)

    roll_value = analysis.calculate_artifact_roll_value(artifact)
    max_roll_value = analysis.calculate_artifact_maximum_roll_value(artifact)
    crit_value = analysis.calculate_artifact_crit_value(artifact)
    print(f"Roll Value: {roll_value}")
    print(f"Max Roll Value: {max_roll_value}")
    print(f"Crit Value: {crit_value}")

    plots.plot_artifact_substat_rolls(artifact)


if __name__ == "__main__":
    main()

What does this mean?

Each stat on an artifact has a 25% chance of being upgraded every 4 levels. There is then another dice roll that decides how much the stat is increased by (for a 5β˜… artifact it's in the range of 0.7-1.0 * base value). This plot shows that distribution.

πŸš€ Deployment

Build the package using poetry:

poetry build

This will create a tar.gz and whl in the dist/ directory:

dist/
β”œβ”€β”€ artipy-(version)-py3-none-any.whl
└── artipy-(version).tar.gz

You can install the built package using pip:

python -m pip install -U dist/artipy-(version)-py3-none-any.whl
# or
python -m pip install -U dist/artipy-(version).tar.gz

πŸŽ‰ Acknowledgements

✨ Original header image belongs to HoYoverse

✨ The Genshin Optimizer project for hugely inspiring this project.