spawns
Spawns is a plugin for Bukkit and Minecraft that allows you to fully customize the spawning behaviour of mobs on your server.
Features
- tweak the default Minecraft spawns or replace them completely
- set mobs to spawn under conditions they never normally would
- block certain mobs from ever spawning
- cause mobs to spawn with potion effects, equipment, saddles, etc.
- cause mobs to spawn in different variants, like powered creeper, wither skeleton, etc.
- mobs appear in the world in the same way as they do normally, so are compatible with all other plugins
Dive right in here to see how to make config files or keep reading for an overview of Minecraft spawning.
Default spawning
Minecraft spawning works like this:
Every spawn cycle (1 tick or 1/20 second by default for hostile mobs) the game makes a list of all the chunks around each player, up to a radius of seven chunks. Each chunk will only be counted once, even if that chunk is around several players.
Once this list is complete a mob limit is calculated. The limit is higher the more chunks are in the list. If the limit is lower than the current amount of a mob type in the world then the cycle will be cancelled.
If the limit is not yet reached a random block from each chunk in the list will be calculated and this chunk will be used as the centre point for a pack of mobs to spawn around. In order to continue, this block must be water for water mobs (only squid so far) and air for any other type of mob.
If this block is suitable then a maximum of 12 random blocks are chosen from up to 20 blocks away, but always at the same height as the centre block.
Lastly, The individual blocks are checked that they can physically fit the mob, so they need to be air, have air above and an opaque block below. The type of mob is chosen based upon the matching conditions (biome, height, floor block type, etc.) and the final mob is chosen randomly from all mobs that are eligible to spawn there. All other mobs in the pack will be the same type.
Permissions
spawns.can-reload-config, which allows the user to reload the config. Default is Op.
spawns.can-count-mobs, which allows the user to display a summary of mob amounts in a world. Default is Op.
Commands
/reload-spawns, or /rs, which reloads the config without having to reload the server. Any mobs already in the world will be unaffected by any changes in the config.
/count-mobs, or /cm, which displays a list of mob numbers in the world. Add a world name argument to specify a world (optional if run as a player) and / or a mob type argument to choose one type of mob to count.
Update checking
If you like, you can set the plugin to check for any newer versions that get released. To do this add an element to the config.xml file, like this:
<check-for-newer-version/>
When this element is present the plugin will report if it finds a newer version. This only works for release builds so you won't be bothered by any beta or dev builds. To disable this checking simply remove the element.
Note that no update will be downloaded even with this set.
Examples
I would love to get any example config/packs/mobs files you have created to add to the docs, so if you have one you're proud of send it in and I'll add it.
spawns took a lot of work, so if your server is enriched by it please consider sending some love my way!
<a href="https://www.paypal.com/cgi-bin/webscr?return=http://dev.bukkit.org/server-mods/mobs/&cn=Add special instructions to the addon author(s)&business=apodlesna@gmail.com&bn=PP-DonationsBF:btndonateCCLG.gif%3ANonHosted&cancelreturn=http%3A%2F%2Fdev.bukkit.org%2Fserver-mods%2Fmobs%2F&lc=US&itemname=spawns+%28from+Bukkit.org%29&cmd=donations&rm=1&noshipping=1¤cycode=USD"><img class="aligncenter" alt="donate" src="https://www.paypalobjects.com/enUS/i/btn/btndonateLG.gif" /></a>
If you're penniless or like spawns but not that much I'm also partial to TF2 items. Send any you don't want my way! STEAM id: coldntired
If you don't know what TF2 is, then start playing! It's free and fun!
For other projects, links, help, etc. please visit the main website.
You can also follow sylian.eu on Twitter for updates.
-
View User Profile
-
Send Message
Posted May 10, 2014@coldandtired
Sorry databases is my weak point too so can't really help there :P
Basically just wanted to add (to my previous post) that, yes, in theory it should probably work, but the choice of collection could be a bit tricky. You want fast add, fast remove, and you want to be able to add/remove in the middle of an iteration over the collection (so you can split the iteration over several ticks). Might exist better solutions, but of the top of my head ConcurrentSkipListMap comes to mind. It does these things, with one "drawback": iteration might miss some objects if they are added during the iteration. This should probably not be a problem though because I believe you only need approximate numbers? So if it reports say, 300, but the correct number is 290 or 310 it probably isn't an issue right? (This error wont accumulate over time - it's just a bit fuzzy.)
-
View User Profile
-
Send Message
Posted May 10, 2014@AnorZaken Sounds like it might work :)
My current plan I'm implementing as a test is to store every mob in a database as it spawns and then every tick grabbing all the rows which match mobs currently in the world (loaded chunks) and then a sub query on that set formed from the condition(s).
Pseudocode worldMobs = select all rows with id matching mob.uniqueid return worldMobs with tag of x and spawnsId of y.count
Sadly, I know almost nothing databasey so have to think in LINQ and try to find a Java alternative!
-
View User Profile
-
Send Message
Posted May 10, 2014@coldandtired
I haven't properly looked into the despawning problem, and one would hope there is a better way, but I can think of one way to count mobs that would (sort of) work (unless there is a memory leak somewhere). But it is a bit complicated and requires understanding of weak references and garbage-collection.
Basically whenever an entity gets spawned you could store it in a WeakReference (that WeakReference being registered to a ReferenceQueue that you've made) that in turn gets stored in a collection of appropriate sorts. The basic working principle of this solution is that once the entity despawns it will soon* (*usually - and only if there is no memory leak somewhere else - like in another plugin for example) be garbage-collected, which will cause the garbage collector to add the corresponding WeakReference-object to your ReferenceQueue. That means that you can poll this ReferenceQueue from time to time, and the number of elements in this queue is the number of entities that got garbage-collected since you last checked and emptied the queue (use the WeakReference-objects in this queue to remove the strong references to the WeakReferences-objects - aka to remove them from the collection you used to store WeakReferences - otherwise you will accumulate and have a memory leak of these objects :P).
tl;dr: Use the garbage collector to do the work for you and notify you of entities that has disappeared.
See this java article for a much better explanation than mine! :P
You could of course combine this with manual checks: every tick you could check a few of the entries in the collection (of WeakReferences), 1. Try to retrieve them (if not they have been garbage-collected) 2. if retrievable, check if they are dead or some other stuff, if so remove from collection and do other appropriate tasks. But basically the idea in this case is that you don't need to loop through the whole collection every tick, just check a few, store the index (or similar), and continue where you left of the next tick. This way performance can be tuned on the fly even: if server is lagging you could try to detect this and do less processing each tick. And since you are using WeakReferences storing all entities in a collection isn't a problem / memory leak.
Instead of being forced to hold up the main-thread to count all mobs this can allow the counting to be split up over several ticks in a safe way (there are pitfalls!). So it might be worth testing out.
-
View User Profile
-
Send Message
Posted May 10, 2014@coldandtired
Do as you wish with it, I think it will mostly be useful to you anyway - as soon as 1.7.2b6 gets approved it wont be much use to most people. :P
It's open source and free to use. (I forgot to include a license file but SpawnsSpawnFix.java ...lets say thats public domain because it's not a big deal, the aztb-classes though are part of a larger collection of tool-classes, they are creative-commons-attribution - aka do anything as long as I get credit for them.)
Regarding the chunk unload - I'm not sure, but I would think a RemoveWhenFarAway-enabled mob can despawn without the chunk getting unloaded. Don't take my word for it though...
-
View User Profile
-
Send Message
Posted May 10, 2014@johndcastro The problem with your config is that you have MC spawning disabled, so the only way for mobs to appear is through Spawns and other plugins/player commands.
You only have one timer with will start if the world has 3 or fewer mobs per player in it.
What this means is that unless you have mobs coming into the world somehow (through another timer, for example) the condition will never be true if it isn't already.
Better is to specify a maximum number of mobs under which the timer will start and once this number is reached it will stop spawning until a few of them are killed/despawn.
-
View User Profile
-
Send Message
Posted May 10, 2014@AnorZaken Busy morning! :)
I've updated the wiki as you mentioned. Much prefer it to the old Wordpress way!
I'm also subscribed to the chunk load/unload event which adjust the mob counter so it seems something isn't working as it should be :( This still won't handle mobs removed without going through the API though so I might just go back to the old way and find the sweet spot for counting without bogging sown the server too much.
Thanks for your plugin. I'd already made the change to spawning in the block centre in 1.7.2 b6 and 1.7.9 b2 but they are still awaiting approval. Your link will almost certainly be deleted by staff soon - do you want me to put up a page on the wiki for it?
-
View User Profile
-
Send Message
Posted May 10, 2014Made a small plugin to (partially) fix, and optionally help debug, Spawns.
Aside from the debug stuff it adjusts the spawn location for Spawns mobs so they spawn in the middle of blocks. The plugin is called SpawnsSpawnFix.
(It is made for Spawns 1.7.2 b5 and MC 1.7.2 - I haven't tested it on any other version.)
It runs in debug-mode by default, and will print out A LOT of messages in the console.

It can look something like this:
(Click to enlarge)
It has 3 commands that all require op, and of which 2 only are for debug-mode:
For debugging it can be nice to disable spawn-messages with ssfs and then wait for death messages (two of which can be seen in the above example) and use ssftp to tp to the location where that mob died. In other words it's a handy tool to teleport to and inspect the locations where Spawns-mobs actually spawn.
ssftp keeps track of the 512 most recently spawned Spawns-mobs. This is only done in debug-mode - "Normal"-mode is very lightweight. (Debug-mode can be disabled in the plugin config.)
I'm obliged to raise attention to the fact that this plugin has not been uploaded to and inspected by bukkit - use at your own risk.
Now that we've got that technicality out of the way... [MOD edit: Removed unapproved link]!
Hopefully this will be useful to you (or someone else). The code is very simple so if it doesn't work with the 1.7.9-version it can probably be fixed by doing only 2 or 3 small and easy changes. Oh, right! Almost forgot to mention: It's open-source and all the source is included inside the jar! If there is any questions, you want me to explain the code or whatever, just ask!
-
View User Profile
-
Send Message
Posted May 9, 2014btw. spotted a tiny mistake in the documentation for hubs
notice lack of '/'. (will ofc cause a crash)
Also may I recommend adding
...to timers page, similar to how
...is added the hubs-page. (Easier to read/learn.)
-
View User Profile
-
Send Message
Posted May 9, 2014@coldandtired
Well the mobs can disappear without dying can't they?
If you're only listening to death events then aren't you going to miss all the "despawned" mobs?
Well... "despawned" is a relative term here...
Might or might not be what you intended...
See this.
(I do believe RemoveWhenFarAway = true would indeed despawn the mob though - with no event afaik.)
-
View User Profile
-
Send Message
Posted May 9, 2014Hello @coldandtired, we are really enjoying your plugin. We are having an issue with the timer not starting when world-has-spawned is set in the Start-If section. Below is my example of it <start-if> <world-has-spawned per-player="Yes">..3</world-has-spawned> </start-if>
If I remove that it works great however mobs will continue to spawn and we are trying to limit the total number of mobs so we don't get overloaded. My goal is to control the number of mobs within a player hub. So I do have the hub has spawned in the hub sections to move on however I am finding once it ends the timer just kicks back on again and keeps spawning. Any update would be greatly appreciated.
Just in case here is a pastie of my testing world.xml http://pastie.org/9160593 with just the one timer in it for now
-
View User Profile
-
Send Message
Posted May 8, 2014@shaythegoon This is what I'm looking into tomorrow. There is code that should remove any mobs from the counter when they die, but I'm not sure why it isn't working as it's supposed to.
Possibly I'll go back to the old way, which was to count the mobs every 5 seconds.
-
View User Profile
-
Send Message
Posted May 8, 2014hmmm, still getting a problem with <world-has-spawned> After the mobs have reached the limit they never spawn again, until I re-log the server or shut it down completely. Was this the original intention...
shaythegoon
-
View User Profile
-
Send Message
Posted May 8, 2014@coldandtired
thanks, it just means I can have <blocks>x:y:z,x:y:z</blocks> for individual packs, which means I can use less timers, i think xD
shaythegoon
-
View User Profile
-
Send Message
Posted May 8, 2014@shaythegoon I believe you can do
which would mean "if location is 2:20:35 or 28:10:42 then..." but I can add a single condition for you.
-
View User Profile
-
Send Message
Posted May 8, 2014@AnorZaken I can't find a way to avoid that bug. No matter what I try it seems the file gets read properly but then that parse exception is thrown :(
I've built a 1.7.2 version of the new config for you which is being checked now. I would recommend it over the old version if it does what you need (it should, I don't think I left anything out when I changed the configs).
-
View User Profile
-
Send Message
Posted May 8, 2014Hey Cold,
Is it okay if you change the <x><y><z> conditions into something similar to the <block> thing for the Hub. This is because the x y and z conditions can't be "Paired" or "Grouped" together like the <block> tag can (eg: <block>x:y:z,x:y:z</block>)
thanks
Shaythegoon
-
View User Profile
-
Send Message
Posted May 8, 2014@coldandtired
No problem, I'm basically helping myself since the server I'm playing on is using your plugin! :P
To answer your question: yes, everything works fine once I removed the '#'. (I didn't bother testing other rarely-used-but-valid-in-folder-and-filename symbols - only changed my folder name.)
P.S: I think that spiders still need 2 blocks wide spawn-space, so spawning spiders 1 block away from walls is probably still a good thing - would assume horses need at least 2x2x2 too, maybe more? But it would be bad if zombies and such "thin creatures" never spawn in 1-block narrow passage-ways that players tend to dig out while mining.
(Fun-fact: If I'm correct the minecraft codes Entity-class has a width, height and length property, but bukkit doesn't expose them... didn't dig around very deep not sure why.)
-
View User Profile
-
Send Message
Posted May 8, 2014@AnorZaken Thanks for the great comment!
I'l test the first thing later today. I've never heard of that happening before. Did everything work correctly when you removed the # sign?
For the second thing, I wasn't aware of that. The newer version simply spawns things one block away from walls but your way would be far easier :)
Thanks again. I'll see if I can build the newest version with 1.7.2 without problems and give you a choice.
-
View User Profile
-
Send Message
Posted May 8, 2014Was going to do some work with Spawns (for a private 1.7.2 server) when I stumbled on an obscure bug in your loadConfig-code:
line 236 Spawns.java (1.7.2 b5):
This can cause a very misleading SAXParseException even if there is nothing wrong with the xml-file. Took me a while to track down the true cause, but it turns out it can't handle all types of paths. In my case the absolute path was: "H:\#TESTSERVER2" and that will crash your plugin with a SAXParseException...
"lineNumber: 1; columnNumber: 1; Content is not allowed in prolog."
...because of the '#' in the path.
(Have not tested this in your latest version because I'm only interested in 1.7.2)
Not going to look into this issue any further since I will just change the path. But might be very helpful to know in case you want to try and fix it / others are getting this exception and can't find the cause.
Pastebin if you're curious, but should be super easy to reproduce yourself...
Spawns path-related xml parsing error
(Clean server, no other plugins, empty world, packs.xml freshly auto-created by your code - never edited.)
Oh, right... and what I was actually looking into:
Your understanding of the coordinate system in minecraft seems to have one small but crucial flaw... To spawn something on the middle of a block you need to add +0.5 to the x- and z-coordinate. Your code (1.7.2 b5) is currently spawning stuff on the North-West corner of blocks, causing mobs to quite often die of suffocation in caves or steep hill/cliff/mountain areas.
Basically just go ingame, activate the F3-overlay, look straight down, position yourself on the middle of a block and you will see this. (Also many bukkit-commands like /tp adds +0.5 automatically for convenience... try using /tp but instead of "/tp x y z" type /"tp x.0 y.0 z.0" and you will end up on the North-West corner of that block.)
I can send you my debug code for this if you are interested...
-
View User Profile
-
Send Message
Posted May 7, 2014@shaythegoon Not quite. Did you kill it the normal way (i.e. not with a command)?
I had a report it wasn't working quite right so I will investigate tomorrow.