Ok... NOW I'm sad.
Arcanaville, thank you for asking so many questions !
That would be highly inefficient. I would make power and attribmod activation period explicitly supported in the primary event loop.
|
Where is your data going to come from, if your engine doesn't have a one-to-one mapping of mechanics to the data we have? For each effect that a power performs, here an incomplete list of what a game engine would have to understand, not counting superficial things (like floating text and combat spam): Attribute affected (i.e. Smashing, Melee_Attack, Regeneration) Aspect affected (i.e. Cur, Abs, Str, Res, MaxMax) Scale value Table (i.e. Ranged_Damage, Melee_Buff_Tohit, Melee_Ones) Attribmod target (i.e. self, target) Period (i.e. how often the effect occurs) Duration (i.e. how long the effect lasts) Chance (i.e. chance the effect will take effect) Delay (i.e. how long to delay effect after hit before taking effect) NearGround, AllowStrength, AllowResistance, AllowCombatMods (flags) Requires (postfix expression which must evaluate true for effect to occur) AttribmodType (i.e. Magnitude, Duration, Expression) StackingType (i.e. stack, ignore, replace, extend) StackLimit (maximum number of times this specific effect can stack) Duration (used for Magnitude type) Magnitude (used for Duration type) MagnitudeExpression (postfix expression used for Expression type attribmods to calculate magnitude scale value) InnerRadius, OuterRadius (min and max radius allowed for effect used when power is spherical AoE) SuppressionCodes (codes representing conditions under which effect is temporarily suppressed) Reward (used to define powers granted with GrantPower effects) EntityDef (used to define special entities for EntityCreate effects) |
Alternatively, if you want to make up your own engine in a couple weeks that doesn't have this complexity, you'll then have to convert all the powers data to that new engine somehow. |
How long would it take just to write the expression engine that figures out what to do with: kMeter,source>,.9,<,kHeld,target>,0,>,kSleep,targe t>,0,>,||,&&,enttype,target>,player,eq,&& (stalker crit) |
And how would you make Dual Pistols work: would you properly implement GlobalChanceMod or would you just recreate the powerset by hand? http://tomax.cohtitan.com/data/power...d.Dual_Pistols |
But there is something you can use already, the "mode" variable every entity has. Like "disableAll" etc. These are just bits in a bitfield right ? It can be set/deset as part of effects too.
Would you write a completely new combo system and redo all the Dual Blades powers by hand, or implement mode setting and use the original data: http://tomax.cohtitan.com/data/power...ee.Dual_Blades |
Or you can use modes or a mode-like system. A special bitfield for use by powersets, like the dual blade, dual pistols, or street fighting, Titan Weapon, Staff Fighting (notice these are all offensive powersets, so mutually exclusive on one single toon). Fiery Embrace is an exception, but it's a single power, it could manage with only one bit of the new bitfield. Each new power could use specific bitmasks to apply to the new bitfield, given the effect. This has to be done for these 5 or 6 power sets, and you have to code the method to parse these commands, but it's not goint to take 10 hours.
Do you write your own Fury system and redo all Brute attacks, or implement the Rage bar and Brute fury damage buffs within the data? |
I think its easy to say "just convert the data to formulas" without actually seeing the data or knowing the mechanics. I would challenge anyone to just *list* the mechanics that would have to be implemented in four weekends much less actually implement them in code. |
Basically, although there's some extra complexity in there that causes some effects players might not care about. My guess is that there's at least three main timing "loops": a 30/sec animation synchronization event loop that synchronizes server events with client activity, an 8/sec impulse action loop that the game engine uses to initiate events and actions, and I have some evidence for a 2/sec decision loop that determines when critters decide to take a course of action. I've actually put more thought than is really useful into how to account for time in CoH. How to deal with things like recharge and regeneration (tick decrementers seems the best approach), event overflow (i.e. Hami lag: global clock tick-based correction seems the best there) stuff like that. |
I should also mention that how we conceptualize what powers do as players and what they actually do mechanically are often very different. So if you decide to make a game based on the conceptual nature of the powers you may find yourself recreating the powers from scratch, because the data we have doesn't do what you think it does. |
For example, CoH has no "chaining" mechanic. None. Chaining powers grant powers to targets which create an aura around the target which forces the target to grant additional powers to a limited number of the targets around them which themselves damage the target and grant the same aura to those targets and set a flag which prevents the same target from being hit again by the target it hit with its own aura. All the data says is "give that guy a new power." It takes human comprehension to look at the sum total of what's going on and say "that's a chaining attack." But if you make a game engine with a chaining mechanic, what's going to use it? None of the powers in City of Heroes, until you make them do so by hand. Unless you're smart enough to create an expert system that can deduce developer intent from the data. |
A lot of powers work like this. Tanker single target attacks aren't: they are AoEs, all of them. That's so that taunt can hit multiple targets. But the damage in them is restricted to only the targets exactly zero feet from the center of the AoE. Which, in the modern game, is at most one thing. Do you implement that behavior directly, or do you again, by hand, change the definition of all those tanker attacks to be single target and implement a new mechanic for AoE taunt effects as a special case? |
[/quote]Do you directly implement exactly how our game engine deals with buffs that buff themselves? Or do you fudge, again by hand, Combat Training: Offense?[/quote]You mean things like resistible resistance debuffs ? Hell, I would straightly implement it without trying to fix it. It's part of the compliance. Buffs are always Irresistible and/or "Ignores Enhancement & buffs" to try to diminish these effects, even for resistance (doesn't take +dam into account)
There's actually a set of flags that tell the game engine to treat things like enhancements differently than powers - enhancements actually *are* powers, just powers that work differently. Do you hard code implement that distinction directly, and then have to deal with things like Luck of the Gambler: Def/+GlobalRech as yet another hand-edited special case? This is another case where we think of something as one thing, but the game thinks of it as something completely different, and there are cases where the difference is important. In the above enhancement, the +Def Strength should only affect the power its slotted into. The +Rech Strength should affect the entire player. There's no "rule of five" except in the devs' head. That's not something the game engine is directly aware of. Its actually just another Requires clause on the passive powers that are granted by the inventions as the set bonuses. Do you implement that in a hard coded fashion or do you implement that specific field in a general purpose manner? Because if you don't, you'll then have to make a special case rule for the "rule of one" used by Bruising, and the "rule of three" for the Might of the Tanker proc. |
If you don't implement all of the complexity of the game engine, you'll be left with the actual data being a cloud of special cases, which would probably take more time to implement in the long run. What we see and what the game engine does are often radically different in the details, and the game obscures a lot of funky activity the data contains to make interesting things happen. Skip that complexity in the engine, eat it in the data. There's no way around that. What's a single target attack, what's a pet, what's a buff, what's an enhancement - these all sound like easy questions to answer. But they aren't, at least not by just looking at the data. |
Conclusion:Hey hey hey ! we nearly went over all the mechanics of the combat in the game in a single post ! And you still think this would take 1000 hours ? Okay, I'll give you the time we are spending discussing this
WE ARE HEROES. THIS IS WHAT WE DO.
City et moi, �a colle !
2. Because pohsyb confirmed the existence of that system when I discussed game clocking with him.
And you still think this would take 1000 hours ? |
Ranging from 2 minutes to a week-end, depends on what that humanly means :S Looks like a coma-separated... thing, each thing between comas is a token meaning... function names, operators and parameters ? You would need to set up a grammar in Yacc or Bison (heh !) and make your hearts desire come true. |
To you its just tokens. But its actually an example of the number of moving parts in the game engine you can't trivially simplify.
There are dozens of attributes with half a dozen aspects, plus over a hundred mechanically different ways to affect them. That's hundreds of hours just to create a complete attribmod calculator. If you spent 24 hours a day for four weekends I would bet anything you would not be finished with that, and that's maybe 15% of a working combat game engine.
It took me two weekends worth of work to write the code to simulate enough attack calculations to generate my attack set metrics for I24 beta ranged set metrics, and I hadn't finished adding the tohit tracking for fast snipe. That would be about 0.5% of a working combat engine.
Honestly, I recommend you to spend just a single weekend writing as much of an attribmod calculator as you can. Not even an engine, just a calculator that can be given a set of attribmods and will calculate what the attribute values are for the entity that has them for the full duration of those attribmods, moment by moment. That's like at most 1/6th of a full combat engine. If you think you can write a full combat engine in four weekends, you should be able to do this in one without missing the NFL late game.
Just try it for even one hour and see how far you get. I can only assume you are dramatically underestimating the time necessary because you have no reference to compare to.
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
We are making progress
Quote:
2. Because pohsyb confirmed the existence of that system when I discussed game clocking with him. |
If anything, my estimate actually went up. You seem to be dismissing anything that isn't "hard" as taking essentially no time, when the problem isn't complexity, its thoroughness. |
For example: That's just a postfix expression. But you're focused on the grammar, and not on all the systems that grammar implies have to exist. Its referencing entity properties set by other mechanics, all of which would require more code. There's no possible way to make the expression system work in a week end. To you its just tokens. But its actually an example of the number of moving parts in the game engine you can't trivially simplify. |
There are dozens of attributes with half a dozen aspects, plus over a hundred mechanically different ways to affect them. That's hundreds of hours just to create a complete attribmod calculator. If you spent 24 hours a day for four weekends I would bet anything you would not be finished with that, and that's maybe 15% of a working combat game engine. Honestly, I recommend you to spend just a single weekend writing as much of an attribmod calculator as you can. Not even an engine, just a calculator that can be given a set of attribmods and will calculate what the attribute values are for the entity that has them for the full duration of those attribmods, moment by moment. That's like at most 1/6th of a full combat engine. If you think you can write a full combat engine in four weekends, you should be able to do this in one without missing the NFL late game. Just try it for even one hour and see how far you get. I can only assume you are dramatically underestimating the time necessary because you have no reference to compare to. |
It took me two weekends worth of work to write the code to simulate enough attack calculations to generate my attack set metrics for I24 beta ranged set metrics, and I hadn't finished adding the tohit tracking for fast snipe. That would be about 0.5% of a working combat engine. |
WE ARE HEROES. THIS IS WHAT WE DO.
City et moi, �a colle !
The Mids or even the City of Data database is a bad place to start. Despite my efforts to modernize CoD, it's still lagging behind as far as actual implementation details. There's a lot of fields in the powers that it doesn't even display, like activation requirements, target requirements, etc.
I actually miswrote that. I meant: What makes you think the 1/30 sec loop is the animation one ? Is it exclusively animation ? I think it's the combat/vitals loop, and the 1/8 sec loop the positionning loop, and animation is just a by-product of the power part of combat.
|
30hz would be awfully inefficient for a combat loop just because of how much time you'd spend re-evaluating things that don't really change all that often, relatively speaking. The server DOES have to process animations, if for no other reason than to figure out how long to root a player, since the only place that information exists is on the flags of the animations themselves (the ones flagged CantMove). Not to mention the timing for things like weapon redraw.
I think it's been fairly well established by information posted by developers that there are two separate loops going that interact with each other periodically.
But I also think what remaining out of our reach is the "which powers has every NPC" database.
|
It's an example of what, actually ? When does this get involved, and what does it do client-side ? I did throw grammar at it because I didn't know what that was. I do want to know when and what because that could help me understand the mechanics, not reinvent an emulating mechanism. I know you don't invent things, but I was as puzzled by this as much as if you did. I could have called that an "*** pull". If it's power-related and not in the City of Data database, it's useful. If you just applied that fancy representation just for the pleasure of finding me dumb-founded... well... I don't see the point.
|
City of Data pretties them up a bit before displaying them as conditionals -- it contains a parser that re-arranges them into algebraic notation. It also evaluates them in order to try to figure out if a certain effect is PVP or PVE-only, and whether or not to count it in the "average damage" total.
Incidentally, I did write that parser over a weekend, but it's a grossly simplified version. It implements all of the grammar I believe, but when evaluating most of the variables just dummies them out as zero or a predefined default.
We are making progress
I actually miswrote that. I meant: What makes you think the 1/30 sec loop is the animation one ? Is it exclusively animation ? I think it's the combat/vitals loop, and the 1/8 sec loop the positionning loop, and animation is just a by-product of the power part of combat. |
The difference between what I'm calling an "action" and an "event" is: activating a power is an action. A regeneration tick is an event.
Ok, so the only hard part is thoroughness, you say ? My thoughts exactly. But most of the thoroughness is already made by datamining efforts done by the Titan Network with City of Data or the Mids. |
Also, this assumes the person looking at the data knows what they are looking at.
ho ho ho, now you're getting interesting ! Okay, I take the bait. |
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
In some ways, I think it is easier to create a similar system, with possibly changed under-the-hood mechanics, than it would be to reverse engineer the CoH engine. I think part of the problem Arcanaville is stating is that the game engine is inherently complex to decode.
However, a coder doesn't have to worry necessarily about the complexity of the system. For instance it may be almost impossible to determine what the net effect of a power is, but that doesn't mean it is impossible to code. If we simply add parts to the machine, and those parts interact, then the machine grows exponentially more complex but did not necessarily take exponentially more work to create.
For instance, take a function y = x. Simple and easy to calculate. Now say we wanted it to be slightly more complex, and made it y = e^(x).
Continuing to increase the complexity:
y = e^(sin(x)
y = e^(sin(x^2)))
y = e^(sin(x^2))/hyptan(x))
etc. Already we have a very difficult function to predict. And this is just a simple function of x and y. If I gave someone a graph of the function the function, it would hard for them to deduce the formula I used to create it.
However, if I told someone the function, they could easily tell me what it would do by plotting it out. Alternatively, if I told someone I wanted a graph that alternated between 2.6 and .42, with increasingly fast periods and a vertical asymptote at 0, they could create something that would resemble the function I described. It might have small differences (such as those produced in the games timing systems), but ultimately the functions will have a rough similarity that may be enough to fool a person into thinking they are the same graph.
Basically, what I'm saying is that completely recreating CoH's engine with perfect accuracy is a project that could easily take 5000+ hours. However, creating a engine that produces similar results might not take the same amount of time. For instance, such an engine might not have the desynchronization that this engine's clocks have.
I'm not saying that the work required to create such an engine would be unsubstantial, but it is entirely possible that it could be easier to code than the alternative. I'm not a programmer, but my limited understanding tells me that the simplest of the game's mechanics (Damage, resists, defense, healing) could be simply reproduced.
What I would worry about would be AI, the enhancement system, and oddities of the current system. I'm not talking about instantly recharging powers or chaining, but instead things like the fact that resists and damage are tied together. Of course, a new game engine could possibly change that, and allow damage enhancements to be slotted into Assault and other sort of things that aren't allowable with the current system.
Essentially, I'm saying that coding the simple parts of the system would not necessarily be hard to do. However, trying to make sure that the same oddities are present, such as the desynchronized clock and the various oddities tied with the way the game considers several differing things to be the same effect.
TW/Elec Optimization
Basically, what I'm saying is that completely recreating CoH's engine with perfect accuracy is a project that could easily take 5000+ hours. However, creating a engine that produces similar results might not take the same amount of time. For instance, such an engine might not have the desynchronization that this engine's clocks have.
|
Consider everything that happens when I activate an attack. Do I have something targeted. Is that thing a valid target for the power. Do I have enough endurance to activate the attack. Am I currently rooted. Does the attack require the target to be near the ground. Does the attack autohit that type of target. What is my base tohit verses that target. What are my net tohit buffs and debuffs. What's the highest net defense of the target applicable to the attack's attack types. What's the accuracy of the attack. What's my net tohit. Does my tohit roll fall below the tohit threshold. What are the attack's effects. For each effect, does it affect the caster or the target. Does the effect have target conditionals. Is the target within the outer radius limit of the effect. Is the target outside the inner radius limit of the effect. What attribute does it affect. What aspect of that attribute does it affect. Are there combat modifiers (level differences) in play. Is the effect immune to combat modifiers. What kind of effect is it: is it a Magnitude or Duration effect. What's its scale value. Is it an expression based magnitude effect. What does its magnitude expression evaluate to. What is its effect modifier at this level for the caster's archetype. Does the effect have a chance to occur. Does the effect have a duration. Should we resolve the effect immediately or should it be delayed. Does it have a period. Does the target have resistances to this effect. Is the effect unresistable. Does caster strength affect the effect. Is the attack itself immune to such strength. Does the effect create an entity. Does the effect grant a power. Does the target currently have an effect identical to this one cast by the same caster? Does the effect stack from the same caster. Does the target currently have an effect identical to this one cast by any caster. Does the effect have a stacking limit. Is the current number of identical effects under the stacking limit.
None of these things are things you can handwave away, and still have a game that functions like City of Heroes.
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
The 8/sec loop determines when actions can start, the 30/sec loop specifies when events occur, and it keeps the server and the client synchronized.
The difference between what I'm calling an "action" and an "event" is: activating a power is an action. A regeneration tick is an event. |
[quote]Nope. Every bit of data implies hundreds of lines of code to do something with that data.[quote]NO NO NO NO and NO for god's sake ! What kind of project manager believes that ?
Once you've implemented something able to decode the data behind, let's say, the Nemesis Staff, it's far easier to do the Force Field.Force Bolt ! But you can't directly do Smite then, except if you've done Shadow Punch ! You have a baseline of minimal data to process and then all the data can be processed by the engine ! It's not because you've got 1000 powers and that it takes 1000 lines to implement Brawl at first that it's going to require 1000x1000 to implement everything ! Gosh !
Also, this assumes the person looking at the data knows what they are looking at. |
That would be more definitive than debating it, because honestly there's not all that much to discuss without flat-out writing a spec for the engine. Only by looking at the data for real and writing code for real are you likely to appreciate the scope of what we're discussing. Or alternatively, your idea of the scope of what we're discussing is radically different than mine. |
WE ARE HEROES. THIS IS WHAT WE DO.
City et moi, �a colle !
Mister_Bison, out of curiosity, don't take this wrong I just want to see where we all standing here and where everyone is comming from:
What is the largest coding project you have engaged on solo? What about in a team?
What about experience with networking code?
What about real-time game development?
It will always amuse me how threads evolve around here.
Be well, people of CoH.
Okay so the action loop is filling the event loop's data ? Action's loop is processing the "launch power"s and the event loop the "Do X points of damage"s ? (notwithstanding all the other things in the event)
|
This interplay generates the server side lag we call "Arcanatime." But even if you didn't want to reproduce this behavior, I'm not sure there's any significantly easier way to reproduce all of the events in the game engine as they occur. It actually took me a couple of days of thought and experimentation to come up with the design for a reasonable scheduler that would properly process everything that happens in City of Heroes.
Quote:
Once you've implemented something able to decode the data behind, let's say, the Nemesis Staff, it's far easier to do the Force Field.Force Bolt ! But you can't directly do Smite then, except if you've done Shadow Punch ! You have a baseline of minimal data to process and then all the data can be processed by the engine ! It's not because you've got 1000 powers and that it takes 1000 lines to implement Brawl at first that it's going to require 1000x1000 to implement everything ! Gosh ! |
On top of that, many fields are themselves indirectly processed, like the Expression fields which themselves require an entire scripting engine just to process. And parsing the grammar of the Expression fields is exactly zero percent of the problem. The real problem is writing the code to properly evaluate all of the indirect references to the game. Which *itself* requires entity tracking code to allow for those indirect references to go somewhere. AttributeRequires as a single field could end up taking ten times more code than fully processing all of the damage-type attribute fields because of that.
(Since Abs and Cur modifiers on those attributes actually point to Health, they can all be processed with an iterated loop of code, but they cannot be processed with the same code as all other attributes with their own separate attribute values directly. Doing crazy pointer magic to make all of the attributes work with a single processing loop would save some coding time, but probably add significant debugging time to the process.)
At this point, I'm really interested to see what sort of code you generate, to represent your understanding of the actual problem being discussed.
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
I've been involved in various scales of software development and design for about 15 years now, and I'm closer to Arcanaville's position than Bison's.
Writing code to handle, say, damage boosts may not give much reusable code for, say, maxHealth boosts. There might be common code for accessing the raw data elements, but then a great deal of completely unshared code for how those data elements are processed once retrieved.
Blue
American Steele: 50 BS/Inv
Nightfall: 50 DDD
Sable Slayer: 50 DM/Rgn
Fortune's Shadow: 50 Dark/Psi
WinterStrike: 47 Ice/Dev
Quantum Well: 43 Inv/EM
Twilit Destiny: 43 MA/DA
Red
Shadowslip: 50 DDC
Final Rest: 50 MA/Rgn
Abyssal Frost: 50 Ice/Dark
Golden Ember: 50 SM/FA
Mister_Bison, out of curiosity, don't take this wrong I just want to see where we all standing here and where everyone is comming from:
What is the largest coding project you have engaged on solo? What about in a team? What about experience with networking code? What about real-time game development? |
Sure I'm not a multi-decade code veteran here, I didn't code in Basic or Fortran, nor on Amiga or Amstrad, but that doesn't mean I don't have a brain and can't learn or work, or that what I was taught was crap. Doesn't mean I know it all either. I actually want to appear stupid and get told things harshly than people saying nothing and letting me in the wrong. Actually, I've come to see this little explanation as tutoring on the game's mechanisms, making notes here and there that could see better use than in the dark corners of a single brain. Also, I'd like some people to come to term with their assumptions that there is only the harsh way to an implementation.
Originally Posted by ArcanaVille
More or less. Critically, the 30/sec loop also calculates when animations start and stop, because that has to be in sync with the client that does animations. At launch, there were all sorts of odd glitches where the player would activate a power and the character would just stand there. That's because the server told the client "do this" and the client said "can't, still doing that" and then the client said "done, now what" and the server said "forget it, I'm already moving on to the next thing." The server has to know what the client is doing, which is why the server, among other things, has to now what is happening at every 30th of a second, because the client works on that clock.
|
This interplay generates the server side lag we call "Arcanatime." But even if you didn't want to reproduce this behavior, I'm not sure there's any significantly easier way to reproduce all of the events in the game engine as they occur. It actually took me a couple of days of thought and experimentation to come up with the design for a reasonable scheduler that would properly process everything that happens in City of Heroes. |
What's actually the most unnerving in network play ? movement lag. Power lag, everybody can do with it, but jumping a fraction of a second too late and your down the hole instead of on the other side. So movement has a special treatment in network games, everytime. Since you have the network lag, it's no use doing it 120 times a second, that's why the Entity placement engine is on this 1/8 timer, and power launching is the duty of the placement engine because line of sight is one of the requirements. But the combat/effect timer can be as fast as you want, basically, because you have events based on time, and in a second it doesn't matter if you loop 2 or 6 times because you'll have to do as much processing (well, not to maintain every timers) but you'll have as many messages to send.
Originally Posted by ArcanaVille
Assuming I'm an idiot will only cause me to conclude you're one. Because every *other* programmer in this thread that has worked on something larger than "Hello World!" I'm pretty sure understood what I meant, which was that every data element in the power schema represents a data field which is processed by the game engine, each in a completely different way. Especially within the context of everything else I've said in the thread.
|
[/quote]On top of that, many fields are themselves indirectly processed, like the Expression fields which themselves require an entire scripting engine just to process. And parsing the grammar of the Expression fields is exactly zero percent of the problem. The real problem is writing the code to properly evaluate all of the indirect references to the game. Which *itself* requires entity tracking code to allow for those indirect references to go somewhere. AttributeRequires as a single field could end up taking ten times more code than fully processing all of the damage-type attribute fields because of that.[/quote]What's this "expression field" you're waving around ? never heard of that. That's the list of power effects ? Codewalker already said it was done, and I'm not one to let done work spoil.
(Since Abs and Cur modifiers on those attributes actually point to Health, they can all be processed with an iterated loop of code, but they cannot be processed with the same code as all other attributes with their own separate attribute values directly. Doing crazy pointer magic to make all of the attributes work with a single processing loop would save some coding time, but probably add significant debugging time to the process.) |
EDIT: As I lied down to sleep, I understood your point about damagetype attributes and health now. That does shake my already-laid coding plan, but I'll make up a workaround this night I think, else tomorrw, else, with an ugly hack.
At this point, I'm really interested to see what sort of code you generate, to represent your understanding of the actual problem being discussed. |
WE ARE HEROES. THIS IS WHAT WE DO.
City et moi, �a colle !
We have access to that, just haven't advertised it. Come to think of it I'm not really sure why the client would possibly need that data, but I guess I can't complain that it was included.
|
May I ask why the NPC data was always kept hidden in the back-end of things? I've often wanted to be able to, say, look at how much resistance various enemies have, or exactly what the various powers of the Awakened are doing behind the scenes as they charge up and flash text at me, and it's always been a bit frustrating to know that it's in CoD, just hard to find.
|
WE ARE HEROES. THIS IS WHAT WE DO.
City et moi, �a colle !
Because you have an in-game tool to do exactly that, it's the power analyzer (MK3 to hit any mob). Once it has hit you have the hit entity's real numbers (attributes), and so this data would have come to nullify the need for this power.
|
The actual answer to the question is that the original game designers believed as a matter of game design philosophy that it was harmful for players to understand the game mechanics, because it was felt that this would lead them to focus on game mechanics themselves instead of playing the game as presented. They wanted us to enjoy the game for its qualitative features instead of its quantitative ones.
Personally, I think this was terribly misguided. Access to how something works does not primarily drive whether people focus on it. People who want to focus on those things will do so, and people who don't want to will not do so, whether the information is easy to access or not. Yes, there are some middle-ground folks who might swing one way or the other depending on what the game provides, but I suspect very much that they average out overall.
Unfortunately for this game's original devs, its designers were either very bad at math, or at least very bad at interpreting how the things math told them would translate into functional play. Because the players were largely disallowed from knowing the math or the numbers to plug into it, they could not detect this or show it except qualitatively, at run-time. That made it very hard to convince the devs of real performance issues, for either over-performing or under-performing things.
Blue
American Steele: 50 BS/Inv
Nightfall: 50 DDD
Sable Slayer: 50 DM/Rgn
Fortune's Shadow: 50 Dark/Psi
WinterStrike: 47 Ice/Dev
Quantum Well: 43 Inv/EM
Twilit Destiny: 43 MA/DA
Red
Shadowslip: 50 DDC
Final Rest: 50 MA/Rgn
Abyssal Frost: 50 Ice/Dark
Golden Ember: 50 SM/FA
Depends on what you mean by "similar." What I was talking about was reproducing, in effect, every aspect of every power and every enhancement currently in the game. Its not necessary to do that in the same way as the game engine, but if you're not reproducing the CoH engine precisely, you're just making a different game, which was not what I was talking about.
Consider everything that happens when I activate an attack. Do I have something targeted. Is that thing a valid target for the power. Do I have enough endurance to activate the attack. Am I currently rooted. Does the attack require the target to be near the ground. Does the attack autohit that type of target. What is my base tohit verses that target. What are my net tohit buffs and debuffs. What's the highest net defense of the target applicable to the attack's attack types. What's the accuracy of the attack. What's my net tohit. Does my tohit roll fall below the tohit threshold. What are the attack's effects. For each effect, does it affect the caster or the target. Does the effect have target conditionals. Is the target within the outer radius limit of the effect. Is the target outside the inner radius limit of the effect. What attribute does it affect. What aspect of that attribute does it affect. Are there combat modifiers (level differences) in play. Is the effect immune to combat modifiers. What kind of effect is it: is it a Magnitude or Duration effect. What's its scale value. Is it an expression based magnitude effect. What does its magnitude expression evaluate to. What is its effect modifier at this level for the caster's archetype. Does the effect have a chance to occur. Does the effect have a duration. Should we resolve the effect immediately or should it be delayed. Does it have a period. Does the target have resistances to this effect. Is the effect unresistable. Does caster strength affect the effect. Is the attack itself immune to such strength. Does the effect create an entity. Does the effect grant a power. Does the target currently have an effect identical to this one cast by the same caster? Does the effect stack from the same caster. Does the target currently have an effect identical to this one cast by any caster. Does the effect have a stacking limit. Is the current number of identical effects under the stacking limit. None of these things are things you can handwave away, and still have a game that functions like City of Heroes. |
Actually, I feel the really difficult things to simulate would be things other than the combat engine. I think we know enough about that engine to logically recreate a functionally similar entity. But even a combat-centric game like CoH has huge amount of extra systems that also need to work right, and I think that the potential for difficulty is way higher for those other systems. I personally have no idea what the difference is between Pet AI and mob AI, and the coding that goes into that (except that you are responsible for mobs dealing twice as much damage through AI tweaks).
TW/Elec Optimization
Sure I'm not a multi-decade code veteran here, I didn't code in Basic or Fortran, nor on Amiga or Amstrad, but that doesn't mean I don't have a brain and can't learn or work, or that what I was taught was crap. Doesn't mean I know it all either. I actually want to appear stupid and get told things harshly than people saying nothing and letting me in the wrong. Actually, I've come to see this little explanation as tutoring on the game's mechanisms, making notes here and there that could see better use than in the dark corners of a single brain. Also, I'd like some people to come to term with their assumptions that there is only the harsh way to an implementation.
|
Do this experiment: at random select 10 libraries/classes/whatever code files you are familiar with in one of those projects. Without opening them, guess how many lines of codes they have. Write it down. Then open them and count them. How many did you get right?
I am looking at a very simple piece of code right now, does nearly nothing. Its 112 lines of code. There is no optimization that can be done to it, its rather sleek code. Best I can do is making it hard to read by bumping code lines on top of each other and deleting comments. This just makes it harder to work with later, though.
The point is, you can have a perfectly clear idea of how to approach a coding task, you likely have what it takes to do so, but without enough years of experience you are nearly certainly going to understate how long it will take you.
Again: not doubting your ability to do the job we are talking about, I am doubting your ability to do the estimate on how long it will take you and how many lines of codes you will end up with.
Heck, after 16 years of coding for a living, I still often understate it! I made a habit of just padding it upwards because I KNOW I am getting it wrong.
BTW: I am not singling you out. I asked you because I am already familiar with Arcanaville's background. You will notice I also still asked her about her 3k hour estimate (for a MyBrute project) despite knowing that, though.
Oh one last thing: real time game development does not mean things wont lag. "Real time game development" simply means the loops are aware of how long they take, and advance things appropriately. If a loop gets overloaded for any reason and is delayed, there will be lag, but time will not come to a halt. CoH server is real time in that sense. If something overloads and a loop hangs for 2 seconds instead of 0.125, you still will see 2 seconds pass in the recharge timer of all powers (for example) or enemies move 2 seconds worth of distance based off their last active speed, etc etc. [It also may mean the game is not turn based but that's not what I mean here.]
Wait, the client shouldn't do anything, it's a client, it sends request and gets updates, everything happens server-side, well, nearly everything, at least everything combat(and animation)-wise are decided on the server-side and just user input is forwarded by the client (things like respec or real powers for instance use data on the client side plus eventually some constant data received from the server ages ago, like the chosen powersets and currently slotted enhancements). Since you would know some lower bounds to some effects you can program the client to actually don't forward things the player can't do anyway, but ultimately the server has the hand and say 'it's ok'. If it was like you said, if the server kept in sync with the client, how could you have powers showing ready when they are not ? How could I animate Haste (though only the excitation/shrugging, not the pompoms) when I activated it when it wasn't server-ready ? I believe the client does not sync the "animation", the rooting for sure (because it defines what the player is able to do) but not the "play flare animation" part. Animation is fluff, feedback, rooting is an effect, even if it's "animation rooting", isn't this why some powers don't root anymore (non-offensive PBAoEs anyone ?) Or am I missing something
|
What's actually the most unnerving in network play ? movement lag. Power lag, everybody can do with it, but jumping a fraction of a second too late and your down the hole instead of on the other side. So movement has a special treatment in network games, everytime. Since you have the network lag, it's no use doing it 120 times a second, that's why the Entity placement engine is on this 1/8 timer, and power launching is the duty of the placement engine because line of sight is one of the requirements. But the combat/effect timer can be as fast as you want, basically, because you have events based on time, and in a second it doesn't matter if you loop 2 or 6 times because you'll have to do as much processing (well, not to maintain every timers) but you'll have as many messages to send. |
Quote:
|
If you don't know these things even exist, I'm not sure how you can be so certain about your estimates for how long it would take to reproduce all of the combat engine's behavior.
That's still only 2 things to do differently, and since you've got functions, with parameters you can code pretty much any number of cases in your functions. It doesn't reduce the complexity though, I agree. It has to be somewhere. But you don't have to code a function for every existing combination of effect. What's the parser for then ? That could sort things out. But do we agree I just have to produce a library that handles entities and all their attributes (inspired from the attribute window plus every hidden attribute/fields I need for the implementation) and "example" functions that apply all power effects that I can think of and translate it into calls to that library ? Then the next stage would be executing said function when parsing the matching power's effects part. |
while(true): evaluate(power)
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
May I ask why the NPC data was always kept hidden in the back-end of things? I've often wanted to be able to, say, look at how much resistance various enemies have, or exactly what the various powers of the Awakened are doing behind the scenes as they charge up and flash text at me, and it's always been a bit frustrating to know that it's in CoD, just hard to find.
|
CoD can show it if they wanted, but they would likely get in trouble with the devs, who would either attempt to take them down or obfuscate data in the client further.
Actually, I feel the really difficult things to simulate would be things other than the combat engine. I think we know enough about that engine to logically recreate a functionally similar entity. But even a combat-centric game like CoH has huge amount of extra systems that also need to work right, and I think that the potential for difficulty is way higher for those other systems. I personally have no idea what the difference is between Pet AI and mob AI, and the coding that goes into that (except that you are responsible for mobs dealing twice as much damage through AI tweaks).
|
I know I spent a couple of weeks, off and on, just musing to myself how the game engine must work for unresistable resistance debuffs to work they way they do and for Combat Training: Offensive's accuracy buff to work as it does. When I posted my results on ranged damage metrics in the beta fast snipe thread a legitimate question was whether I had properly accounted for sonic blast buffing its own DoT with -Res - which I had not, because my calculator (deliberately, due to time constraints) did not deal with effect over time specifically in that manner. But that has a very significant impact on Sonic's numbers.
Having written damage calculators, damage mitigation simulators, and other discrete calculators gives me a particular perspective on this topic. The sheer amount of stuff the game engine does is enormous compared to the amount of time it takes to account for each effect.
Also, it was only on average about 28% more damage except in some degenerate cases.
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
Exploits. If everyone can read the data easily, things like Hamiddon would have been defeated on day one.
CoD can show it if they wanted, but they would likely get in trouble with the devs, who would either attempt to take them down or obfuscate data in the client further. |
By mutual agreement, most of the people (I'm aware of) that were capable of seeing that data elected to show player data and not critter data, due to the potential for critter data to be used for exploitive purposes or to spoil the intent of certain content. For example, before I told the players what the LRSF towers did, I tested them myself to prove that knowledge was capable of being determined in-game by a player, and even so I left one thing out until the devs granted me permission to mention it - the momentary intangible buff that allowed Recluse to break toggle debuffs.
[Guide to Defense] [Scrapper Secondaries Comparison] [Archetype Popularity Analysis]
In one little corner of the universe, there's nothing more irritating than a misfile...
(Please support the best webcomic about a cosmic universal realignment by impaired angelic interference resulting in identity crisis angst. Or I release the pigmy water thieves.)
Radiation Armor
Radiation Melee
Psionic Melee
Force of Will
Gadgetry
Experimentation