Closed caitisgreat closed 6 years ago
This would definitely make killing Hells Raiders bandits at night for the Old Guard much more challenging.
Currently, if you do the quest at night, the Bandits just stay still like a rock since they can't see you (and thus won't turn hostile, meaning no x-ray vision since they have to be hostile first), letting you aggro and kill them one by one. They just ignore all the gunfire.
Sure, it's just that depends rather strictly on #19437 which is a bit controversial. Except maybe for the player - it could be hardcoded to only care about the player, but then you wouldn't have the parts about NPCs locating monsters by footsteps.
What does this have to do with persistent ids? If a npc hears a sound, they can react to it just fine without identifying its source, in fact that's information they should not have.
They need to have a lot of info to sensibly react to sound. They're supposed to be humans, not zombies and as such they absolutely need to be able to tell apart player moving around the house from a zombie stumbling on the other side of the wall. No ids, no advanced AI, simple as that. Any workarounds will be massive and terrible hacks.
You need a better example, that distinction would be "footstep" vs "shuffle", and does not require knowing the source. NPCs should NEVER use an id to determine the origin of sensory input, if the input doesn't have the necessary data, either it should be added, or the NPC shouldn't know it.
NPCs should NEVER use an id to determine the origin of sensory input, if the input doesn't have the necessary data, either it should be added, or the NPC shouldn't know it.
Counterexample 1: Checking if the source of sound is one of the seen monsters.
The right way: Checking if the id attached to sound is in set of seen ids. If it isn't, it must be a different monster. If you hear many sounds from that direction/have bad hearing/etc. maybe add some fuzz factor.
The wrong way: Going through all monsters in the game to find the seen ones, then comparing their positions to position of sound source.
The "Oh shit, what are you doing?" way: Including all the necessary information in the sound, going through all monsters in the game, correlating their stats with those attached to the sound with unbalanced noise to the position, resulting in hearing that takes a ton of processing power just to notice that the sounds always happen when the seen zombie makes a step - something trivial IRL.
Counterexample 2: Remembering perceived monsters
The right way: Storing their ids. If mistaking monsters is desired, implementing it sanely on those ids, by allowing one monster to be perceived as another. Having them forget monsters that move away. Letting NPCs be a somewhat smarter instead of being a lot dumber.
The wrong way: Storing entire copy of the monster to represent its last seen state and the number of turns since it was remembered. Extrapolating the locations of monsters (badly) ensuring that NPCs obviously act and reason like robotic in-game entities instead of humans who reason like "the zombie would go after him, that's what zombies do". Also, have them be incapable of understanding that a zombie trapped in an armored car will probably still be there after a minute, because that takes too much brainpower for a human.
The way to fuck it up: Storing a subset of the data, doing the wrong way a bit faster, but having to extend it every time anything new needs to be added, slowing down development when it needs speed the most instead of cutting the structure down to needed parts when requirements are properly known.
Those aren't even forced examples. A NPC wants to know if it sees all the monsters to count them, which is important on night missions. This is something easy to do intuitively but not easy to program in (properly, not in such a way that it has more edge cases than regular ones).
Good job completely missing the point and building ridiculous strawmen, but sure, go ahead and keep grinding that axe.
Checking if the source of sound is one of the seen monsters.
I'm not clear on why this is something the NPC is assumed to be aware of, they can't watch every monster simultaneously in order to determine if a particular monster was the origin of a particular sound. They should be percieving a set of sound events, and correlation between sounds and monsters SHOULD be vague in general.
Remembering perceived monsters
The right way: Modeling sensory perceptions as discrete and explicit sets of attributes presented to the NPC AI.
The way to fuck it up: Give the NPC a handle to the entire monster (or player) state every time they interact in any way, nearly guaranteeing that NPCs chronically act like psychic ninjas becaue they constantly "accidentally remember" things they shouldn't know.
A NPC wants to know if it sees all the monsters to count them, which is important on night missions.
This is action hero bullshit, you're saying the NPC is watching every monster in sight and correlating every sound they make with their actions, even if it can barely see them since it's, you know, dark. The NPC (and monsters, and the player) should only have access to what their senses reveal, they should not have a side-channel to an unambiguous source of truth via internal game APIs.
This isn't just about senses, this is about loose vs tight coupling. Giving the NPC AI total access to player and monster data is a great way to guarantee that you implement a handful of features really fast, then get bogged down in a quagmire of oversharing and overcoupling since the NPC now knows all kinds of things about entities that it shouldn't. It also means that if ou want to test your NPC you have to generate real monsters and hand the NPC its UUID since that's your interface, oh yea, and you have to generate a game world too since I'm assuming you're looking up the monster there via it's UUID.
The right way: Modeling sensory perceptions as discrete and explicit sets of attributes presented to the NPC AI.
And then drop them on the input because no one has enough free time to jump through all the hoops to simulate an entire world on the other side, untangle turn-related data from monster speeds, cluster sound points and extract statistical data from them just to figure out monster counts, and test the entire system for stability to ensure the NPC isn't flip-flopping from "I can take them on" to "this horde is too huge" just because of excessively strict requirements on AI in the name of some abstract ideal.
you're saying the NPC is watching every monster in sight and correlating every sound they make with their actions, even if it can barely see them since it's, you know, dark
No, I'm saying that the NPC should be able to tell if the footsteps come from the monster it sees marching or from the one outside view. Something utterly trivial IRL due to effectively continuous time, but needlessly convoluted in a turn-based, move-counting world of abstractions you refuse to name as such.
Giving the NPC AI total access to player and monster data is a great way to guarantee that you implement a handful of features really fast, then get bogged down in a quagmire of oversharing and overcoupling since the NPC now knows all kinds of things about entities that it shouldn't.
As opposed to implementing a whole lot of neatly uncoupled features never.
NPCs already do have an access to and do use player and monster data all the time. They aren't fed an illusion of the world. And yet somehow it doesn't turn into a giant mess of overcoupling, as you predicted. Why the double standard then? Why would giving them access to the same data by a new channel suddenly magically ruin everything?
It also means that if ou want to test your NPC you have to generate real monsters and hand the NPC its UUID since that's your interface, oh yea, and you have to generate a game world too since I'm assuming you're looking up the monster there via it's UUID.
And how do you imagine a world-less NPC test? A NPC being fed a visual copy of the world somehow? They need a whole world to execute a single turn. They see the map, they find the monsters on it, they are affected by the weather.
I could understand it if it was a clean neat code where everything is decoupled and I wanted to add some horrible hack to staple things together.
But what you're defending is not a clean, neat, decoupled code, but an unordered tangle of dependencies, and you're defending it from adding a clean dependency that could easily be changed in one place (say, by extracting "physical data" from Creature
and operating on that).
Just wanted to chime in here on the issue since originally submitting it. My original intent was to make a very explicit difference between auditory senses and visual senses. To me, it makes more sense (hehe) to have audio gently guide a monster into visual range, even if they have no idea that there's a monster there to know. So in essence, I agree with Kevin's interpretation of the implementation.
Players react to sound without ever knowing monster exist, they have no idea what's on the other side of the wall for example. I understand that a player would remember that an actor might disappear behind a wall, but I’m not really looking for NPCs to have that behavior. It seems needlessly complicated and not fun. I wouldn't expect the NPC's to have extra-sensory perception about the player or any other monster.
I would insist on providing a behavior that causes an NPC to investigate a noise, not necessarily play cat and mouse about finding it. And I feel that there ought to be a respectful range to the way the noises are heard. Deaf NPCs wouldn't hear players or monsters at all, whereas CBM-enhanced NPCs might hear the subtlest of noises. At the point the NPC could see another actor, I would expect it to react accordingly with existing visual behaviors. Following the actor as necessary.
I don't really care that an NPC could determine whether the player is behind a wall. Friendly NPCs already intrinsically follow the player when allied. I'm suggesting that when they aren't allied, that they investigate noise made by other actors and solely that. The flavor text being just that. In a way, throwing the wool over the player's eyes to the fact that the NPCs aren't actively aware of their presence, just making it appear as they are. And if that evolves later, so be it, but at the present only monsters seem to have this behavior.
I'd suggest looking at some examples from other games, such as immersive stealth games like Thief: The Dark Project or Metal Gear Solid. I've provided an example of getting caught in Metal Gear Solid for reference. Note how the NPCs are only able to see Snake within their cone of vision, but often hear him and relocate based on noise Snake makes to place him in the cone. Even after a while giving up on tracking the noise and returning to their patrol.
Thanks for taking the opportunity to read this. I really appreciate having so many eyes on the issue I submitted, I definitely feel like it’s being taken seriously. You're all doing a fantastic job and dialogues like these are part of the reason.
And then drop them on the input because no one has enough free time...
I disagree that the shortcut of having the NPC examine game state directly will accelerate development significantly in the medium to long term, which are the only timescales I care about. Even if I'm wrong, I'd prefer fewer new NPC AI features (including none) than spending effort on features that make the game even more of an over-coupled mess.
in the name of some abstract ideal.
Yea, decoupling and modularity of software components never helped anyone /s
you're saying the NPC is watching every monster in sight and correlating every sound they make with their actions, even if it can barely see them since it's, you know, dark
No, I'm saying that the NPC should be able to tell if the footsteps come from the monster it sees marching or from the one outside view.
Those are the same thing in a huge number of scenarios, for example your solution would allow a NPC to distinguish between a visible zombie and a zombie 2 squares away on the other side of a wall from across the street, or count the number of zombies in a smoke cloud without ever seeing them, or even worse, correctly identify each zombie in a smoke cloud based only on their footsteps.
Something utterly trivial IRL due to effectively continuous time
Really? You can stand on a busy sidewalk with your eyes closed and tell me the names of everyone on both sides of the street based on their footsteps? Because that is an actual example of a bug this system can have. Worse, it's extremely difficult to test for over-sharing, so this kind of bug would accumulate, where under-sharing can be caught relatively simple tests.
Giving the NPC AI total access to player and monster data is a great way to guarantee that you implement a handful of features really fast, then get bogged down in a quagmire of oversharing and overcoupling since the NPC now knows all kinds of things about entities that it shouldn't. NPCs already do have an access to and do use player and monster data all the time. They aren't fed an illusion of the world.
Yes, I'm aware I was describing the status quo, and it is that quagmire of over-coupled garbage. We need to move away from that, not double-down on bad design.
And how do you imagine a world-less NPC test? A NPC being fed a visual copy of the world somehow?
No, they would be fed a set of sensory inputs, and their resulting decisions would be checked, or at a different level they could have internal state injected, like a set of threats that they make a decision about.
They need a whole world to execute a single turn. They see the map, they find the monsters on it, they are affected by the weather.
That's a massive problem that needs to be fixed, yes. Why do you think I've been saying for years that the current NPC implementation isn't a stable starting point? Especially the AI, it just needs to be replaced.
Yea, decoupling and modularity of software components never helped anyone /s
Insisting on applying ideas that only really shine in big projects, to small projects made in spare time, is cargo cult programming.
Really? You can stand on a busy sidewalk with your eyes closed and tell me the names of everyone on both sides of the street based on their footsteps?
Non-sequitur. I can tell when a footstep is made by a person I see.
No, they would be fed a set of sensory inputs, and their resulting decisions would be checked, or at a different level they could have internal state injected, like a set of threats that they make a decision about.
Sounds like a ton of redundant data per NPC. And judging at the speed of development, something that would take 3-5 years to happen. The project may well be dead by then, especially with code standards blocking interesting features.
That's a massive problem that needs to be fixed, yes.
It's a minuscule problem compared to the less technical glaring flaws which could be fixed in 10% total time (including long term) by allowing less stiflingly strict standards.
Yea, decoupling and modularity of software components never helped anyone /s Insisting on applying ideas that only really shine in big projects, to small projects made in spare time, is cargo cult programming.
DDA is small? WTF is your threshold for a large project? But sure, if you'd like to apply more rigor, pleace cite sources that indicate that 200,000+ lines of C++ composed of 700+ classes is "too small to bother with decoupling and modularity". It's not a sentiment I'm familliar with in sotware engineering or computer science, but I'd be interested to learn what academia is saying about it.
Really? You can stand on a busy sidewalk with your eyes closed and tell me the names of everyone on both sides of the street based on their footsteps? Non-sequitur. I can tell when a footstep is made by a person I see.
... AND you can watch every person in all directions simultaneously, that's absurd. You're simply ignoring the fact that your scheme will give the NPC all these inputs simultaneously no matter how many monsters are nearby, AND leak information since there is no limit (other than manual code review, which works SO well /s) on information sharing. Hell, simply adding the monster ID to the sounds, regardless of even looking up the monster object tells the NPC precicely how many monsters are in range, which is an absurd ability to have.
No, they would be fed a set of sensory inputs, and their resulting decisions would be checked, or at a different level they could have internal state injected, like a set of threats that they make a decision about. Sounds like a ton of redundant data per NPC.
Who cares? A "ton" is what, a few KB per NPC? Hundreds? Neither of those is a problem.
And judging at the speed of development, something that would take 3-5 years to happen. The project may well be dead by then, especially with code standards blocking interesting features.
Repeating, Even if I'm wrong, I'd prefer fewer new NPC AI features (including none) than spending effort on features that make the game even more of an over-coupled mess.
And a major reason for this? Massively over-coupled systems are extremely difficult and frustrating to work on, and specificically contribute to loss of developer interest and project stagnation.
That's a massive problem that needs to be fixed, yes. It's a minuscule problem compared to the less technical glaring flaws which could be fixed in 10% total time (including long term) by allowing less stiflingly strict standards.
What less technical flaws? From where I'm sitting, spinning in circles re-fixing the same bugs over and over again is the main drain on project productivity since there is no ratcheting mechanism enforcing that once things are fixed they stay fixed. I'm trying to add unit testing where possible, but it's exactly this lack of modularity that makes it extremely difficult to write them, so refactoring to increase testability is an extremely high value activity, and doubling down on tight coupling between game entities is the best thing you can do to insure that the involved systems NEVER converge on proper functioning since you'll be unable to perform decent automated testing on them.
... AND you can watch every person in all directions simultaneously, that's absurd.
You aren't arguing against giving NPCs "coupled" hearing here, you're arguing for limited sight. Also, leaking some trivial information only violates overly pedantic ideals of what perception should be, it's nowhere near a major flaw when a NPC tells apart a tough zombie from a regular one, even if this happens every single time.
You're simply ignoring the fact that your scheme will give the NPC all these inputs simultaneously no matter how many monsters are nearby
That's not a problem. Not at all. It's just something to take into account when writing the NPC-side function. Pretend-stupidity has a long tradition in video game AI due to how simple and efficient it is compared to forming a complete model of the world on the agent side and dealing with all sorts of representation problems. In most cases, it is better to write an omniscient AI and then force it to act dumb than to try to work it backwards by forcing it to integrate tons of environmental info into its own model of the world. The latter will almost always end up much heavier and harder to keep working.
other than manual code review, which works SO well /s
Biggest errors and massive fuckups in DDA weren't caught by unit testing. You can make everything perfectly testable and then still fuck it up by missing a test case or simply by testing something too complex for neat test cases. Sure, unit testing is helpful - it catches number deviations - but it is just one of the means, not the goal. Sacrificing vital parts of the game for testability is sure going to make everything so much fun!
Who cares? A "ton" is what, a few KB per NPC? Hundreds? Neither of those is a problem.
This data has to be generated and interpreted. That's linear complexity with entity number per NPC without much space for optimization. Like that problem with NPC item pickup causing heavy drop of FPS.
Repeating, Even if I'm wrong, I'd prefer fewer new NPC AI features (including none) than spending effort on features that make the game even more of an over-coupled mess.
Start by removing all monster AI then - it relies on the same mechanisms. Make Days Ahead truly Dark and empty, with player and vehicles being the only mobile entities, because everything else relied on over-coupling for AI.
Massively over-coupled systems are extremely difficult and frustrating to work on, and specificically contribute to loss of developer interest and project stagnation.
Judging by quick peek at git history, I've worked on the NPC AI a lot more than you. Over-coupling wasn't really a problem so far. Maybe it could be cleaner without it, but it doesn't deserve a place in top 10 problems with NPC code from programmer's/maintainer's side. Lack of ability to address items and monsters except by position and index - that was a massive flaw that always made things more annoying, often unfeasible. "Linear" code where each decision is a nearly stateless entity (only carrying an index or two) requiring reconstruction of decision instead of just calling "yes, do that thing" - also terrible, though not as much as the above. World being presented in "slices" instead of events, requiring memorizing, which in turn was impossible due to lack of ability to address things.
Not sure if you're stretching the theory (over-coupling = really bad), classification of over-coupling, the resulting difficulty and frustration or something else, but you certainly are misapplying the theory here, trying to make code smell appear as a massive flaw.
Insisting on applying ideas that only really shine in big projects, to small projects made in spare time, is cargo cult programming.
I'm not going to let you drop this one. Please cite sources that indicate that 200,000+ lines of C++ composed of 700+ classes is "too small to bother with decoupling and modularity". If not I'd like you to retract your "cargo cult" statement. It's extremely rude, and I'm not going to stand for insults like that.
Please cite sources that indicate that 200,000+ lines of C++ composed of 700+ classes is "too small to bother with decoupling and modularity".
I never said it's too small to bother with decoupling. I said that insisting on it - ie. treating it as a necessary thing in all cases - is the problem here. Software design is not just "coding", not just applying memorized patterns. Right tool for the right job, not "one size fits all". And in DDA, one philosophy produced the best results so far: Worse is Better. Making things just maintainable enough, but making them "fun".
Even if by pure LOC DDA may look like a really serious project, on the inside a great, great deal of it is copypasted padding. It's a great example to why one should not use lines of code as a measure of anything else than bloat.
iuse.cpp
, mapgen.cpp
, iexamine.cpp
, faction.cpp
, mission_start.cpp
- have you read those recently? If you want to block or remove important features on the basis of code quality, I'd recommend starting there.
So no, I can't really give a source using LOC as a measure.
If not I'd like you to retract your "cargo cult" statement. It's extremely rude, and I'm not going to stand for insults like that.
I apologize for the rudeness and hostility, but I still can't retract that "cargo cult", at least not without trading it for something just as rude. Not without a good reason to see it as anything but, when it involves blocking and cutting out vital parts of the project for a promise of better maintainability. I understand wanting good code quality, but this is much further than that. I'll have to stand by my words, as offensive as they may be, until I'm shown a reason to believe otherwise.
If not I'd like you to retract your "cargo cult" statement. It's extremely rude, and I'm not going to stand for insults like that.
That did not look like an insult to me. Different methods of programming suit different projects. This has to account for the size of the program, the function, and how it is being developed.
While I would not consider myself qualified to evaluate the efficiency of the code itself (lacking familiarity with it), if another developer reasons that there are inefficiencies, the reasoning for this should at least be understood, even if not agreed with.
I feel that you are taking the matter too personally, and this entire thread has strayed off topic and devolved into bickering, which is detrimental to the actual subject of this issue and to the project as a whole.
I still can't retract that "cargo cult", at least not without trading it for something just as rude.
Ok then, this conversation is over, as well as all future discussions about uuids you may wish to bring up. Im not going to repeatedly discuss this topic if you can't even be bothered to be civil about it.
That did not look like an insult to me.
I'm not interested in your opinion on the matter. It is as you say personal, and therefore none of your damn business.
You do not need to be so rude about it.
Moreover @kevingranade, I did not say it is personal. You have either misread my statement, or twisted my words.
I said you are taking it too personally. Taking every criticism as an insult or pointless whining is detrimenetal to this project. Moreover it reminds me of other former contributors such as @mugling and @chaosvolt in that they both did not handle criticism in a rational manner, and their reactions (that of the latter especially) were detrimental to the project.
Ok, I retract the part of my statement asserting that you said it was personal, but not the assertion that it is personal, and it's still none of your damn business.
Understood. That said, I only got involved out of concern. Your impoliteness in response to that what was further prompted me to object to your handling of criticism and your attitude, which unfortunately is relevant to everyone you interact with. I have always attempted to maintain a formal attitude, be respectful to others on this project, and not take things personally. I only ask that to show the same respect to others as well.
That said, my apologies for getting involved.
TODO: Break this issue up into one issue per suggestion in the OP.
Broken up into specific sub-issues.
Assuming issue #19977 is resolved, it'd be nice if NPCs could also listen for other actors. For example, if skulking around in the dark is your thing, it'd be nice if NPCs could hear you the way monsters can, in that they'd investigate the noise. Perhaps even provide a vocal cue like, "Who's there?" or "What the heck was that noise?" before you take your makeshift crowbar to their heads (I swear I'm not a psychopath.) Furthermore, should you decide to remain silent they might wander off back to where they were or what they were doing originally, again invoking another audio cue like, "I must be hearing things." or "There's nothing here after all."
On the other hand, if you're friendly with the NPC in question, it'd be interesting to hear them take account of an noise that might be you. For instance, you are nearby the NPC, but they recently lost sight of you and started hearing noises nearby - audio cues could include something like "Is that you,
player name
?". If they then did find you, after investigating, they could reassure themselves like "Oh, thank goodness, I thought it wasa/an
monster name
." Or, if they stumble upon something hostile, they could yell to let you know they're under attack. "a/an
monster name
! Helpplayer name
!" Of course, I think the player should be given the option to tell friendly NPCs to keep quiet too.I think these audio cues could help to make NPCs feel more alive, as opposed to the hordes of zombies in game.