Time for a little payoff, now that we have the violent info at hand.
Interpersonal Conflict
Ok, yesterday was a bit of a letdown; once we were done, the visuals just looked exactly the same as they had before. But now we can prove that Knowledge is Power and show more of the action. Damage indicators seems like a good start.
In order to test out results quickly, we’ll need to foment a little discord on this mostly-peaceful map. Let’s talk to the SQL server (edited a bit for conciseness):
> SELECT npcID, name FROM NPC WHERE name='Sven';
npcID name
----------- --------------------------------------------------------------------------------
20000 Sven
(1 row(s) affected)
> SELECT spawnX, spawnY, spawnZ from SpawnZone WHERE npcID=20000;
spawnX spawnY spawnZ
----------- ----------- -----------
41 5 0
(1 row(s) affected)
> SELECT zoneID, spawnX, spawnY, spawnTimer, notes from SpawnZone WHERE spawnMap=0 and maxAllowedInZone>1 and spawnZ=0;
zoneID spawnX spawnY spawnTimer notes
----------- ----------- ----------- ----------- --------------------------------------------------------------------------------
16 21 9 160 Boars, Wolves, Orcs West Kesmai
17 66 16 160 Boars, Wolves, Orcs
18 84 24 160 East Kesmai Wilds
20 117 24 160 Far East Kesmai Wilds
21 116 9 160 Centaurs
(5 row(s) affected)
> SELECT * from SpawnZone WHERE zoneID=21;
zoneID notes enabled npcID spawnTimer maxAllowedInZone spawnMessage minZone maxZone npcList spawnLand spawnMap spawnX spawnY spawnZ spawnRadius spawnZRange
----------- -------------------------------------------------------------------------------- ------- ----------- ----------- ---------------- -------------------------------------------------------------------------------- ----------- ----------- -------------------------------------------------------------------------------- ----------- ----------- ----------- ----------- ----------- ----------- --------------------------------------------------------------------------------
21 Centaurs 1 16 160 10 NULL 0 0 NULL 0 0 116 9 0 4 NULL
(1 row(s) affected)
> INSERT INTO SpawnZone (notes, enabled, npcID, spawnTimer, maxAllowedInZone, spawnMessage, minZone, maxZone, npcList, spawnLand, spawnMap, spawnX, spawnY, spawnZ, spawnRadius, spawnZRange)
> VALUES ('temp centaurs in town', 1, 16, 15, 10, NULL, 0, 0, NULL, 0, 0, 41, 11, 0, 4, NULL);
(1 row(s) affected)
We found where Sven (the guy behind the counter in the temple) spawns, and duplicated a centaur spawning zone (with faster respawning) just a bit south of that. That should make the town more exciting. Let’s see:

Certainly more exciting, but we just see the centaurs suddenly becoming corpses. We need to at least see them being damaged:

We’ll drop this half-transparent red block in front of damaged NPCs, and scale it based on the damage.
|
|
|
|
That presumedDead
flag turns out to be pretty important: watching the database, I kept seeing NPCs that stopped updating with their hit points above zero. I’ll guess the server code doesn’t always
update the hit points if a character dies in some interesting way.
Gone but not forgotten
You may have noticed the corpse disappearing in that last GIF. With this much bloodshed, the field was getting crowded pretty quickly, so it’s necessary to clean up the fallen:
|
|
If you’ve been quiet for ten rounds, your active
flag gets unset. And while it’s not set:
|
|
It works, but why not just destroy the objects? This is step one toward having an object pool of NPCs, so we don’t have to instantiate them and our memory churn is reduced.
For now, keeping them around helps a little bit with debugging, at a small performance cost. Yes, and I now know I should have used
SetActive
.
Bonus Cautionary Tale: Earlier That Day…

And this was with the server side turned off. Nothing was changing, but memory usage would eventually skyrocket. Meanwhile the Unity editor ground to a halt and eventually had to have its process killed. I’ve been intentionally not paying much attention to memory allocation, planning to do a few future days on it, but this needed to be taken care of before we could do anything else. Shouldn’t take too long to figure out what’s going on, right?

1. Unity itself is locking up, and I am running an older version. Upgrade to v4.6.8 (latest 4.x version)…no change.
2. Try creating a standalone executable, and not having the Unity Editor running…no change.
3. Must be the garbage collector not geting a chance to do its job. Let’s invoke it every time we hit the database… …very little change. Memory continued to increase, average increase per second would quickly hit a floor that was way too high.
4. Let’s not actually instantiate any NpcScript objects…very little change. Huh?
5. Let’s not call UpdateNpcCohab
…no change.
6. Let’s not call UpdateAllNpcs
at all after the first minute or so…memory behavior settles down, somewhat.
7. Let’s just stop hitting the database for NPC updates after the first minute or so…same settling. What’s happening?
|
|
When checking the database, on each data row, we’re instantiating a new NPC object. How is that a problem? Once we’re done with that list of NPCs (on exit from UpdateAllNpcs), the garbage collector will take care of it, right? Let’s take a look at the constructor we’re hitting:
|
|
And since it’s a subclass of Character:
|
|
Problem number one is that these are pretty big objects for me to instantiate just to hold a few values. Problem number two is that something about them (those Timers?) is keeping the garbage collector from taking care of them. Time to stop calling server code so cavalierly and make only what I need.
|
|
Even this should be refactored, probably into a struct. But just making this simpler class (only the members I needed, no constructors inherited or otherwise) left me able to run for hours with no significant memory issues.