Skip to main content
  1. Posts/

Day 35 - Rise (and Stumble) of the Dudes

OldDays ste-reez-muvi seitan-spin Unity csharp ruby
Table of Contents

Always travel in packs.
Always travel in packs.


Coding
#

Firstly, that thick NPC thing was not so difficult to track down.

Assets/Managers/NpcManager.cs
231
thisNpcScript.newScale = new Vector3(1.0f / dimension, 1.0f / dimension, thisNpcScript.transform.localScale.z);

All of the NPCs are 0.1 units thick, and 0.1 decimal is a non-terminating binary value. Reading the value out of the engine, doing math on it, and plugging it back in requires some care. Over decent intervals of time, the error was building up, so we got thick NPCs. It’s hardcoded now.


Using the test code I threw together, and a little tweak to give them all the same material, it’s easy to get a horde of dudes wandering blindly north-ish through town.

experiment0.rb
80
81
82
83
84
85
86
87
88
89
90
91
 9999.times do
  host.cmd({"String" => ['w','nw','n','ne','e'].sample, "Match" => / ->/}) { |c| puts "14 #{c.gsub(/\e/, "[ESC]")}" }
 end
end

threads = []
20.times do
 threads << Thread.new do
  have_fun
 end
end
threads.each { |thr| thr.join }

But why are some of them rendering as wolves?

There&rsquo;s something you don&rsquo;t see every day.
There’s something you don’t see every day.

Worse yet, why am I rendering as a wolf?

Full moon?
Full moon?
This is not my beautiful GameObject!
This is not my beautiful GameObject!

Not just a visual defect, but a very specific wolf. All symptoms point to a problem with the object pool.

Assets/Managers/NpcManager.cs
172
173
174
175
176
177
178
179
180
181
182
183
184
if (npcScripts.ContainsKey(npc.worldNpcID)) {
  tempNpc = npcScripts[npc.worldNpcID];
} else {
  tempNpc = npcPooler.GetPooledObject().GetComponent<NpcScript>();
  tempNpc.Reset();
  tempNpc.npcManager = this;
  tempNpc.npcId = npc.worldNpcID;
  tempNpc.name = npc.Name;
  SetMaterials(tempNpc);
  tempNpc.toBeSeen = (position.z <= mapManager.zTop + 1);                    
  npcScripts[npc.worldNpcID] = tempNpc;
}
tempNpc.gameObject.SetActive(true);

I’m beginning to suspect that nothing before the SetActive(true) is actually happening, or at least isn’t having a real effect. Let’s check that theory.

Assets/Managers/NpcManager.cs
190
191
192
tempNpc.gameObject.SetActive(true);
if (recycledNpc) print("Recycled NPC has ID " + tempNpc.npcId + " when it should be " + npc.worldNpcID);
if (tempNpc.npcId != npc.worldNpcID) Debug.Break();

No good, it always has the right ID. But some further playing saw my PC being inactive at the gameObject level. How could that be happening?

Assets/Managers/NpcManager.cs
173
174
175
176
177
178
if (npcScripts.ContainsKey(npc.worldNpcID)) {
  tempNpc = npcScripts[npc.worldNpcID];
  if (!tempNpc.gameObject.activeInHierarchy) {
    print("NPC " + npc.worldNpcID + " not active!");
    Debug.Break();
  }

Well, that triggers a bunch if we cycle through some gangs of dudes. So we’re pulling references out of the npcScripts dictionary even if they’ve been thrown back in the recycler. I think we can fix that.

Assets/Managers/NpcManager.cs
155
156
157
158
159
160
161
162
163
if (npc.lastActiveRound < maxGameRound - 10) {
  NpcScript tempNpcScript;
  if (npcScripts.TryGetValue(npc.worldNpcID, out tempNpcScript)) {
    tempNpcScript.gameObject.SetActive(false);
  }
  npcScripts.Remove(npc.worldNpcID); // oops, forgot to do this
  npcLocations.Remove(npc.worldNpcID);
  if (npc.isPC) activePcs.Remove(npc.worldNpcID);
} else {

and now everything works as it should. I’m beginning to look forward to rewriting most of this code with what I’ve learned, but that will have to wait.


More to come
More to come

Day 35 code - tests

Day 35 code - visualizer

Decimal/Binary Converter