Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - ayy1337

Pages: [1] 2 3 ... 6
1
There's no point suggesting improvements evidently so I won't waste my time anymore, have fun.

2
It's not storing the information because that information becomes useless the next frame.

The information isn't always useless in the next frame though is it. If you have two units in a room and no visibility changes happened to the tiles in the room since last frame, until someone moves you don't have to re-check LoS. If the room is small enough that every unit can see every other unit, you don't need to check for LoS changes even if they move around. This would make the LoS cost basically zero for that whole room, regardless of how many units are in it.

3
"Storing information about which units are nearby" is fundamentally equivalent to figuring it out by doing a nested loop. This is collision detection, and a lot of the optimizations requires various assumptions that we simply do not have the ability to consume. In fact, we're already doing one of the biggest optimizations, an axis-aligned bounding box, checking if the other object is within a 53x53x53 AABB with its center at the dwarf. This is a known problem, it's not like I haven't done research into all this.

You'll find that the vast majority of the optimizations there contain such phrases as "Where most of the objects involved are fixed" or "that approach is well suited to handling walls and fixed obstacles in games". Dwarf Fortress doesn't have those, so a lot of the optimizations would be costly to implement in the first place. You can't "pre-bake" stuff into a map that changes all the time.
It's not storing the information though is it, because every frame the information about which units can see each other is dropped and has to be regenerated from scratch; every calculation about every pair of units has to be done again, in both directions.
Also while the game map isn't fixed like an RTS game, lots of the map does actually change very rarely; my dining hall once constructed is likely to remain as it is for a very long time, measured in frames. These rooms are also ones which the player can define themselves, and are where most dwarves spend the most time, and are most likely to congregate in a high density.

4
Yeah, unfortunately, that "most" happens to not include dwarves, who can see further underground than most, and also doesn't include goblins, who can be seen further underground than most.
I still don't see the problem, since dwarves looking at dwarves will have the same stats, which is going to be the most common comparison by far. Even if the two units have different sight characteristics, if you are lucky (50% of the time) you'll get the unit with shorter sight of the pair first and not have to check LoS the other way.

Maybe there should be a data structure that stores information about the location of things in the map then?

The way the game is structured is already a nightmare for the cache, which is the actual largest cause of performance issues; just improving cache locality on units a little improved performance by 60%, yet more big ol' structures isn't going to help; moving unit positions out into their own array is likely to be the biggest gain, funnily enough
Storing information about which units are nearby is fundamentally going to be faster than figuring it out every frame by doing a nested loop over all the units, regardless of whether the current structure of the game sucks.

5
Creatures keep track of their own positions, there's no concept of "checking tiles in the vicinity" except checking every unit to see if they're nearby, these are synonymous with the way the game is structured

Maybe there should be a data structure that stores information about the location of things in the map then?

Edit: Possibly in the current way you could reduce some of the work by saying if dwarf A has line of sight to B on this tick, assume B has line of sight to A unless he has different sight distance. Yay still waking up. I think this would reduce the number of checks you have to do by about half, assuming most units have the same sight distance.
Also, maybe you could defer LoS checks for pairs of nearby creatures that you just checked - If I had LoS to you last tick, and we're still more or less in the same room, don't check LoS again.

Can't, low-light vision and glowtiles means that A sees B does not imply B sees A

Idk how either of those works in detail, can you explain? I was thinking that you can just check if the two creatures have the same sight characteristics, and because most will, you'll still get the benefit of not having to check line of sight twice in most cases, even if you have to check both ways for pairs that have different characteristics.

6
Another issue I just thought of.. If you do have that cluster of units, which is going to happen not just in sieges but in all your meeting halls, dining areas, dormitories, inns, temples, etc..
Each dwarf is going to do a detailed LoS check for every other unit in its vicinity, checking the tiles around it repeatedly, which sounds like the more-expensive part of the calculation than checking if their distance is <27
If you have to do a scan of the tiles around the dwarf for LoS to 20 units you're potentially scanning the same tiles 20 times , although that would be the worst case where they are all standing in roughly the same direction from you (edit: actually, isn't the worst case that you don't have real LoS to them, so you exhaustively check every tile you do have LoS to? not really sure how that works); might be quicker to exhaustively check all the tiles around the dwarf once if he's in a densely populated area, and this would at least scale only linearly with number of dwarves.

Edit: Possibly in the current way you could reduce some of the work by saying if dwarf A has line of sight to B on this tick, assume B has line of sight to A unless he has different sight distance. Yay still waking up. I think this would reduce the number of checks you have to do by about half, assuming most units have the same sight distance.
Also, maybe you could defer LoS checks for pairs of nearby creatures that you just checked - If I had LoS to you last tick, and we're still more or less in the same room, don't check LoS again.

7
I think the "stand there while a dragon is breathing fire at them" example wasn't an issue with not checking the tile they're standing on frequently enough for environmental hazards, but identifying that there's even a dragon there in the first place that they should be concerned about. Checking for "tiles currently the target of a hostile action" doesn't solve the issue of fleeing from the dragon in the first place, which was the main point.

As for breaking up the whole thing into a grid, that doesn't work nearly as well as it sounds due to the joys of the million-odd edge and corner (literally) cases. That and maintaining such a large structure and having to shuffle around which units are in which box, more often than not, will be more expensive than just checking against every other unit on the map, doing a quick "is it 26 units away?" distance check, and if not, then doing a line-of-sight check.

The game is, from a technical standpoint, sparse. Very large map, very few units. There are times where there are a lot of units (sieges, namely), but we're still talking a drop in the bucket compared to the size of a map (tile-wise a map is about 100 levels tall and hundreds of tiles across). Subdividing the search space only makes sense from an optimization standpoint for dense, not sparse, situations, usually (caveats always apply of course).
With the dragon, you could still know a dragon is around reasonably well if you check LoS every say, 2, 3, or even 5 ticks. And by combining that with the check i mentioned where you have a hostile action even if some really fast creature manages to gap close too fast, you can respond to the attack itself.

Also, there's not _that_ many units, but if you're doing nested loops over a couple hundred or a thousand units every tick evidently it can get pretty slow - in the OP he says going from 1000 units to 2100 decreased the FPS from ~50 to about 16, about 3 times worse for a doubling of units which sounds like something is scaling nearly quadratically with unit count.

8
They happen every time dwarves are able to act and they need to happen every time dwarves are able to act, otherwise they will not react properly to their environment and will just stand there while a dragon is breathing fire at them et cetera.
Might it be cheaper to check the immediate tiles in your vicinity for danger rather than looping through every unit in the game to see if they're nearby?

Could just manually search every nearby tile, which could be very slow, or breaking down the high level regions into subregions (9*9*Y tiles or 16*16*Y) and tracking which region a dwarf/object/dragon is in.
Also if your dwarf doesn't notice a dragon 26 tiles away for 2 ticks is it really a problem?

Edit: Say if you keep a list of all tiles currently the target of a hostile action, like dragon breathing fire, and its source, check the zone around that for creatures that need to respond. Dragon attacks occur much much less frequently than every tick so that would be much cheaper than checking every creature every tick.

9
DF Suggestions / Re: Bring back "tightly shut" doors
« on: February 11, 2023, 06:21:27 pm »
The game already splits accessibility into subregions, that's kinda the problem. Having more subregion maps for pets, flying units etc. would be a performance disaster, nevermind everything else.
Regions but not subregions. https://youtu.be/RMBQn_sg7DA?t=1035 Have a watch of the whole thing it's pretty cool.

10
DF Suggestions / Re: Bring back "tightly shut" doors
« on: February 09, 2023, 01:29:45 am »
Doing something like rimworld's subregion system should work, the dev talks about how it enables this very thing in a video about it.

11
DF Suggestions / Re: QOL: bulk remove/cancel constructions
« on: February 07, 2023, 04:00:37 am »
Definitely need this. Moving dormitory or dining halls is painful in its current state

12
Another one I miss is being able to limit a workshop to people above/below a certain skill level, and last used construction material being at the top of the list when you go to build again.

13
You can do O(1) existence lookups, like say a hash table of creatures in the fort
Sure, why don't you get right on that.

Sure mate just let me fire up my copy of the source code and write it in :')

14
A dwarf will never meet their grandfather in your fort if their grandfather is not in the fort.
How else are they supposed to know if their grandfather is in the fort?
You can do O(1) existence lookups, like say a hash table of creatures in the fort

15
I did another 3-minute profile on my 260-citizen fort, this time with the knowledge of the source. Percents are going to overlap some. Specific seconds are not.

The slowest thing was line-of-sight checks. Due to the fact that it was only counting the checks in the function itself, this was a total of 14.7% of CPU time. However, if you remove one specific thing from line-of-sight checks (more on that later), it's 8%, and thus faster than the next thing. 13.181s in the function itself.

The slowest individual thing in the fort was checking family relationships. This was mostly, so far as I could tell, called in the context of watching performances, probably to tell if they should be feeling love at their family members or whatever. This was 9% of CPU time. 15.537 in the function.

Next is getting glowtiles. This is required for line-of-sight tests, naturally. Glowtile'd creatures are visible from farther in the dark. 5.7%. This is the slowest part of line-of-sight checks, at least as far as stuff that's actually done. 11.749s.

That's all pretty interesting, if you don't mind me asking when exactly are line of sight checks being done? Is it once per frame every creature checks whether every other creature is in line of sight or something less frequent? And curious about the family relations stuff too. If it's performances does that mean if there's no taverns that just goes away?

Pages: [1] 2 3 ... 6