Skip to content

Mob Configuration (Overview)

MyLadyMalady edited this page Jun 25, 2024 · 31 revisions

Overview

Structure

Generally, for consistency purposes and ease of navigation, a mob config file should follow this root-level structure in this order:

  • key
  • type
  • pathfinding
  • showNameTag
  • meta
  • extra
  • equipment
  • attributes
  • skills
  • goals
  • [custom Element skill, selector or validator paths]

With the exception of key, type and pathfinding, any of the above can be omitted from the file if unused. In that case, it's preferred to delete a property entirely instead of appending {} for blocks or [] for lists.

The following is a basic example that uses this convention:

key: some_zombie
tags: [ some_tag ]
type: minecraft:zombie
pathfinding:
  type: proxima.path_settings.ground
  jumpHeight: 1.25
  fallTolerance: 4
  stepHeight: 0.5

showNameTag: false

meta:
  customName: <green>Some Zombie</green>

extra: {}

equipment:
  LEGGINGS: '{id:"leather_leggings"}'

attributes:
  generic.max_health: 10

attributeModifiers:
  damage.fire.addition: -69

skills:
  - type: mob.skill.play_sound
    trigger: SPAWN
    selector:
      type: /thisCanBeNamedAnything
    sound: { name: 'minecraft:entity.lightning_bolt.thunder', source: PLAYER, volume: 100.0, pitch: 1.0 }

goals:
  - type: mob.goal_applier.collection
    goalCreators:
      - type: zombies.mob.goal.break_window
        breakTicks: 1
        breakCount: 1
        breakRadius: 0.5

thisCanBeNamedAnything:
  type: mob.selector.self

In practice, showNameTag, which already defaults to false, and extra, which has no child properties, would be deleted in this example. Here, they're just used to illustrate the layout.

When configuring for Phantazm, all conventions should be followed to ensure congruency.

Mob Key

Without the mob key property, there is no mob file. It determines the mob's internal ID and, for obvious reasons, it has no default and it must be unique for every mob file — otherwise, you have a conflict which will prevent the server from starting.

In the rest of the configuration schema, the key is used in any circumstance where this particular mob needs to be referred to. Currently, that only includes the mob validator, various forms of the shooting ability (guns and the mob skill), mob spawning, as well as round configurations for both Endless and regular modes.

Convention

The key naming convention we use is all lowercase, separating individual words with underscores. Mobs for the default difficulty of a map do not need to have a suffix, otherwise you should append _[difficulty], e.g. some_zombie_rip, to the end of the key. Mobs specific to an Endless instance of a map have _[map + difficulty acronym]e, e.g. some_zombie_fge, unless the map is Endless-only — in which case, this is not necessary to indicate.

Currently, in both the mob spawning skill and the Endless config, you must include it with the phantazm: prefix, e.g. phantazm:some_zombie. In the shooting abilities and the regular round config, you can use it with the prefix but you do not have to.

Mob Tags

The tags property is used to sort mobs into categories. It accepts a list of arbitrary words, with the same character set as mob keys.

On its own, this property doesn't do anything. The idea behind it is to enable quick and easy validation for groups of mobs in validators/predicates used elsewhere, where adding/removing a mob to a group is as simple as editing a tag in its file instead of having to make changes across multiple other places. The tags should also be used to communicate the "purpose" of a mob (such as whether it's a boss or not) and to enforce brevity in validators that target a specific group.

For example, if you have a skill that affects mobs with specific "characteristics", e.g. fire-immune mobs, the preferred way of doing it is to add a tag to all of those mobs and include the tag rather than the mob type in appropriate validators/predicates.

Mob Type

The type property is frequently used across an average mob file, but its purpose depends on the property it's nested under. The root-level type determines the entity type that spawns, and it must point to a single, valid Minecraft resource location for an entity. This includes the minecraft: prefix at the beginning.

For example, to make your mob a zombie, you would use type: minecraft:zombie.

Without this property, the file isn't valid. It has no default and each mob must be associated with an entity type.

Pathfinding

The pathfinding property and its children have no default and, as such, its block must be included in full in each file. The only exception is targetDeviation.

It takes the form:

pathfinding:
  type: proxima.path_settings.ground
  jumpHeight: 1.25
  fallTolerance: 4
  stepHeight: 0.5
  targetDeviation: 0 #optional
  • type: This determines what kind of pathfinding the mob will use. Currently, the only possible value is proxima.path_settings.ground, which controls gravity-bound mobs.

  • jumpHeight: This controls how far a mob can jump. For most mobs, you should use 1.25 at minimum, which is close to the vanilla jump height for zombies. Otherwise, they may not jump up on some partial blocks that they would be able to on vanilla.

  • fallTolerance: This controls the distance a mob is willing to fall through, e.g. with a value of 5, a mob will consider up to 5-block falls in its pathfinding if there are any. This is irrelevant to fall damage. To avoid issues, the minimum we are using is 4.

  • stepHeight: This controls how far a mob will warp up (not jump) to a block. You should use 0.5 at minimum, which would enable the mob to step on stairs and slabs without having to jump on each.

  • targetDeviation: This is the maximum distance at which a mob will stop from a player, but not the minimum — it will not attempt to move out of the way if it's closer than that to its target. It defaults to 0, and as such is only present in configs for purely ranged mobs. Do not include it if you expect your ranged mob to deal melee attacks in any significant capacity.

With the exception of type, which takes in an Element resource, these properties take a double value measured in blocks.

The listed minimums are not a hard rule, as there are circumstances where you may not want to follow it, e.g. to keep a mob on top of a flat, raised platform, you would set fallTolerance to 0.

Convention

The only notable convention for pathfinding is that its child properties should be written in the above order. As long as there's only one, it does not matter whether you use a trailing zero on a whole number or not.

ShowNameTag

Not to be confused with a meta customNameVisible property, which fulfills a slightly different role, showNameTag: true toggles a mob's nametag to be shown at all. Since it defaults to false, most mobs excepting bosses do not need it included in their files.

Meta

The meta property is fairly similar to extra, minus its child properties being reserved for mob modifiers that are not specific to Zombies.

Most meta properties can be left out from a file since they have default values.

The current child properties are:

  • customName: All mobs should have this property. It's used for kill messages, e.g. 'Player was killed by [mob's custom name]' or 'Player killed [mob's custom name]', the latter given that the announceKill extra node is set to true. This is also the text displayed as a boss' name if the healthbar skill isn't present.

    It accepts a MiniMessage string as a value. Otherwise, it defaults to empty, meaning that a mob in its kill message etc. would just display what Minecraft calls its entity type — which is something that we want to avoid.

  • customNameVisible: This property will not work without showNameTag: true enabled. As such, it's typically just bosses that have it present in their files.

    It accepts a boolean value, otherwise defaulting to false.

    Note: if you have showNameTag enabled but you never set customNameVisible: true, a mob's nametag will only be displayed when it's in a player's crosshair.

  • isBaby: This is a boolean that toggles whether a mob spawns in its baby form or not, where available. It defaults to false (does not spawn the baby version). If a mob has no baby version, this does nothing.

  • size: This is a whole numerical value that determines the size of a mob that has multiple forms, where available. Mostly used for slimes. It defaults to 0. If a mob has no differing sizes, this does nothing.

  • isSmall: This is a boolean specific to armor stands that toggles its size. Default is false (the armor stand uses the ~2 block tall model).

  • isInvisible: This is a boolean that toggles a mob's permanent invisibility on and off. It defaults to false (no invisibility). This invisibility is present since the mob spawns and lasts until it dies.

  • isGlowing: This is a boolean that toggles a mob's permanent glow effect on and off. It defaults to false (no glow). It's present since the mob spawns and lasts until it dies. Use this one with caution, as we have found that having a significant number of glowing entities alive causes noticeable FPS lag.

  • hasGravity: This is a boolean that toggles whether an entity has gravity, but is intended to only be used for static (non-moving) armor stands. Defaults to true (entity is subject to downward velocity).

  • itemStack: Only used for item entities; this is how you select the rotating item that it displays. This specific property doesn't accept anything except another child property.

    • material: The Minecraft ID of the item you want to use. You must specify this because it's nothing by default.

Convention

The convention for the structure of the meta block is the above list in order.

customName can use MiniMessage's "Color", "Decoration", "Reset", "Rainbow" and "Gradient" tags, and others have no functionality for this specific node. For the Color tags, you're allowed to use Minecraft's old color formats, e.g. <blue>, as well as hex codes, e.g. <#dc7f54>. You can use multiple in a single name, but exercise common sense when naming mobs — unless it's appropriate for the theme, it's better to have simpler formatting than the more complicated/fancy kind. Read more about MiniMessage here.

There are special rules regarding the Decoration tag: the only ones you would use for mob naming are <bold> and <obfuscated>. <bold> is applied to bosses whereas normal mobs do not have it, and <obfuscated> should only be used where it makes sense to do so.

Bosses on a non-standard difficulty for a map have their names prefixed with [DIFFICULTY], with [DIFFICULTY] being in all capitals, with a color associated with that difficulty, e.g. <#b90f0f>RIP</#b90f0f> <green>Some Zombie</green>, however, you should not do the same for regular mobs.

These are the color hex codes for each difficulty:

  • #4da8ff: 0 stars (Undefined)
  • #4de1ff: 1 star (Easy)
  • #57ff4d: 2 stars (Normal)
  • #f5ff4d: 3 stars (Hard)
  • #ff1f1f: 4 stars (RIP)
  • #b90f0f: 5 stars (Cursed)
  • #c515a4: 6 stars (Forsaken)
  • #660f9b: 7 stars (Doomed)
  • #3410ad: 8 stars (Infernal)
  • #1d0c58: 9 stars (Maledict)
  • #120c27: 10 stars (Abominable)

Do not use the above in a standard difficulty for a given map.

Extra

The extra property is similar to meta but contains modifiers that are largely Zombies-specific.

All of its properties can be left out from a file as all have default values and none are mandatory, depending on the mob value.

The current child properties are:

  • resistInstakill: A boolean value that toggles what it says on the tin, though it also includes Dragon's Wrath and similar abilities. It defaults to false (no immunity) and all bosses should have it set to otherwise.

  • resistFire: A boolean value that toggles immunity to fire-based attacks and perks such as Fire Bullets. It defaults to false (no immunity).

    There is an alternate way of achieving this through resistances, although it doesn't guarantee full immunity in certain circumstances: [link]

  • resistSlowDown: A boolean value that toggles immunity to perks such as Frozen Bullets. It defaults to false (no immunity).

  • announceKill: A boolean value that toggles whether this mob's demise gets broadcast to other players. Defaults to false, but all bosses should have set it to true.

  • ticksUntilDeath: This is a whole number in ticks that counts down until the mob self-destructs, defaulting to 6000 (5 minutes). It's mandatory to include it in projectile files, as projectiles that fly out of bounds (through barriers) may not despawn otherwise, causing lag. We typically set it to 200 but it can be anything so long as it's reasonable.

    It's possible to disable it by setting the value to -1, but you should never do this unless you have a very good reason for it. Anything that would enable a game to stall infinitely should be avoided.

  • partOfRound: A boolean value that determines whether a mob of this type spawned by the spawn_mob skill, with the add_to_round callback, is added to the round counter or not. Defaults to true (they count towards the # of mobs left in the round and must be killed for the round to advance).

  • bypassEndlessScaling: This is a boolean value that toggles whether a mob's attributes are affected by Endless scaling. It defaults to false, and it's usually projectiles, which are also a mob type, that have it set to otherwise.

The next few are specific to Endless and are used to overwrite the default mob scaling (the one defined in a map's endless.yml file) in cases where the default is incompatible with a mob's design. The formulae are defined in exactly the same way as the scaling in endless.yml.

These (and the defaults) are ignored if bypassEndlessScaling is set to true.

  • endlessHealthScaling: Controls a mob's health scaling.

  • endlessDamageScaling: Controls a mob's damage scaling.

  • endlessSpeedScaling: Controls a mob's speed scaling.

Finally, the next three are almost never included (changed), but you're free to do so if there's a situation that calls for it.

  • speedupIncrements: This is the number of times a mob will have the speed-up applied to it over its lifetime. It's a whole number that defaults to 5.

  • speedupInterval: This is the time in between each speed-up increment. It's a whole number that represent a time in ticks, and defaults to 1200 (60 seconds).

  • speedupAmount: This is the amount of speed-up in each increment. It's multiplicative, movement_speed += movement_speed * speedupAmount, so it accepts a percentage in its decimal form. Default is 0.1.

Convention

The convention for the structure of the extra block is the above list in order.

Equipment

The structure of the equipment block is the following:

equipment:
  OFF_HAND: '{id:"bone"}'
  MAIN_HAND: '{id:"bone"}'
  BOOTS: '{id:"leather_boots"}'
  LEGGINGS: '{id:"leather_leggings"}'
  CHESTPLATE: '{id:"leather_chestplate"}'
  HELMET: '{id:"leather_helmet"}'

The name of each child property corresponds to its equipment slot on a mob. This uses Minecraft's appropriate SNBT for whichever item you want the mob to equip, enclosed in single quotes. To leave an equipment slot as blank, do not include its property in the file.

All armor is cosmetic on our server. The armor value is assigned in the respective attribute field instead.

Note: this is the format that you must use for colored leather: '{id:"leather_boots",Count:1,tag:{display:{color:7613700}}}', where color: is the decimal equivalent of a color's hexadecimal code; in this case, a conversion of base16 '742d04' to base10 '7613700'.

To minimize pain with heads, this is their format: '{id:"player_head",Count:1,tag:{display:{Name:"{\"text\":\"Useless Text\"}"},SkullOwner:{Id:[I;1348936302,2131970044,-1416818425,-2140271418],Properties:{textures:[{Value:"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODZhZWE5ZmQ0OGM3MzAzMDNhMWI5M2NjNTBmM2RiMmEwNTI1MTU2YTJkMGMwMWY1MjIyMjE0NmExMTFlZTQ3MiJ9fX0="}]}}}}'.

Generally, to avoid the horror of trying to debug SNBT, you should copy an existing string for a head and replace both the value within Id:[] and Properties:{textures: [{}]} with the respective values of whatever head you're trying to add to a mob. There is conflicting information online as to whether the Name:{} field is necessary, but you should include it just in case; the text contained within is unimportant.

There is also an alternate form that you would not use for mob config:

equipment:
  OFF_HAND: 
    material: minecraft:bone
    lore: [ 'item lore' ] #optional, also pointless for mobs
    tag: '{NBT data that isn't related to material or lore}' #optional

This is used for when you need to add a description (lore) to an item, meaning that it is unnecessary when trying to equip a mob with it. This is what lobby items would use.

Convention

The convention for the structure of the equipment block is the above list in order. Do not use the alternate form.

Including Count:1 is optional for each item, unless you have NBT tags that follow after — not including it sometimes causes issues in that case.

Attributes

Attributes govern a mob's statistics, and they are largely the same as the ones listed on the Minecraft wiki. There are a couple of exceptions to that:

  • generic.follow_range: This does not do anything on our mobs because we don't use vanilla pathfinding.

  • horse.jump_strength: This won't do anything unless there's a player riding a horse. Horses' jumping is otherwise governed by the jumpHeight child in pathfinding.

  • generic.flying_speed: We currently do not support flying mobs.

  • zombie.spawn_reinforcements: This does nothing. If you want a zombie (or any other mob) to spawn additional mobs, there is a spawn_mob skill that you can use.

We also add some of our own. In general, they are prefixed by phantazm.:

  • phantazm.hitbox_expand: This expands a mob's hitbox for the purposes of shooting it with a gun. It does not have an effect on its "actual" hitbox, i.e. what you'd see in F3 + B. Default is 0, it otherwise accepts a percentage as decimal where hitbox += hitbox * hitbox_expand.

  • phantazm.headshot_multiplier: This determines the damage taken by a mob on a headshot. Its value is a percentage as decimal. Defaults to 1.

  • phantazm.attack_speed_multiplier: This determines the attack speed of a mob where it governs the number of attacks within its given attack cooldown. Defaults to 1.

One thing of note is that our server has a much higher cap for the armor and health attributes than what's listed on the wiki.

Convention

The typical convention for the attributes block is to follow it as outlined in the wiki page. Do not include the useless attribute keys. All Phantazm attributes should be in order after Minecraft's generic ones.

Attribute Modifiers

This is part of the new Damage API. Because of how it works, type resistances cannot be set to a specific number, but must go through the calculations defined in the above page.

In order to emulate a set resistance, you can use damage.[type].multiply_total = -[% as a decimal deducted] and none of the other calculation methods. For example, a 100% resistance to fire would be damage.fire.multiply_total = -1, 25% is = -0.25, and so on. However, consider that this number mightn't be accurate if other modifiers are applied to the same attribute.

A more complex formula with all three resistance methods can be found on the above page.

Convention

Define resistances in the order that damage types appear in on above page.

Skills

Main article: Skills

Goals

The Goals property defines parts of mob behavior and the order that they should be accomplished in.

It accepts a list where each member begins with type: mob.goal_applier.collection in order of priority, i.e. the applier collection that controls mobs breaking out of windows should always be the first member, and each has one or more goalCreators, which is also a list. Applier collections are executed one after another, but the children within one, given that there are multiple goal creators, are executed simultaneously if possible.

This is a standard configuration our current possible goals appear in:

goals:
  - type: mob.goal_applier.collection
    goalCreators:
      - type: zombies.mob.goal.break_window
        breakTicks: 20
        breakCount: 1
        breakRadius: 0.5

  - type: mob.goal_applier.collection
    goalCreators:
      - type: mob.goal.melee_attack
        cooldown: 20
        range: 0.25

      - type: mob.goal.follow_entity
        selector:
          type: mob.selector.entities_in_area
          originSelector:
            type: mob.selector.self
          validator: /alivePlayers
          target: PLAYERS
          limit: 1
        retargetInterval: 20
        followRange: 1024

Our Zombies-specific goal creators are:

  • zombies.mob.goal.break_window: This defines window-breaking as part of a mob's behavior. It has several modifiers:

    breakTicks: Whole number in ticks, measures the time between each attempt at breaking a window.

    breakCount: Whole number, measures amount of blocks broken per attempt.

    breakRadius: Double in block length, measures how far away a mob must be from a window to attempt breaking it.

Our generic goal creators are:

  • mob.goal.melee_attack: If you include this as part of a mob's config, it will perform a melee attack every time its target is in range. It must be coupled with mob.goal.follow_entity for the sake of the selector. It has several modifiers:

    cooldown: Whole number in ticks, measures the amount of time between each attempt at an attack.

    range: Double in block length, measures how far away a mob must be from its target to attempt an attack.

    bypassArmor: Boolean value that determines whether a mob's melee attack ignores its target's armor. Defaults to false, so it isn't typically included.

    Damage is managed by the generic.attack_damage attribute. Skills inflicted with each melee attack are determined by the ATTACK trigger.

  • mob.goal.follow_entity: This enables a mob to pathfind to its target. It has several modifiers:

    selector: Skill selectors

    retargetInterval: Whole number in ticks, measures the amount of time that passes before a mob recalculates the closest match to the selector's validator.

    followRange: Double in block length, measures the maximum distance at which a mob will try to pathfind to a target.

mob.goal.melee_attack and mob.goal.follow_entity should always be part of the same applier collection.

Any of these can be omitted depending on the situation, i.e. a projectile would lack goals entirely and a fully ranged mob would not have the melee attack goal.

Custom Element Paths

Main article: Element paths