JAS Part 5 - ProjectZulu/JustAnotherSpawner GitHub Wiki

Spawntags, Blocks, Foot, solidside, liquid, and more.

#What are spawn tags?

Spawn tags exist in 3 locations of primary concern:

1) Creaturetype.CFG

  • this is where the mob groups are defined. where your caps are for the groups and so on. A spawn tag here would affect all the mobs with the same group name. A spawn tag here is generally setting general perimeters or requirements for the entire group. Yes they can be set in other places, it JAS .

"Spawn Tag": "!liquid({0,0,0},{0,0,0})||!liquid({0,0,0},{0,-1,0})||normal({0,0,0},{0,1,0})",

"This line says spawn unless NOT liquid (spawn in liquid only) at a searchable area of zero or one block directly below it, or unless normal (standard block) above it. The first three grouped numbers represent x,y, and z coordinates where x = front and behind, y represents above and below, and z represents left and right. The second group of three numbers represents the search offset (in case you don't want the search to be directly over the entity." noswanson1982

That is the standard spawn tag for WATERCREATURE but some have had issues with the infamous squid spawning on land. This is most likely caused by a conflicting mod. Since squid are vanilla mobs, something that would conflict with it spawning and cause it to become taken over by the vanilla spawn system could easily cause it to spawn out of control. So, while the standard one usually causes no issues this next one add more search to make sure there is more water blocks around.

"Spawn Tag": "!liquid({2,1,2},{0,0,0})||!liquid({2,0,2},{0,-1,0})||normal({0,0,0},{0,1,0})",

"Now, this should check 2 blocks in front, in behind, to the right, and to the left of the mob before spawning. It should also check one block above and below the mob as well. The mob shouldn't spawn if there is any other block besides liquid within two blocks horizontal to the mob." noswanson1982

Even that could not work depending on your list of mods, but as you understand how the mob system works you will understand what your mods are doing and how to troubleshoot it yourself.

For example: take the squid on land, or the masses of squids spawning in a small space in the ocean.

  1. JAS uses its own spawnlist and empties the vanilla list.
  2. IF a conflict or other issue were to cause JAS to stop taking control of squids it would revert to its original mods control in this case vanilla
  3. vanilla will fill up its spawn cap with squid, which may never happen since JAS is still emptying the vanilla spawnlist but it will still spawn squid.
  4. since it only has squid under its control it will spawn masses of them.

2) EntityHandlers or Living Handlers

  • EntityHandlers is the folder where the Living Handler files are. Living Handler files ARE the CFG files which contain the data on ever mob from every mod. Either as individual files named after the mod they come from, or one giant file that contains all the mob from all the installed mods in one file. This depends on if you have it set to make individual files or one giant one. the outcome and use is the same either way.

Spawn Tags here are also like the creature type tags in that they affect multiple mobs.

for the creeper, its LH entry looks like this.

"Spawn Tag": "(obj.light>4)||!sky()",

SO the creeper should spawn if light is less than 4 OR it can see skY.

If that line were in the creaturetype.cfg it would affect all the mobs in that group, which would also be skeletons, spiders, etc. In the LH file, under the creeper entry means it only affects the creepers. All the creepers in a vanilla world. So this would add to what the entry for the group the creeper belongs to which is MONSTER and looks like this:

"Spawn Tag": "obj.difficulty()==0||!solidside(1,{0,0,0},{0,-1,0})||liquid({0,0,0},{0,0,0})||normal({0,0,0},{0,0,0})||normal({0,0,0},{0,1,0})||!opaque({0,0,0},{0,-1,0})",

We will translate that later, but here we only care that it adds to the creeper requirements it does not change it.

3) SpawnListEntries SLE's

*SpawnListEntries is also the name of a folder, which has CFG files named just like the ones in the EntityHandlers folder.

by default the files in here contain lines like: "Creeper": { "Weight-PassivePackMax-ChunkPackMin-ChunkPackMax": "0-0-0-0" },

And again, you can add spawn tags here as well, in fact, you can add the same one you put in the EntityHandler CFG file

"Spawn Tag": "(obj.light>4)||!sky()",

It has the same affect as well. The difference is in what the SLE is for. SLE entries have to do with spawn weights, passive pack spawns and chunk pack spawns FOR EACH AND EVERY BIOME it is listed in.

Here is where you decide what biomes a mob can spawn in, its weight (percent to spawn vs others in same biome) and pack numbers. so, a creeper can spawn in many biomes and if I were to add that spawn tag to the beach biome entry, the creeper would then have that requirement added for ONLY the beach biome. when it spawns in the flower field biome it has only the creaturetype (or GROUP) spawn conditions.

So I could effectively make different spawn tags for every biome I want the creeper to spawn in. I can also decide what Biomes I want the creeper to spawn in. Maybe I choose only one and it has to be above 120, lol.

Making a whale need to have more water so it's really in the ocean, or keeping mobs from spawning in trees, or making sure the right color of bird from MOC spawn in the right place, or ensuring mobs don't spawn underground when you are above ground to save more resources on your cpu. All this and more are what spawn tags do.

A spawn tag looks like this:

"Spawn Tag": "!solidside(1,{0,0,0},{0,-1,0})||liquid({0,0,0},{0,0,0})||normal({0,0,0},{0,0,0})||normal({0,0,0},{0,1,0})||!opaque({0,0,0},{0,-1,0})"

It might seem long, at which point I say "seems?", it is long. We will dissect this line.

###Spawn Tag Elements Spawn Tag. Well, we pretty much got this from previous sections, or do we ?

REMEMBER: JAS's mentality when interpreting instructions is....

####Common Elements used in tag lines

0 = DOWN
1 = UP
2 = NORTH
3 = SOUTH
4 = WEST
5 = EAST

INTEGER elements are simply a number i.e. 1

BOOLEAN True and False are reserved keywords true and false respectively

== Equality operator, to compare if two numbers are equal i.e. sky()==true

Not operator, to reverse a boolean value is ! i.e. !sky()

OR operator is simply || i.e. solidside(1,{0,0,0},{0,-1,0})||liquid({0,0,0},{0,0,0}).

AND operator is simply && i.e. solidside(1,{0,0,0},{0,-1,0})&&liquid({0,0,0},{0,0,0}).

Strings are marked using Single quotation marks '' i.e. 'Skeleton'.

Arrays are marked using by curly opening and closing braces and a comment between each element i.e. Three integer elements would be {1,2,3}

Access to the following methods are provided and accessed in the form "Spawn Tag": "sky()". If a specific size array is marked with the form [N] where N is the number of values required. If unlimited it will say N. Typically 3 and that means X,Y,Z coords/range/offsets. If 2 it would mean min/max or X/Z (i.e. biomes which are same no matter Y).

Behaviours

Tags can be attached to Creature Types, Living Handlers, and Spawn List entries. The behaviour effected depends on the field the tag is attached to. Each entry type does not support all of the aforementioned behaviours.

The following is an overview of the tags. Beginners will want to start at the Example configuration files for in-depth explanations with examples.

Entry Type Field Rtn Value Effect
CreatureType "Spawn Tag" Boolean [***] Whether Entity of the TYPE's spawning should be interrupted. i.e SPAWN entity unless EXPRESSION is TRUE
LivingHandler "Spawn Tag" Boolean [***] Whether Entity's spawning should be interrupted. i.e SPAWN entity unless EXPRESSION is TRUE [**]
"Despawn Tags" Boolean [***] Whether Entity's despawning should be interrupted. i.e DESPAWN entity unless EXPRESSION is TRUE
"PostSpawn Tags" Boolean [***] Used to writeNBT data after immediately after an entity is spawned [*].
"Entity Tags" Boolean [***] Used to writeNBT data after immediately after an entity is spawned [*].
"Entity Tags" String [***] Overrides what Entity this LH should spawn. Expects a String value, a JAS entity mapping.
SpawnListEntry "Spawn Tag" Boolean [***] Whether Entity of the this BIOMEGROUP's spawning should be interrupted. i.e SPAWN entity unless EXPRESSION is TRUE [**]
"PostSpawn Tags" Boolean [***] Used to writeNBT data after immediately after an entity is spawned [*].

[*] : Note that writeNBT can be done during the Spawn Tag for MOST entities. MoCreatures entities were the reason this capability was added.

[**] : LivingHandler and SpawnListEntry conditions are combined with either OR or AND depending on the value of the LivingHandler "Spawn Operand"

[***]: Absent if empty

Behaviour examples

# Example Tag Interpretation
1 "Spawn Tag": "true" Entity should spawn
2 "Spawn Tag": "false" Entity should not spawn
3 "Spawn Tag": "sky()" Entity should spawn unless it can see sky
4 "Spawn Tag": "!sky()" Entity should spawn unless it can see not sky

###Blocks are Real

####Definition

''boolean block(String[N] blockKeys, Integer[3] searchRange, Integer[3] searchOffsets)''
''boolean block(String[N] blockKeys, Integer[N] metas, Integer[3] searchRange, Integer[3] searchOffsets)''

  • '''String[N]''' means JAS expects to receive N names (no limit, you decide) specified in an array: surround your list of block names with {}, enclose each separate name within single quotes and separate with commas. The last item should not have a comma after it. See examples below.

  • '''Integer[3]''' means JAS expects to receive exactly 3 numbers (your search ranges, on the X, Y and Z axes) in an array. Do not enclose numbers in quotes.

  • '''blockKeys''' refers to the name of any Minecraft blocks. For vanilla block names, check the Minecraft wiki Blocks page. ** Modded blocks are also accepted in the usual format ''modname:blockname''.

  • '''metas[N]''': optional. If you need to refer to a specific block value via its metadata, specify it in an array; put down 1 value required per block name, in the same order.

  • '''searchRange''' is how far away you want to check ''both in forward and reverse direction''. For example, specifying {1,2,3} here means JAS will check 1 blocks in front and behind = total 2 on the X axis, 2 blocks up and down = 4 blocks on the Y axis, 3 blocks left and right, total 6 on the Z axis. ** searchRange can be 0 for all 3 axes, which tells JAS to only check the single block in which a mob is located.

  • '''searchOffsets''' moves the search sphere defined above by a number of blocks in the direction specified. This can be useful to avoid checking belowground or aboveground, for a surface-dwelling mob. ** searchOffsets can be 0 for all 3 axes, which tells JAS to center the check on the mob itself.

####Examples

  • block({'glass'},{8,8,8},{0,0,0}) ** Search for glass within 8 blocks centered on the MOB along all axis (x,y,z).
  • block({'fence','nether_brick_fence'},{8,1,8},{0,0,0}) ** Search for those 2 types of fence up to 8 blocks away front/behind, left/right (X and Z axes), and 1 block up/down (Y axis), again starting centered on the mob.
  • block({'leaves','leaves2'},{0,3,0},{0,3,0}) ** Search for leaves up to 6 blocks ''above'' the mob: the search will occur for 3 blocks up/down as specified in searchRange (6 blocks total), but the zone being checked starts 3 blocks above the mob.

###BlockFoot

####Definition

''boolean blockFoot(String[N] blockKeys)''
''boolean blockFoot(String[N] blockKeys, Integer[N] metas)''

####Examples

  • blockFoot({'dirt','BiomesOPlenty:driedDirt','grass','sand','stone','cobblestone'}) ** Checks that the mob is, or would be standing on any of these blocks.

  • !blockFoot({'dirt'},{2}) ** Checks that the mob is/would '''not''' be standing on podzol.

###Solidside

There are many other commands, but solidside is the most commonly used, and asked about command in the forum.

The format for solidside is as follows:

  • boolean solidside(Integer side, Integer[3] searchRange, Integer[3] searchOffsets).

-----Boolean solidside(--------1-------,-----------{2,3,4}-------------,----------{0,-3,0}-------------)

We break the line down as follows.

boolean - The result of our search for a solidside block will be boolean (true or false)

solidside - look for a solid side of a block

Integer side, - Which side of the block are we checking to see if it's solid (1 = up, or top)

Integer[3] searchrange - Integer[3] means [x,y,z] axis, so it really asks "how far on each axis to search (from the *spawnpoint). 2 on the x axis, which is in BOTH directions so a total of 4 (2 in front and 2 behind). 3 on the y axis for a total of 6 (3 up and 3 down) and finally 4 on the z axis for a total of 8 (4 left and 4 right)

Integer[3] searchOffsets - The offset location of the spawnpoint This is essentially MOVING the spawnpoint so the searchrange would actually be moved (not to spawnpoint, remember we are looking for a block with a solid top) so the spawnpoint remains the same, but we are adjusting the ranged that it will be looked for by... 0 blocks on the x -3 blocks on the y (3 blocks down) 0 blocks on the z

So the above example would encompass 18 blocks in its search for this block with a solid top and it would not use the spawnpoint as its center but 3 blocks below the spawnpoint.

Now, with all that information, we are still asking a question as indicated by our BOOLEAN command in front. so, if our giant question resulting in finding nothing, the results would be put in the form of our first command (boolean) and since it asks for a true or false result, the result returned would be false.

CrudeDragos:

Some additional notes on how solidSide works. This is set by the block itself. Default properties in all blocks until overrides:

A block side is solid if:

  • BlockSlab: All sides if DoubleSlab OR TopSide if Upside Down slab (top half of voxel occupied)
  • BlockFarmLand: The top and bottom are not solid
  • BlockStairs: If flipped, upside is always solid. East/West/North/South are solid if the solid side of the stair is

on that side of the voxel. Otherwise not solid.

  • BlockSnow: All sides if the block is a full Snow Block, otherwise none.

  • BlockHopper: Always Side Up is solid, otherwise see isNormalCube below.

  • BlockCompressedPowered: All sides solid.

    Otherwise it is a call to isNormalCube which by default means(material IS Opaque*) && (renderAsNormal**) && (does NOT provide power***)

    • Obviously can be set by material. Generally though, False if translucent, is True if NOT Translucent & material blocks movement (So if you cannot see through it and it blocks movements, note TNT is considered translucent and thus not Normal)

    **renderAsNormal=If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)

    ***Can this block provide power. Only wire currently seems to have this change based on its state.

###Liquid - Normal - Opaque

####Definition

''boolean normal(Integer[3] searchRange, Integer[3] searchOffsets)''
''boolean opaque(Integer[3] searchRange, Integer[3] searchOffsets)''
''boolean liquid(Integer[3] searchRange, Integer[3] searchOffsets)''

  • '''Normal''' is one of several block properties. By default, normal means the block is opaque, is rendered visually as a standard block, and does not supply power. This property can be changed by modders however, and its value for modded blocks may not be coherent with what it means for vanilla Minecraft.

  • '''Opaque''' checks whether a block is defined as completely opaque or not internally, rather than visually. For example, while texture packs can change a block's appearance, they cannot alter properties defined by a mod author; the authors decide if their blocks are truly opaque or not. Refer to your mod documentation/forums for more info on modded block properties.

  • '''Liquid''' checks if a block is actually a liquid: water, lava, Buildcraft oil/fuel, any other modded liquids are probably included (check with your mod documentation in case of doubt.)

  • See Blocks are Real for an explanation of expected parameters and types.

####Examples

  • normal({0,0,0},{0,1,0}) ** Checks if the single block above the mob's location is a normal cube.

  • liquid({0,0,0},{0,0,0}) ** Checks if the mob is currently standing in 1 block of liquid.

  • opaque({0,0,0},{0,-1,0}) ** Checks if the block located 1 below the mob is completely opaque.

#Event Spawns

Enabled as of Just Another Spawner v0.17.0

Event spawns are MVEL expressions capable of spawning entities that are triggered at particular occasions that occur while playing Minecraft. Similar to how Chunk spawning occurs whenever a new chunk generates, users may cause special spawns to occur at specific events. Chunk spawning is not considered an event spawn.

Each event spawn entry consists of a TRIGGER and an EXPRESSION. The expression is an MVEL expression with different functions depending on which trigger is being called.

Triggers

Simply put, its something that starts an action. You pull a trigger, a bullet comes out.

Trigger Value Called When
LIVING_DEATH any entity dies
SLEEP a players click on a bed to attempt sleep
BREAK_CROP a block is broken that is an instance of the IGrowable
BREAK_TREE a block is broken that is a BlockLog or wood

Event Spawns. Ability to spawn entity upon certain conditions being triggered. Currently 'LIVING_DEATH', 'SLEEP', 'BREAK_CROP', and 'BREAK_TREE'.

File Format

Configured under folder EventSpawns in WorldSettings. Any fileaname with a .CFG extention will work. File consists of array of elements each containing two fields TRIGGER and EXPRESSION. Trigger is when the expression will be evaluated. Expression determines what, if anything, will spawn.

i.e. 'Sleep' Trigger spawns Zombie within 5 blocks of player when he attempts to sleep. 'Living_Death' trigger spawns 2 zombies whenever one zombie dies.

[
  {
    "trigger": "SLEEP",
    "expression": "spawn('Zombie').offset(5)"
  },
  {
    "trigger": "LIVING_DEATH",
    "expression": "spawn('Zombie').offset(5).alsoSpawn('Zombie',0,0,0)"
  }
]

Functions

Living Death Functions

Access to common functions under the 'obj', 'lgct', 'util', 'wrld', and 'time' categories.

Return Value Function Call and Arguments Purpose
boolean isPlayer() Returns whether the Dead entity was a Player
String livingName() Returns whether the name of the dead entity
boolean isDamageSource(String desiredDamageSource) Checks if the damage source was the one provided: i.e. inFire, onFire, lava, inWall, drown, starve, cactus, fall, outOfWorld, generic, magic, wither, anvil, fallingBlock, mob, player, arrow, thrown, indirectMagic, thorns
boolean isProjectile() Checks if the damage source was a projectile
boolean isExplosion() Checks if the damage source was is explosive
boolean isFireDamage() Checks if the damage source was fire
boolean isMagicDamage() Checks if the damage source was magic
SpawnBuilder spawn(String entityMapping) Create a Spawn object that JAS uses to spawn an entity must be on the last line or call 'return spawn(...'

Break Crop and Break Tree Functions

Access to common functions under the 'obj', 'lgct', 'util', 'wrld', and 'time' categories.

Return Value Function Call and Arguments Purpose
String blockName() Name of block
boolean blockMeta() Meta value of block
int isMaterial(String materialName) If Block is specified material
String material() Name of current material
boolean isBlock(String blockName) if Block is provided name
boolean isBlock(String blockName, int blockMeta) if Block is provided name and meta
SpawnBuilder spawn(String entityMapping) Create a Spawn object that JAS uses to spawn an entity must be on the last line or call 'return spawn(...'

Player Sleep Functions

Access to common functions under the 'obj', 'lgct', 'util', 'wrld', and 'time' categories.

Return Value Function Call and Arguments Purpose
boolean sleepResultOk() If sleep attempt result is OK
boolean sleepResultNotSafe() If sleep attempt result is NOT_SAFE
boolean sleepResult(String result) Check if sleep attempt result matches provided string
EnumStatus getResult() Sleep attempt result OK, NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW, TOO_FAR_AWAY, OTHER_PROBLEM, NOT_SAFE;
SpawnBuilder spawn(String entityMapping) Create a Spawn object that JAS uses to spawn an entity must be on the last line or call 'return spawn(...'

SpawnBuilder Functions

The object returned by the spawn(...) function is a special class that allows multiple functions to be called on it in a row. i.e. in the expression spawn('Zombie').offset(5).alsoSpawn('Zombie',0,0,0) both functions offset and alsoSpawn are functions of SpawnBuilder.

Return Value Function Call and Arguments Purpose
SpawnBuilder offset(int radius) Randomly moves the spawn point within the XZ within a radius of 5 blocks
SpawnBuilder offset(double spawnPosX, double spawnPosY, double spawnPosZ) Moves the spawn point by the values provided
SpawnBuilder alsoSpawn(String entityMapping, double offsetX, double offsetY, double offsetZ) Spawn an additional entity at an offset of the original
⚠️ **GitHub.com Fallback** ⚠️