Skip to content

Creating a new Affix

Wouter Koppenol edited this page Dec 8, 2023 · 2 revisions

Creating a new Affix

Occasionally, Blizzard adds new Affixes to the game which will need to be added to Keystone.guru. An affix in the context of Keystone.guru is Bolstering, Bursting, Sanguine. A collection of affixes are called an AffixGroup. This was choosen specifically to reduce the confusion when calling everything 'affixes'. In Laravel, the model Affix should be pluralized to affixes in the database, which can lead to confusion since the concept of 'affixes' means a collection of affixes that are assigned to a single week. That concept is as such called AffixGroups which then has its own database table called affix_groups.

This page focuses purely on Affixes, not on AffixGroups. But the distinction is important to understand. To add affixes for a season (AffixGroups) see the documentation for this process.

Adding your new affix to the code

Open up app/Models/Affix.php and add your new constant there. Add the constant to the const ALL = [..] array. If applicable, add it to the const SEASONAL_AFFIXES = [..] array. Again, if applicable add it to private const SEASONAL_TYPE_AFFIX_MAPPING = [..]. Read about Seasonal indexes if you haven't yet.

Adding a new Affix in the seeder

The seeders contain all the static data for Keystone.guru. This is the data that does not change during the runtime of the site - things that users cannot edit. They will only change whenever the site is updated and as such can be cached heavily. Seasons are one of these things.

In folder database/seeders/AffixSeeder.php exists a list of affixes that currently exist in the platform. Simply add your new affix here just like the other affixes are added.

Adding a new seasonal affix to the ExpansionSeason

I don't quite like what's going on here, but it happens. In app/Service/Expansion/ExpansionSeason.php we keep pre-calculated data related to Expansions and Seasons which are then stored in Redis and decoded upon page load for usage throughout the platform. In this file are a list of seasonal affixes that need to be set so various things can be turned on/off based on the current seasonal affix in the platform. Mostly things like additional settings for routes that belong to a certain seasonal affix or on the affix list page etc.

This will probably be refactored in the future and removed.

Adding the new affix to the map Javascript

In file resources/assets/js/custom/constants.js I keep a list of .. constants, which are used across the map Javascript. One of these things is a list of Affixes such as const AFFIX_INCORPOREAL = 'Incorporeal';. Add your new affix there so that you can check in the next session if your current route has a certain affix and execute code to support it.

Adding Affix-specific code to the map

This is used more often. If you haven't, check out how the map Javascript works first. As you know, the MapContext is the data layer of the map. It can be of multiple types, depending on what we're currently using the map for. Be it editing the mapping, or viewing a route.

Only when you view a route, do you actually have affixes that you can check. This means that if you try to do it in the context of editing a MappingVersion the function will always return true. To check if the current map/route has an affix:

let mapContext = getState().getMapContext();
if (mapContext instanceof MapContextDungeonRoute) {
    let hasFortified = mapContext.hasAffix(AFFIX_FORTIFIED);
}

Based on that you can make the map do things when just the Fortified affix is available. This type of structure is used pretty extensively across the map Javascript. You always want to be checking if a certain affix applies to the current map or not. That way when a certain affix is not around you simply don't do anything with it. For example, if enemies are marked as Inspiring, you want to highlight said enemies when the route has an Inspiring affix selected. If the route does not it only produces more noise so it's best to hide the visuals then.

Adding Affix-specific code to the backend

If there's some specific code for the backend required for a certain affix, you can check this using the following:

if( $affixGroup->hasAffix(Affix::AFFIX_PRIDEFUL) ) {
    ...
}

All routes are assigned at least one affix group ($dungeonRoute->affixes (see, it's confusing already since this IS the list of AffixGroups)), so you can iterate over those groups to see if a route has a certain affix. I haven't needed this yet but if you do, create a helper function for it (like ->hasAffix(..) above here).

Seasons are assigned these same AffixGroups so you can apply the same logic there.

Clone this wiki locally