Page 1 of 2
[Script] - Smart Spawner
Posted: Wed Oct 17, 2012 11:03 pm
by Xanathar
Hi all, following is a script for a "smart" spawner.
Code:
Code: Select all
function countEntitiesOfTypesInLevel(spawnedEntityNames, level)
local count = 0
for e in allEntities(level) do
for _, t in ipairs(spawnedEntityNames) do
if (e.name == t) then
count = count + 1
end
end
end
return count
end
function partyDist(x, y)
return math.abs(party.x - x) + math.abs(party.y - y)
end
function spawnChecked(level, spawners, spawnedEntityNames, maxEntities, minDistance)
if countEntitiesOfTypesInLevel(spawnedEntityNames, level) >= maxEntities then
return
end
local spawner = spawners[math.random(1, #spawners)]
local dist = partyDist(spawner.x, spawner.y)
if dist < minDistance then
return
end
spawner:activate()
end
Usage:
- Put it into a script entity in one (and only one) level in the dungeon, doesn't matter which, called "smartSpawning"
- Call it with smartSpawning.spawnChecked(<level>, <table-of-spawners>, <table-of-monsters>, <max-monsters>, <min-distance>) from a timer, pressure-plate or other activating device
Example:
Code: Select all
function spawnGo()
local spawners =
{
lvl5spawner1,
lvl5spawner2,
lvl5spawner3,
lvl5spawner4,
lvl5spawner5,
lvl5spawner6
}
smartSpawning.spawnChecked(5, spawners, { "spider" }, 16, 7)
end
Features:
- Spawns choosing a random spawner from the list
- Doesn't spawn if there are already <max-monsters> spawned entities in the level
- Doesn't spawn if the picked spawner is under <min-dist> distance from the party (to avoid seeing monsters appearing out of nowhere)
Let me know of any issue - I'll post to the wiki soon.
Re: [Script] - Smart Spawner
Posted: Thu Oct 18, 2012 1:21 am
by zeltak
Thank you! Have to test this out. I was pondering something like this myself, but it was just ouside my scripting skills.
edit: any ideas how to incorporate monster levels into that script? I mean if I would like to spawn level 3 crowerns for example.
Re: [Script] - Smart Spawner
Posted: Thu Oct 18, 2012 11:12 am
by Xanathar
First of all, read this post from Grimwald about designing spawners for high level monsters:
viewtopic.php?f=14&t=3770&sid=2c140181a ... ebc#p38581
And define, say, the "level2_snail", "level3_snail" etc.
Then, let's say you want to have a 25% chance of spawning a level 5 snail and 75% chance of spawning a level 3 snail:
1) Create 2 spawners (let's call them lvl5snailspawn and lvl3snailspawn)
2) Use a non-equally distributed table when passing spawners to the function:
local myspawners = { lvl3snailspawn, lvl3snailspawn, lvl3snailspawn, lvl5snailspawn}
smartSpawning.spawnChecked(3, myspawners, { "level3_snail", "level5_snail" }, 12, 9)
Re: [Script] - Smart Spawner
Posted: Thu Oct 18, 2012 12:16 pm
by Grimwold
Great script. Thanks for sharing this. One possible enhancement would be to change the spawned entity on-the-fly and have the script randomly choose entity and spawner independently
So you'd include something like this (untested)
Code: Select all
local spawnedEntityName = spawnedEntityNames[math.random(1, #spawnedEntityNames)]
local spawner = spawners[math.random(1, #spawners)]
spawner:setSpawnedEntity(spawnedEntityName)
spawner:activate()
and you would call it with something like:
Code: Select all
smartSpawning.spawnChecked(5, {spawner_1,spawner_2,spawner_3},{"crowern","crowern","crowern","wyvern"},16,5)
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 9:28 pm
by Ixnatifual
I've got 3 snail spawners and are using the following.
Code: Select all
function spawnGo()
local spawners =
{
spawner_156,
spawner_160,
spawner_157
}
smartSpawning.spawnChecked(14, spawners, { "snail" }, 2, 1)
end
As I understand it at most 2 snails are supposed to be in the level at one time given the above. Yet it seems to keep endlessly spawning snails. Am I missing something here?
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 9:50 pm
by HaunterV
hmm I think I like this. Since the spawners have no ai on the go, If you control when a monster spawns you reduce the number of monster AIs running in the background.
I mean, Ive noticed all teh monsters in your dungeon will run around doing their own thing which to me means the computer is tracking their movements n such even if the player cant see them. This must be needless CPU usage, or at the very least a spot that could do with some optimization, which I think this idea helps get a handle on.
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 9:57 pm
by Ixnatifual
Think about it this way:
- Monsters on levels outside the one you're at are probably updated a lot less frequently, similar to how scripts running on different levels work. The further away from your level, the less frequently they are updated.
- A game like StarCraft can have hundreds of units off-screen being controlled with super frequency with no slowdown issues.
That being said, completely filling levels with monsters the player may never see probably isn't so smart.
Edit: I just tested monster movement in my dungeon - I went to level 14 and looked at the monsters through the editor map at level 1. It took like a minute for a monster up there to move even a single square. So the game seems to have its own smart method of reducing CPU load for less relevant monsters.
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 10:15 pm
by Ixnatifual
Ixnatifual wrote:As I understand it at most 2 snails are supposed to be in the level at one time given the above. Yet it seems to keep endlessly spawning snails. Am I missing something here?
I called the script thinking I was on level 14, when really I was on level 15. Since no snails were on level 14 the conditions for spawning extra snails kept being true.
On the plus side I learned some extra LUA from debugging effort.
This part
Code: Select all
for e in allEntities(level) do
for _, t in ipairs(spawnedEntityNames) do
if (e.name == t) then
count = count + 1
end
end
end
seems kind of heavy duty, though. Even on a super simple level it looped the second for 117 times. I tried on one of the larger levels and it was a whopping 1968! If only there was an allMonsters function instead of allEntities.
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 10:51 pm
by Xanathar
I just tested monster movement in my dungeon - I went to level 14 and looked at the monsters through the editor map at level 1. It took like a minute for a monster up there to move even a single square. So the game seems to have its own smart method of reducing CPU load for less relevant monsters.
If I remember a petri post correctly:
- The level you are in is updated every frame
- The level above is updated every odd frame
- The level below is updated every even frame
- All other levels are updated in a round-robin fashion
But I might have completely misunderstood that post and/or remember it wrong.
Re: [Script] - Smart Spawner
Posted: Thu Dec 13, 2012 10:54 pm
by Xanathar
Even on a super simple level it looped the second for 117 times. I tried on one of the larger levels and it was a whopping 1968! If only there was an allMonsters function instead of allEntities.
Another solution could be to keep the count at the spawn and in the onDie hooks, but then one must be aware of monsters falling in pits which could alter the count (so maybe also keep count in onMove). If there is a real performance problem it might be worth rewriting it with jkos hooks this way.