Skip to content

JS package for calculating unit stats in SWGoH

License

Notifications You must be signed in to change notification settings

munelear/swgoh-stat-calc

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SWGOH Stat Calculator Readme

Calculates unit stats for EA's Star Wars: Galaxy of Heroes based on player data. Accepted data formats are those found in swgoh.help's API endpoints, specifically the 'player.roster' object from their /player endpoint.

One additional data format is supported as well -- referred to as 'raw' in this documentation, it's a more 'pure' format based on the objects directly returned by the game's servers.

Setup

Node.js

Installation

npm install swgoh-stat-calc

Initialization

const statCalculator = require('swgoh-stat-calc');
statCalculator.setGameData( gameData );

Raw JavaScript

The statCalculator.js file is the complete calculator object, and has no dependencies on Node-specific packages. It can run just as well in any browser/system with at least ES6 compatibility. If used outside of npm, copy that file to a location your project can access, and adjust the require() parameter to point to that file, such as:

const statCalculator = require('./statCalculator.js');

Methods

Examples below make use of the api-swgoh-help package (loaded into variable swapi) to collect the raw data. See it's documentation to learn more about how to use it to gather this data.

.setGameData(gameData)

Tells the Stat Calculator what to use for the base Game Data. As hinted at in the Setup code above, this needs to be called before any stats can actually be calculated. Can also be used later to update / reassign the game data, if an update is detected and loaded externally.

Paramters

gameData Object
The Obect used by the Stat Calculator to read raw game data. It requires a specific format. An example JSON file of the proper gameData object can be found here. That link should remain active and updated, and thus can be used directly to create the data object. To create the object from swgoh.help's /data endpoint, see the code in dataBuilder.js. (A separate package for this code will be created in the future, but for now, it's just hiding in that project).

Return Value

None.

Example

// uses 'node-fetch' for the GET request to retrieve the gameData object
const fetch = require('node-fetch');
const statCalculator = require('swgoh-stat-calc');

let gameData = await (await fetch('https://swgoh-stat-calc.glitch.me/gameData.json')).json();
statCalculator.setGameData( gameData );

.calcCharStats(char [, options] )

Calculates stats for a single character.

Parameters

char Object
The character object to calculate stats for. Only a single character is allowed. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The stats object for the given char. Does not affect char itself.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// pull Darth Sion out of roster as an example
let char = player.roster.find( unit => unit.defId == "DARTHSION" );
// get stats
char.stats = statCalculator.calcCharStats( char );

.calcShipStats(ship, crew [, options] )

Calculates stats for a single ship.

Parameters

ship Object
The ship object to calculate stats for. Only a single character is allowed. See Object Formats below for more info.

crew Array
Array of crew members belonging to the ship. Each element is regular character object. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The stats object for the given ship. Does not affect ship itself.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// pulls Hound's Tooth out of roster as an example
let ship = player.roster.find( unit => unit.defId == "HOUNDSTOOTH" );
// pulls Bossk out of roster for example crew
let crew = player.roster.find( unit => unit.defId == "BOSSK" );
// get stats
ship.stats = statCalculator.calcShipStats( ship, [crew] );

.calcRosterStats(units [, options] )

Calls .calcCharStats() or .calcShipStats() depending on each unit's combatType in a roster.

Parameters

units Array
Array of unit objects to calculate stats for. Each element is regular unit object. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The number of units that had stats calculated. The original units array has been altered such that each element now has a .stats property with the calculated stats.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// get stats for full roster
let count = statCalculator.calcRosterStats( player.roster );

.calcPlayerStats(players [, options] )

Calls .calcRosterStats() for each roster object in the player profile(s) submitted.

Parameters

players Object or Array
Full player profile(s). Either a single player or an array of players is accepted. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The number of units that had stats calculated. The original players object/array has been altered such that each unit in each player.roster object now has a .stats property with the calculated stats.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// get stats for full roster
let count = statCalculator.calcPlayerStats( player );

.calcCharGP(char [, options] )

Calculates GP of the specified character.

Parameters

char Object
The character object to calculate stats for. Only a single character is allowed. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The GP of submitted character.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// pull Darth Sion out of roster as an example
let char = player.roster.find( unit => unit.defId == "DARTHSION" );
// get GP
char.gp = statCalculator.calcCharGP( char );

.calcShipGP(ship, crew [, options] )

Calculates GP of the specified ship.

Parameters

ship Object
The ship object to calculate stats for. Only a single character is allowed. See Object Formats below for more info.

crew Array
Array of crew members belonging to the ship. Each element is regular character object. See Object Formats below for more info.

options Object | Optional
Optional stat format flags/instructions. See Options below for a breakdown.

Return Value

The GP of submitted ship.

Example

// get Player roster from api.swgoh.help
let player = (await swapi.fetchPlayer({
  allycode: 231686213,
  language: "ENG_US",
  project: {
    roster: {
      defId: 1,
      nameKey: 1,
      rarity: 1,
      level: 1,
      gear: 1,
      equipped: 1,
      combatType: 1,
      skills: 1,
      mods: 1,
      relic: 1
    }
  }
}) ).result[0];
// pulls Hound's Tooth out of roster as an example
let ship = player.roster.find( unit => unit.defId == "HOUNDSTOOTH" );
// pulls Bossk out of roster for example crew
let crew = player.roster.find( unit => unit.defId == "BOSSK" );
// get stats
ship.gp = statCalculator.calcShipGP( ship, [crew] );

Options

The options parameter of all calculation methods is an object that can contain any of the following properties. Any additional properties of the object will be ignored.
The Default explanations below are what is used when the related flag(s) are not used.

Example

{ gameStyle: true, unscaled: true }

Calculation control

calcGP: true
Runs GP calculations along with any specified stat calculations, and stores its value in the unit's .gp property, as well as in the .stats object as .stats.gp.

The GP value will be inaccurate for /units style objects since it is missing values that are needed for the GP calculation, such as relic level, skills, and whether the ultimate is unlocked for galactic legends.

onlyGP: true
Implies calcGP. Skips all stat calculations and only calculates the GP.

withoutModCalc: true
Speeds up character calculations by ignoring stats from mods.
Default - calculate mods stats for all characters that include them.

useValues: {Object}
Overrides unit parameters with specific values. Object structure and total options are as defined below. Parameters provided here can be missing in the original unit.

{
  char: { // used when calculating character stats
    rarity: 1-7,
    level: 1-90,
    gear: 1-12,
    equipped: "all" || "none" || [1,2,3,4,5,6], // See Below
    relic: 1-9 // 1='locked', 2='unlocked', 3=R1, 4=R2, ...9=R7
    skills: "max" || "maxNoZeta" || 1-8, // See below
    modRarity: 1-7,
    modLevel: 1-15,
    modTier: 1-5,
  },
  ship: { // used when calculating ship stats
    rarity: 1-7,
    level: 1-90
  },
  crew: { // used for characters when calculating ship stats
    rarity: 1-7,
    level: 1-90,
    gear: 1-12,
    equipped: "all" || "none" || [1,2,3,4,5,6] || 1-6, // See Below
    skills: "max" || "maxNoZeta" || 1-8, // See Below
    modRarity: 1-7,
    modLevel: 1-15,
    modTier: 1-5,
    relic: 1-9 // 1='locked', 2='unlocked', 3=R1, 4=R2, ...9=R7
  }
}

char.equipped / crew.equipped - gear currently equipped on characters/crew:

  • "all" - all possible gear at the current level.
  • "none" - no gear at the current level.
  • Array - List of filled slots. Slots are numbered 1-6, left to right, starting at the top by in-game UI.
  • Integer - Number, 1-6, of gear pieces equipped at current level. Only valid for crew.

char.relic / crew.relic - Relic 'Tier' to use
Used as the relic.currentTier property in .help's data format.
Values of 1 and 2 are for 'locked' and 'unlocked', while values >2 are 2 more than the actual Relic Level.

crew.skills - skill level to use for all crew members' abilities:

  • "max" - Max possible level.
  • "maxNoZeta" - Leaves zeta abilities at level 7, but uses max level for all others.
  • Integer - Number, 1-8, to use for all abilities, if possible.
    8 or higher is identical to "max".

Default - uses the values defined by the unit objects submitted.
This applies to each individual property of the useValues object, not just the option as a whole.

Value control

percentVals: true
Converts internal flat values for Defense (Armor/Resistance) and Crit Chance (Special/Physical) to the percentages displayed in-game. Uses the decimal form (i.e. 10% is returned as 0.1)
Default - return the flat values for above stats.

scaled: true / unscaled: true
Matches scaling status of values used internally to the game (as seen in portions of swgoh.help's /data endpoint).\

scaled - multiplies all values by 10,000. All non-modded stats should be integers at this scale.
unscaled - multiplies all values by 100,000,000. All stats (including mods) fit as integers at this scale.
Default - Stats returned at the expected scale as seen in-game. Non-percent stats (like Speed) should be integers, all percent stats (like Potency) will be decimals

Stats Object Style

Default
The default Stats Object Style has the following properties:

base all units - The base value of of the unit's stats without any stats from mods/gear/crew. For characters, these are the values used in mods with a percent bonus. gear characters - Amount of stat granted by currently equipped gear (and unused within mod calculations).
mods characters - Amount of stat granted by mods.
crew ships - Amount of stat granted by crew rating.

gameStyle: true
Activates the percentVals flag above, and also changes the Stats Object to have the following properties:

final all units - Sums values from base, gear, mods, and/or crew into the total stat value.
gear characters - Amount of stat granted by currently equipped gear (and unused within mod calculations).
mods characters - Amount of stat granted by mods.
crew ships - Amount of stat granted by crew rating.

Stat Naming Options

language: {Object}
Tells the calculator to rename the stats using the submitted object. Used mostly for localization. Object must be such that options.language[ statID ] is the stat name, i.e. {"1": "Health",...}.
An example English localization can be seen here.
Note that a large enough array will also work, as can be seen here.

Note on language keys: The object/array for options.language does not need to be as complete as the above examples (which cover all 60 possible stats in game code). Some statIDs that exist in game code are not used (such as id 59 - "UnitStat_Taunt"), and even more are not returned by this API (such as id 57 - "Speed %" - which converted to the flat "Speed" value, id 5).
Any statIDs that are not in options.language will remain indexed as that integer ID in the return object.

noSpace: true
Converts any stat name strings used in the language option into standard camelCase with no spaces. Only affects stat names defined in that parameter.
I.e. if the language[6] is Physical Damage, return object will use physicalDamage as the name.

Object Formats

"Native" format -- swgoh.help's /player

Player profile object. Contains a .roster property with an array of unit objects.

Full profile:

{
  roster: [
    {
      defId: <String>,
      rarity: <Integer>,
      level: <Integer>,
      gear: <Integer>,
      equipped: [
        {
          equipmentId: <String>
        },
      ... ],
      skills: [ // skill list only required for crew members when calculating ship stats
        {
          tier: <Integer>,
          id: <String> // id only needed for GP calculations
        },
      ... ],
      mods: [ // can be skipped if using `withoutModCalc` flag for characters only
        {
          pips: <Integer>,
          set: <Integer>,
          tier: <Integer>, // tier only needed for GP calculations
          level: <Integer>,
          primaryStat: {
            unitStat: <Integer>,
            value: <Number>
          },
          secondaryStat: [
            {
              unitStat: <Integer>,
              value: <Number>
            },
          ... ]
        }
      ... ],
      relic: {
        currentTier: <Integer>
      }
    },
  ... ]
}

Used directly by .calcPlayerStats(), which also accepts an array of these objects (and swgoh.help's /player endpoint always returns an array)

player.roster
Used directly by .calcRosterStats()

Unit single element of player.roster
Used directly by .calcCharStats() and .calcShipStats() (for both the ship and the crew members).

"Units" format -- swgoh.help's /units

Object indexed by unit's base ID. Each such property is an array of unit objects.

Full Object:

{
  <BaseID>: [
    {
      starLevel: <Integer>,
      level: <Integer>,
      gearLevel: <Integer>,
      gear: [ <String>, ... ],
      mods: [
        {
          set: <Integer>,
          level: <Integer>,
          stat: [
            [ <Integer>, <Number> ],
          ... ]
        }
      ... ]
    },
  ... ],
  <BaseID>: [ ... ],
... }

Only allowed by .calcRosterStats(). As skill info is not included in this format, ship stats cannot be processed. Only characters will have their stats calculated. Relic levels are not available in this format, so stats granted by relics will not be included.

Note: swgoh.help's /roster endpoint is an array of these objects. While that array is not directly accepted, each element in the array is a "Units" style object that is accepted as stated above.

"Raw" format -- direct from game

Player profile object. Contains a .rosterUnit property with an array of unit objects.

Full profile:

{
  rosterUnit: [
    {
      definitionId: <String>,
      currentRarity: <Integer>,
      level: <Integer>,
      currentTier: <Integer>,
      equipment: [
        {
          equipmentId: <String>
        },
      ... ],
      skill: [ // skill list only required for crew members when calculating ship stats
        {
          tier: <Integer>,
          id: <String> // id only needed for GP calculations
        },
      ... ],
      equippedStatMod: [ // can be skipped if using `withoutModCalc` flag for characters only
        {
          definitionId: <String>
          level: <Integer>,
          tier: <Integer>, // only needed for GP calculations
          primaryStat: {
            stat: {
              unitStat: <Integer>,
              unscaledDecimalValue: <Integer>
            }
          },
          secondaryStat: [
            {
              stat: {
                unitStatId: <Integer>,
                unscaledDecimalValue: <Integer>
              }
            },
          ... ]
        }
      ... ],
      relic: {
        currentTier: <Integer>
      }
    },
  ... ]
}

Used directly by .calcPlayerStats(), which also accepts an array of these objects.

player.rosterUnit
Used directly by .calcRosterStats()

Unit single element of player.roster
Used directly by .calcCharStats() and .calcShipStats() (for both the ship and the crew members).

Changelog

  • Version 1.1.0
    • Added support for a 'raw' format -- in line with the roster format sent directly by the game, not from swgoh.help.
    • Exposed the endpoints for calculating GP so they can be called directly.
  • Version 1.0.8
    • A number of bug fixes
    • Support for Relic stats (not available in .help's /units endpoint)
    • Added GP calculations, available only with a calcGP flag using .calcRosterStats() (and thus also .calcPlayerStats())
  • Version 1.0.1
    • 'Minor Text Fixes' to this README
  • Version 1.0.0
    • Initial Release

About

JS package for calculating unit stats in SWGoH

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%