Roses of Lore, my most ambitious project (as well as my first) will feature cities full of bustling people, vehicles, and the like. I have contemplated how I would flesh out the cities, and still keep the game running smoothly. The following represents some simplified concepts that I feel might work, but I would like some feedback, as well as some thoughts on how you might handle this.
1.) Only update in oview(world.view*2)
This would consist of giving each NPC a schedule, dictating their pathing, behavior and interaction with the PCs. At certain points in the game an NPC would have to be at a certain location, doing a certain things, or traveling to another location. By tracking where the players are (there will only be 3 players max, and they will usually be travelling together, though that's not mandatory), and when, I can calculate what NPCs should be in view, and what they should be doing. Once the NPC has left oview(world.view*2) I would have no need to keep them active, and therfore, can shut them down, so to speak. I'm still not sure exactly how I would go about doing this, but it sounds feasible. I noticed a lot of proffessional games, especially 3D games, do this. Only activating enemies when you get close enough to see them.
2.) Crowds as dense turfs or objs
This could even be worked with the above, limiting only those NPCs of importance as actual mobs. The remaining crowds and groups of NPCs would be dense turfs or objs, with animations showing them interacting with the environment. Again, I would only have to animate those in view, keeping the processor from exploding.
Well, that's all I have come up with so far. I don't want a barren city devoid of life, so there must be 100s of people filling out the streets. Some streets will have more people than others, like shoping districts and such, but even a relatively low-traffic area is still way too much for most people's computers to handle.
What are your thoughts on these approaches, or how would you handle representing a dense city environment in BYOND? I'm open to suggestions, critisism (constuctive only, please) and general flaws in design.
~X
ID:153847
Nov 30 2002, 11:04 am
|
|
I think as a general rule, RPGs are better if instead of including tons of useless NPCs, you simply only include ones that have some importance, even if that importance is just to provide scenery. If the NPC has no purpose other than to take up space, just leave it out.
|
In response to Foomer
|
|
It has importance, they represent a crowded urban environment. Leaving them out would represent a desolate urban environment, not in line with the story of the game... The important ones can be mobs, leaving the rest as simple pictures in dense turfs, or such, but they still need to be there.
~X (Pimps don't work desolate cities) |
In response to English
|
|
English wrote:
Perhaps you could divide each map into many areas that are roughly the size of the players view. Then when they enter any area it activates (loads mobs and tells them to start moving) all of the surrounding 8 areas that haven't already been activated (usually 5 of them will already have been activated). That would ensure that they never see cars appearing out of thin air and everything should be on time (unless your cars are going 200 mph or something). This is basically how I'd approach it too. NPCs need only be active when a player is in the general vicinity. Then you have to deal with fewer AI calls, but you don't run into discontinuities caused by working only with the player's (extended) view. My idea would be to have a macro and micro level of activity. At the macro level, you'd know a certain number of people should be doing X, or going to Y, or so on. At the micro level, these people are actually active and moving. For an absolutely complete system, maps should be polled from time to time to determine what's going on at the macro level, and move NPCs to other maps accordingly. When a map first "wakes up", it can do the same and figure out who's gone, who's arrived, and then who should be doing what when the player comes into sight. Obviously this description is far from being a complete implementation, but hopefully the idea itself is clear. That still leaves the problem of knowing which mobs to load and which areas they should be attached to. You could have each mob belong to an area (but not be present on the map) and then use that to load everything to the area. You could have their positions refresh based upon the distance to the players. If the players were a city away you could calculate all of the mobs in that cities new positions by tackling 1/5 of the list every 10 seconds (or whatever) whereas areas very close to the players may update 1/3 of the list every 3 seconds to make sure everything goes smoothly. This is assuming each mob has a schedule that tells it where it should be at each time, that would be used to move it from area to area. Also a good idea. The micro level of activity needn't be a single level, but can have some abstract steps for NPCs far enough out of view. Then only mobs in view (or near it) are doing something all the time, whereas others are mostly up to speed and updated less often until they're needed. Lummox JR |
In response to Foomer
|
|
I disagree, sure it is easier if you don't have to sort though crowds but cities aren't really like that. I read a lot of fantasy type books and the cities are always full and then I go and play a game and the cities are deserted and I can't replay all of my favorite scenes from my books.
|
In response to DasFalke
|
|
Foomer has a point, however the keyword is "useless". If you are able to interact with these npcs to a decent extent, I too believe that they are worth the trouble, just be sure to keep a handle on that object limit. If you're having cities swarming with NPCs, its better to create and delete them dynamically.
|
My FaceHug system works on a system of allocation -- every area has a single numeric value that determines how many critters there are in that area. The area also has a list of adjacent areas. Whenever a player is in an area, it determines the extent of what they can see, and if the area has a numeric value, it spawns a critter in a random location outside of the view ranges of any players in the area or adjacent areas (provided any such locations exist). Whenever an area is abandoned and there are no players in any of the adjacent areas, any critters in that area are deleted and the numeric value increased. This also means that the critters can seem extremely sneaky and nasty, since they can appear behind you in a corridor that you thought you had already cleared.
That way, there are typically never more than 5 or 6 critters active at any time. The level of AI given to the critters is also reduced by how many are active -- if only one is active, more CPU time can be spent making it attempt to tactically determine what the players are trying to do, and take steps to stop it. For example, the critter can see people running into a room with two exits, and it knows that a ventilation shaft nearby leads to the corridor on the other side of that room... the critter will take the ventilation shaft. If it discovers that the ventilation shaft has been sealed, it tries a different route. However, when there are six critters around, they all get dumber to save CPU cycles, and they all just start pounding on the door and pile through. Some random shifting of critters also takes place, to simulate critter movement. Eventually, I might also program a system that responds to the players' movements and tactically concentrates critters in different areas based on "importance" weighting (naturally, the areas adjacent to wherever the players are get some level of importance weighting as well). Thus, in that above example, while the critters are pounding on that one door and the players are running to go out the other one, the game's strategic AI is moving critter numbers around and putting them in positions to surround the players. Simply put, you don't need to have a lot of NPCs on one screen to have them respond to players' actions and live their programmed purpose with seemingly high intelligence. |
In response to Spuzzum
|
|
I would like to see that, what's the estimated release date?
|
In response to English
|
|
English wrote:
I would like to see that, what's the estimated release date? Hahahaha...Spuzzum...hahaha..release..hah..date..hahaha *continues fit of laughter* -AbyssDragon |
In response to AbyssDragon
|
|
First, when a PC enters a certain Z level, have all mobs on that Z level start the tracker loop.
ActivityTracker() for(var/mob/pc/P in world) if(P.z == src.z) if(!P.Find(oview(world.view*2)) // Hopefully thats right... src.activated = 0 break spawn(rand(70,130)) ActivityTracker() else src.activated = 0 break Somewhere in calling PC movement, you'll need to have something like this... for(var/mob/M in oview(world.view*2)) if(!M.activated) M.activated = 1 M.Activate() Now, when looping through your action procs (that determine NPC actions), you'll need to keep checking the activated variable. If it's 0, break the proc. You may need other variables to keep track of what stage of action the NPC is in (picking berries, depositing berries, or cleaning basket). The Activate proc should probably use these place-keeping variables to start the mobile back up at the proper action, then keep running the mobile's action loop. This is just a rough idea, and quite simple. Hopefully it gives you a bit of help.. ~Polatrite~ |
In response to AbyssDragon
|
|
*laughs with him* ;-)
|
In response to Spuzzum
|
|
Your system sounds very similar to what I have going on in Maeva now. Yesterday I took that same method and applied it to supply and demand for dynamic generation of shop inventories. When I check the values of objects, it checks a val() proc rather than just a variable. My val() proc checks if there are any objects within the object, and also takes into account the object's supply and demand in the area. Players will essentially be able to walk into a small village and buy them completely out of weapons. Likewise one could try to run a business by selling a particular item frequently and eventually run into the problem of high supply and low demand.
|
That still leaves the problem of knowing which mobs to load and which areas they should be attached to. You could have each mob belong to an area (but not be present on the map) and then use that to load everything to the area. You could have their positions refresh based upon the distance to the players. If the players were a city away you could calculate all of the mobs in that cities new positions by tackling 1/5 of the list every 10 seconds (or whatever) whereas areas very close to the players may update 1/3 of the list every 3 seconds to make sure everything goes smoothly. This is assuming each mob has a schedule that tells it where it should be at each time, that would be used to move it from area to area.
Just some thoughts :)