Edit source Database for all enemies in WARFRAME. Enemy drop tables can be updated on Module:DropTables/data. Enemy damage data based on https://docs.google.com/spreadsheets/d/1sS0OYvBXBkAsUGnlnBzyCA6GSTvLYfQzXka1plH7kxg/edit?usp=sharing credit to User:ArbitraryMary. Last updated: Sat, 13 Jul 2024 23:53:10 +0000 (UTC) by User:Headbox8424 Horizontal Partitions (and where to update data)[] Enemy Entry Schema[] ["Heavy Gunner"] = { General = { Abilities = { "Seismic Shockwave" }, Actor = "", CodexSecret = false, Description = "High damage minigun", Faction = "Grineer", Image = "HeavyGunnerDE.png", Introduced = "Vanilla", Missions = {}, Planets = {}, Scans = 3, TileSets = { "Grineer Asteroid", "Grineer Galleon", "Grineer Shipyard", "Orokin Moon" }, Type = "Ranged", Weapons = { "Gorgon", "Sheev" }, }, Stats = { Health = 300, HealthType = "Cloned Flesh", Shield = 0, ShieldType = "", Armor = 500, ArmorType = "Ferrite Armor", Affinity = 500, BaseLevel = 8, SpawnLevel = 8, Multis = { "Head: 3.0x" }, ProcResists = {}, } }, General Subtable Schema[] General = { Abilities = { "Seismic Shockwave" }, Actor = "", CodexSecret = false, Description = "Codex description of enemy", Faction = "Grineer", Missions = {}, Image = "EnemyImage.png", InternalName = "", Introduced = "29", Link = "Page Name", Name = "Enemy Name", Planets = {}, Scans = 3, Type = "Ranged", Weapons = { "Gorgon", "Sheev" }, }, Key/Column Name Internal Equivalent Data Type Required? Explanation/Description Example(s) Abilities N/A Table (of strings) ❌ Array of abilities names {} Actor N/A String ❌ Voice actor of enemy "[DE]Rebecca" CodexSecret CodexSecret Boolean ✔️ Whether or not the enemy has an entry in the Codex before the player scans it; defaults to false true Description ShortDesc String ❌ Description of enemy as seen in the Codex "High damage minigun" ExcludedFromSimulacrum ExcludedFromSimulacrum Boolean ❌ Whether or not the enemy cannot be spawned in the Simulacrum true Faction Faction String ✔️ Associated Faction "Corpus" FactonDamageOverride N/A String ❌ Override for enemies with different faction resistance value instead of that usually matches their faction. "Grineer" Image Icon String ✔️ Image file name of the enemy as uploaded to the wiki. "CrewmanTech.png" InternalName N/A String ✔️ The full unique name of an enemy formatted as a file path "/Lotus/Types/Enemies/Grineer/AIWeek/Avatars/HeavyFemaleGrineerAvatar" Introduced N/A String ✔️ The game version in which the enemy was first introduced in the global build of WARFRAME "30.5" or "Specters of the Rail" Link N/A String ✔️ Page/article link to the enemy on the wiki "Scorch" Missions N/A Table (of strings) ❌ Star Chart mission nodes/mission types that enemy can appear in { "Kuva Siphon" } Name LocTag String ✔️ Name of enemy "Scorch" Planets N/A Table (of strings) ✔️ Star Chart regions that enemy can appear in as seen in enemy's Codex entry { "Earth", "Void", "Lua" } Scans CodexScansRequiredOverride Number (int) ✔️ Number of scans required to unlock the enemy's Codex entry 3 Type N/A String ✔️ Informal enemy categorization based on common characteristics and/or mechanics (e.g. can only perform Mercy finisher on "heavy" units) "Boss", "Sniper", "Heavy", or "Light" Weapons N/A Table (of strings) ❌ Names of weapons that the enemy wields as stored in Module:Weapons/data (i.e. player usable weapons only) "Grakata" or "Dera" Stats Subtable Schema[] Stats = { Affinity = 500, Armor = 500, BaseLevel = 8, Health = 300, Multis = { "Head: 3.0x" }, ProcResists = {}, Shield = 0, SpawnLevel = 8, } Key/Column Name Data Type Required? Explanation/Description Example(s) Affinity Number (int) ✔️ Base Affinity value at base level 500 Armor Number (int) ❌ Base Armor value at base level 500 ArmorType String ❌ (depreciated as of Update 36.0 (2024-06-18)) Armor class "Alloy Armor" Attacks Table (of tables) ❌ Attack tables defining the base stats of enemy attacks BaseLevel Number (int) ✔️ Base enemy level used for Enemy Level Scaling 1 Health Number (int) ✔️ Base Health value at base level 300 HealthType String ✔️ (depreciated as of Update 36.0 (2024-06-18)) Health class "Tenno Flesh" Multis Table (of strings) ❌ Array of Enemy Body Parts multipliers { "Head: 3.0x" } Overguard Number (int) ❌ Base Overguard value at base level 12 ProcResists Table (of strings) ❌ Array of Status Effects that cannot be applied to enemy; can use "All" as a shorthand for all procs. { "Virus", "Stagger" } Shield Number (int) ❌ Base Shield value at base level 0 ShieldType String ❌ (depreciated as of Update 36.0 (2024-06-18)) Shield class "Proto Shield" SpawnLevel Number (int) ❌ Enemy level at which enemy will first spawn at 8 Attacks Subtable Schema[] Attacks = { { AttackName = "Normal Attack", CritChance = 0.3, CritMultiplier = 2, DamageDistribution = { Impact = 0.5, Puncture = 0.25, Slash = 0.25 }, StatusChance = 0.3, TotalDamage = 100, }, { AttackName = "Melee Attack", CritChance = 0.3, CritMultiplier = 2, DamageDistribution = { Impact = 0.5, Puncture = 0.25, Slash = 0.25 }, StatusChance = 0.3, TotalDamage = 100, }, } Key/Column Name Data Type Required? Explanation/Description Example(s) AttackName String ✔️ Editor-defined attack name "Normal Attack" CritChance Number (float) ✔️ Attack's Critical Chance 0.5 CritMultiplier Number (float) ✔️ Attack's Critical Multiplier 2 DamageDistribution Table (dictionary-like) ✔️ Distribution of damage types as decimals { Impact = 0.5, Puncture = 0.25, Slash = 0.25 } StatusChance Number (int) ✔️ Attack's Status Chance 0.3 TotalDamage Number (int) ✔️ Attack's total base damage before enemy level scaling is applied 75 --- WARFRAME enemy database to be used on the wiki. -- -- @module Enemies/data -- @alias data -- @attribution [[User:FINNER|FINNER]] -- @attribution [[User:Cephalon Scientia|Cephalon Scientia]] -- @attribution Everyone who contributes to adding new data or updating existing values in database --- @require [[Module:LuaSerializer]] -- @release stable -- -- TODO: Since horizontal partitions are accessed programmatically, this means -- that this module can be tailored to serve specific user localizations. -- All we need to do is to add a locale flag in here set to mw.getCurrentFrame():preprocess('{{int:Custom-lang}}'), -- a separate translation table (likely JSON) for mapping canonical internal names to localized names, -- and replace the Name key/Trigger key/index key with the localized counterpart. -- In theory, any database access by requiring this module should contain the -- proper localization based on user's interface language setting. local data = {} local MODULE_LOCALIZATION = mw.site.namespaces[828].name local COOP_FACTIONS = { 'grineer', 'corpus', 'infestation', 'orokin', 'sentient', 'stalker', 'narmer', 'themurmur', 'unaffiliated' } local FACTIONS_MAP = { grineer = 'grineer', ['kuva grineer'] = 'grineer', corpus = 'corpus', ['corpus amalgam'] = 'corpus', infestation = 'infestation', ['infested'] = 'infestation', ['infested deimos'] = 'infestation', orokin = 'orokin', ['corrupted'] = 'orokin', sentient = 'sentient', stalker = 'stalker', narmer = 'narmer', themurmur = 'themurmur', ['the murmur'] = 'themurmur', unaffiliated = 'unaffiliated', ['duviri'] = 'unaffiliated', ['neutral'] = 'unaffiliated', ['predator'] = 'unaffiliated', ['prey'] = 'unaffiliated', ['tenno'] = 'unaffiliated', ['unknown'] = 'unaffiliated', } -- Defining default metatable values local dbMetatable = { -- Page title of database _pageName = 'Enemies/data' } dbMetatable._pageTitle = MODULE_LOCALIZATION..':'..dbMetatable._pageName --- Defining custom looping behavior with pairs() to iterate over multiple -- partitions while acting as one database table. -- @function data.__pairs -- @param {table} self Table self-reference -- @return {function} Iterator function -- @return {table} Contains key-pair values of faction names to corresponding horizontal partition dbMetatable.__pairs = function(self) local temp = {} local factions = COOP_FACTIONS for i, faction in ipairs(factions) do temp[i] = mw.loadData(getmetatable(self)._pageTitle..'/'..faction) end function next(t, key) return pairs(t)(t, key) end function __next(t, key) if not key then return next(t[1]) else for i = 1, #t - 1 do if t[i][key] then if next(t[i], key) then return next(t[i], key) else return next(t[i + 1]) end end end return next(t[#t], key) end end return __next, temp, nil end --- Supporting indexing by faction name (returns array of enemy entries) or enemy name -- (returns a enemy entry). -- @function data.__index -- @param {table} self Table self-reference -- @param {string} key Index key -- @return {table} dbMetatable.__index = function(self, key) if (type(key) == 'number') then return nil end -- Indexing by faction if key and FACTIONS_MAP[key:lower()] then return mw.loadData(getmetatable(self)._pageTitle..'/'..FACTIONS_MAP[key:lower()]) end local factions = COOP_FACTIONS -- Indexing by enemy name local enemy for _, faction in ipairs(factions) do enemy = mw.loadData(getmetatable(self)._pageTitle..'/'..faction)[key] if enemy then return enemy end end return nil end --- For changing which type of database to pull data from. -- If you want to switch to a different database in the same script, must require() -- a new instance of M:Enemies/data. -- @function __call -- @usage require('Module:Enemies/data')(true) -- @param {table} self Table self-reference -- @param {table} args Argument table -- @return {table} Database table dbMetatable.__call = function(self, args) -- Define logic for additional named arguments before the return statement -- TODO: We can take advantage of calling a database table by adding additional arguments -- for filtering out content. return self end --- Serializes database tables into a single string with no functions and metatables. -- @function __tostring -- @param {table} self Table self-reference -- @return {string} Serialized database dbMetatable.__tostring = function(self) return require('Module:LuaSerializer')._serialize(getmetatable(self)._pageName) end setmetatable(data, dbMetatable) return data