A big URRpdate this week, as we hit around 80% completion on the scheduling and pathfinding for all the world’s important NPCs, and also add some smaller additions like banners, drawbridge chains, and finishing off the upper floors of castles. At this point you can now track NPCs leaving their home and going INSIDE buildings – and this again works regardless of what the player does, where the player is, what maps/buildings have thus far been spawned, etc. This is, to put it mildly, a landmark moment. It works completely for guards in mints, and banks (though I have yet to test arenas and archives, but those are the first tasks I’ll be working on checking this coming week). It’s always hard to tell how much code written to deal with Situation A will actually also apply to Situation B until you give it a shot, when the Situations in question are so complex and have so many variables, but I think this code should be entirely transferable. I hope.
So, it’s time for some gifs! Various gifs here of guards leaving districts, entering districts, entering buildings, leaving buildings, exchanging guard duty with others, etc. Guards now work correctly for all outside guards, and almost all inside guards work correctly, and any and every weird combination of movement across the map and the player’s actions also, as far as I can tell, work perfectly.
However, all of this has given rise to a very amusing bug. So, consider this: the world map is split into map grids, each of which is 200×200 tiles when spawned but naturally starts unspawned, and each map grid might contain a range of buildings. When the world is generated I can check exactly what buildings will be in each district, but naturally in most cases I don’t know exactly where each one will be placed – since that would entail spawning the entire map, on the human rather than world scale, at world gen! Which would be absurd and take probably the best part of an hour or something, possibly more (I’ve never tried it and don’t intend to).
Now, consider this. The player is in Map Grid A. In Map Grid B is a guard, who is due to leave their house and move into Map Grid A, to relieve another guard on guard duty. Map Grid B has never been spawned. How long, therefore, should this first action – moving from B to A – take? No matter how any map grid spawns, moving from any point of a map grid to an appropriate edge can never take more than 200 turns, and therefore all movement of this sort, in unspawned areas, takes 200 turns. Were it spawned, it might “actually” take 20 turns or 190, but we have no idea what the correct number would be until spawned, and since it hasn’t been spawned, I play it safe and assume 200.
With me so far? Splendid. Now, let’s say that the guard leaves their (unspawned and nonexistent) home at turn 1000, and therefore is due to leave Map Grid B and enter Map Grid A at 1200. Now, the player is sat in Map Grid A. If the player waits until turn 1190, and then enters Map Grid B, it will then spawn all the buildings and have the NPC do 190 turns of their action. However, what if this building is near the edge to Map Grid A? Let’s say they get there with 90 turns left. Ordinarily, they would go through, and then take 90 turns on the other side… but that would mean if the player immediately went back through, from the player’s perspective, upon returning to Map Grid B, it would appear as if in two turns an NPC had just appeared and teleported ninety tiles up the map grid! Therefore, if an NPC is just about to cross grids, and the player is about to enter that grid, it takes them to an earlier step in their movement so that the player, just entering Map Grid A, sees the NPC for a few turns before they go into Map Grid B. However, what this means, is that if the player keeps hopping back and forth, the NPC keeps getting pushed back and never actually moves through until the player goes somewhere else! It’s very silly. I’m not sure how to fix it yet, though it probably needs some kind of counter that notes if the NPC has already been pushed back once in its current district, and resets after moving to a new grid. But still: it’s an interesting example of the complexity of the system, and some of the weird situations that arise, and how I’ve tried fixing them.
To further illustrate this point, here are some examples of the scenarios that can arise:
- Player is in a map grid and an NPC moves into that map grid, and should physically spawn.
- Player moves into a map grid, and all stationary NPCs outside buildings (e.g. guards) must spawn.
- Player moves into a map grid and another important NPC is moving in that map grid, and must spawn in the right place, an appropriate way along their schedule according to the timing of their schedule.
- The player follows an NPC into a new grid, and the NPC should be x turns away from the edge of the grid once they are spawned, despite having been unspawned after leaving the player’s grid.
- NPC enters unspawned building, player stays in grid, things must happen in building that doesn’t exist.
- Player is in grid with unspawned building and NPCs within that unspawned building need to leave.
- Player is in grid, NPC enters building, player leaves, NPC must be handle its behaviour in unspawned building and unspawned grid.
- As above, but player enters building first, leaving a spawned but unloaded building in a spawned but unloaded grid.
- Player enters building part-way through NPCs doing behaviours within it, causing it to spawn for the first time, and they should all be at the right part of their schedules…
Basically, consider every variable of 1) the player’s action, 2) spawned grids, 3) spawned buildings, and 4) important NPCs moving through all these, and I cannot begin to describe all the variations. Naturally in many cases a piece of code I wrote to resolve Scenario #14 also worked for Scenario #26, and so forth, but in many cases it didn’t and a massive amount of code had to be written to handle every possible variation and permutation. But I think a large part of it is now done.
What is says on the tin, really.
Dare I hope… AI pathfinding/scheduling… finished?!?!?!?!