-
Posts
656 -
Joined
-
Last visited
-
Days Won
1
Content Type
Profiles
Forums
Events
Store
Articles
Patch Notes
Everything posted by UberGuy
-
Hrmph. This is probably going to trigger a mini project I've been able to avoid. Most of the distinct visual "widgets" you see on CoD pages are distinct modules of code, and have their own sense of state and programmable behaviors distinct from other things on the page. Individual attribmod rows under each effect group are not like this. Effect groups are, but attribmods in the groups are not. As a refresher, the rough logical hierarchy for powers looks like this: Power | +---EffectGroup | | | +-----Attribmod | +-----Attribmod | ... +---EffectGroup | | | +-----Attribmod | +-----Attribmod | ... ... Similarly, the panel on each CoD powers pages labeled "Effect Groups" contains one "widget" for each effect group. It is, in turn, composed of smaller, specialized widgets, such as: all the icons for each group, all the icons for each attribmod in the group (which appears once per attribmod in the group), and any nested effect groups (meaning the effect group widget can display other effect group widgets to arbitrary nesting depth). But what is not a widget of its own is the place where each attribmod's info is displayed. Instead that's just part of the Effect Group widget, which renders one row of info per attribmod in the group. This was mostly fine (but never awesome) when I was displaying simpler stuff in each row. But now that CoD is more complex, partly due to better understanding on my part and partly due to new features in the powers system, I find myself wanting each attribmod display to be a widget. That would let it hold state and remember what details it has already rendered. Right now if anything needs to change I re-render the whole effect group. And if I am changing one, I am probably changing them all. Now, that probably sounds bad, but it's not terrible - most powers don't show that much info. But what made me really notice this (mentally, not visually) was that if I want add a control somewhere on the page that lets you control how "tick-mods" are displayed, the only way to update any of them is to refresh all of them, whether they have any "tick-mods" or not. That withers my developer soul a little. Now, that said, this is how changing the AT dropdown or level slider have always worked. When you change them, every effect group is re-drawn. But that feels less awful, since changing AT mods or level values really changes what a lot of attribmods need to display. Anyway, I'm mostly just "stream-of-consciousnessing". I may just suck it up and do this the less fancy, less elegant way, but I'm tempted to spend a bit more time now making it easier to work in new attribmod changes in the future.
-
Not native to the site, no. You'd need a way to search by value on attribmod fields which would be crazy to try and index for use in the browser. (Remember, there are no logic servers for CoD - everything is done in your browser based on pre-prepared data files the web pages pull in.) However, if you're handy with searching text files, it's possible to find it in the raw data. This is actually how I checked for powers to look at when updating the site. I like RipGrep for this sort of thing. $ rg 'f_tick_mag_additive' | rg -v ' 0.0,' powers/mastermind_pets/zombie_minion/summonarmor.json: "f_tick_mag_additive": -0.013199999928474426, powers/mastermind_pets/zombie_minion/summonarmor.json: "f_tick_mag_additive": -0.013199999928474426, powers/mastermind_pets/assault/conserve_power.json: "f_tick_mag_additive": -0.0027000000700354576, powers/mastermind_summon/mercenaries/serum.json: "f_tick_mag_additive": -0.008799999952316284, powers/mastermind_summon/mercenaries/serum.json: "f_tick_mag_additive": 0.06599999964237213, powers/mastermind_summon/mercenaries/serum.json: "f_tick_mag_additive": -0.02199999988079071, powers/mastermind_summon/mercenaries/serum.json: "f_tick_mag_additive": -0.002199999988079071, powers/mastermind_summon/mercenaries/serum.json: "f_tick_mag_additive": -0.002199999988079071, $ rg 'f_tick_mag_multiplier' | rg -v ' 1.0,' $ That first command says "look for files containing lines with the string f_tick_mag_additive that don't contain ' 0.0,' (the default value of 0.0 with a leading space and a trailing comma)". It found 3 powers (it lists Serum multiple times because there are multiple different additive things in there.) The second command looks for files containing lines with the string f_tick_mag_multiplier that don't contain ' 1.0,' (again the default with leading and trailing markers so we don't get substring matches). There are none of these so far.
-
Data is currently uploading, then the site code will be updated. Call it 30 minutes from this post. As always, let me know if you see strange and/or broken things.
-
So one of the new features in the powers system is the concept of "accumulating" changes on attribmod values. These change the current value of an attribmod by a small amount every server tick. Currently this is used in a few Mastermind powers (or MM pet powers) to create "decay" mechanics on buffs so that the buffs decrease over time. There are two base versions of this - additive changes and multiplicative changes. The additive changes create linear change, while the multiplicative ones create compounding changes that decay or grow on a curve. Technically a single attribmod can have both multiplicative and additive per-tick changes applied. All the current ones are additive only. The unit of time change on these is one server "tick". That's roughly 0.132 of a second, but that depends on how well the server is getting things done. Every time the game server updates things on entities in a zone, these per-tick accumulations are updated by the given amount and operation. Right now I have a fairly primitive display of these values - I am just displaying the raw number that's used to update the value per tick. Given how fast ticks are and how long most effects are meant to last, these numbers are quite small. It's not that helpful of a way to display it. I do plan to display a more useful number, but at least this gets it out there. I'm open to suggestions on good ways to do this. I am currently thinking (after confiming what a server "tick" should be) of displaying the additive changes as a "X% per Y seconds" value, with multiplicative values displayed as "decays/grows to X% of base after Y seconds". I can still display the raw value too.
-
Yeah, I am not sure if I can fix that without maintaining some sort of exception list. The "context free" way CoD tries to figure out whether something is PvP, PvE or either sadly depends a lot on allowed targets. There are actual PvP flags that mark an effect as PvP only, but that's not used everywhere, and it being achieved via player/critter target specificity is really common.
-
I'm behind on getting the latest page updates working. I got the bin parser and site builder working. There a handful of bin format changes scattered around various data structures, and while none of them were complicated, it took me longer than it should have to track them all down and account for them correctly. I finally got it fully working this morning. I now just need to update the site to display new fields and upload the new data. I do expect this to be done by no later than this evening US/Central time, hopefully sooner. I may have placeholder icons for a couple of new attribmod flags for the time being.
-
Focused Feedback: Power Level Availability Changes
UberGuy replied to The Curator's topic in [Open Beta] Focused Feedback
Something to bear in mind: if this change specifically causes certain content to be significantly easier because that content just happens to ride level boundaries that suddenly get powers they never used to, it's actually feasible for the HC crew to tweak the content to account for it, rather than avoid the change. This could be relatively simple stuff, like tweaking just the main bosses/AVs in a TF, tweaking the level transitions for the critters in it (say, bringing some scarier mob versions that only appear at higher levels down 5 levels or something), or just adding a new boss type here and there. I'm not attempting to trivialize this kind of change, but HC has some fairly active content devs. As long as such chances can be targeted just at specific content, I think it's feasible without being a big resource drain. I point this out because the arguments against this seem to center around certain, specific TFs because they happen to lay at level ranges where some meaningfully potent powers come into view that were not before. That doesn't sound like a wildly sweeping problem. Sure, it will also affect any missions in the same level band, but I think that's far less of a meaningful thing for your typical arc - mostly because of TF merit rewards. Even if moving of powers down somehow exposed new crazy farming missions or similar exploit-y things that never mattered before. that would still be something that can be fixed in a targeted way. I'm a huge fan of the T2 secondary change. I like the idea of the other stuff moving down so that we don't have to fill levels up with pool powers so much, but I wouldn't keel over if we didn't get it. I'm salivating over the T2 secondary one, though, and don't think any power creep it introduces (mostly at very low levels) is worth sweating. -
Sadly not much progress for the last couple of weeks due to real life complications (health issues with family members). FWIW, all is ... as well as it can be - the family member in question was not in great health to start with, and is largely back to their original state, but that's probably about as good as it's gonna get. So the crisis per se is probably past and my time commitments will hopefully be back to mostly normal.
-
OK, I think I'm finally done reworking how the back-end handles boost powers to enable easier display processing in the web UI. Now I just have to update the web side to do something useful with it! Here's hoping I'll be able to wrap that up by next weekend.
-
Some small fixes this morning: Dark Mode now more visibly shows the headers for power effect group sections. Previously the text was black on a very dark gray, which was basically illegible. It now matches the color of other text in either mode. Activation Effect groups that include pets in the target spec now display "self and own pets". The only other option is "self only". This is a bit of a hack, since the power spec can technically be set to things that would allow other kinds of targets, but Activation Effects are always applied with the caster as the main target (no matter what the base power says), so other target specs ultimately can only effectively result in the two variations "self only" and "self and own pets". A couple of universal set categories had their icons tweaked so they look less like generic enhancements of that type. Some of the power enhancement/set icon display code was cleaned up a bit, though this should make no functional difference. I'm still working on back-end code that lets me improve display of powers that are boosts. It has resulted in a major code reorganization and expansion which is still ongoing.
-
-
That isn't a bug. That's actually the only power directly attached to the entity definition. It gains the rest of its powers via GrantPower Activation Effect attached to other powers in the Symphony Control powerset. I do see a bug there though. It looks like Activation Effects can affect "CasterAndPets" and not just the caster. I'll have to fix a bit of display logic there, as it is currently showing "Self Only" for the AEG's GrantPower, which wouldn't make a lot of sense in this case. You can see the correct target spec in the raw data though.
-
Found some bugs in how enhancement names were being rendered by the code that does so. Pretty sure these have always been wrong - stuff like "Slow" being displayed as "MoveSpeed" and things that are debuffs missing the "debuff" part of the name. The data's been updated with the fixes - this really only affected how the Boost Sets pages display the component enhancements. Next up I'm going to see about adding a bit more description to simple procs. In some ways this will be easier than the enhancement naming, because the sign of the scale of the attribmod determines whether it's a debuff or not. With enhancements, the scale of the strength effect is (almost) always positive - the only thing you can look at to know if it's a debuff is to inspect what the boost power is allowed to be slotted in. Even so, there's some fiddly stuff I'm probably just gonna leave as "Proc", and people can click on it to see the actual power for more info.
-
OK, I got it working faster than I thought I would. Nothing new to see on the site (other than updated data). The code changes this time were just back-end improvements.
-
I haven't yet put yesterday's Alpha patch data on CoD. A few small changes in it that broke long-standing assumptions about a narrow bit of powers data. Nothing changed in data structures, but more how they're used. I'm working on some changes that make fewer assumptions about the affected stuff, and hopefully will have it done by the weekend.
-
New Naming Code Messed Up? Can't Create a Name I Just Deleted.
UberGuy replied to gameboy1234's topic in Bug Reports
So I think I found an old CB thread that talks about this, and I was able to reproduce the issue. What happens is that renamed characters sometimes end up with a duplicate slot assignment after a rename. This is not harmful, except that only one character in a slot can "win", and the loser seemingly disappears from the list. This is purely a UI thing - nothing bad happens to the underlying character info. It looks like the client checks for slot collisions (along with a couple of other invalid states) when reading the file fresh, so logging out and back fixes the issue. -
New Naming Code Messed Up? Can't Create a Name I Just Deleted.
UberGuy replied to gameboy1234's topic in Bug Reports
🤔 You likely did do this, but did you sign out and back in to confirm it was still missing afterwards? -
New Naming Code Messed Up? Can't Create a Name I Just Deleted.
UberGuy replied to gameboy1234's topic in Bug Reports
Make sure your character didn't jump somewhere else in your character list. Especially if you use a customized playerslots.txt. This change should have had no side effects capable of doing what you're describing, but I have seen characters apparently disappear when renamed. In my case, I had a playerslots.txt that had the same character name in multiple slots. The character went to the other spot in the list, which was on a different "page" of my list. -
Updates are publishing. This update contains the following changes: Data changes for today's patches for both Live and Alpha. Live data is now Page 4, and Alpha is whatever was added there on top of Page 4 today. Minor additional info displayed for powers that are boosts (AKA enhancements). The fact that a power is a boost is called out, just above its main data tables (below the description) If the boost has requirements, those are displayed next. Such requirements are used to restrict ATOs to their ATs, restrict "Superior" enhancements to level 50s, and create unique enhancements. The background disc used when the power is viewed as an enhancement in game is now placed behind the power's icon, so it looks more clearly like an enhancement. Less visibly, there are now moderately significant changes to the power info for boosts, moving the boost-specific fields into their own sub "object" and adding a a fair bit of additional data. This will be used to add more visual elements to both the powers page (when the displayed power is a boost) and to the boostsets page. Like many other things, these will likely be icons with "pop up" info indicating interesting info about the boost. For example: is it attuned? Can it be catalyzed and what does it turn into if so? Can it be boosted? Combined? Traded? And so on. I also plan to add enhancement borders to the icon displayed on the powers page for boosts. I have the beginnings of this code already on the boostsets page, but it only handles borders for boosts we find in boostsets, so I need to generalize it a bit and make it into a widget I can reuse on both pages.
-
As someone who often tries herding together more stuff than the aggro cap used to let me (often pulling one two groups onto a third) I'm a pretty big fan of the aggro change. That's not just for farming, either. Granted, the difference in "17 foes max, ever" and what we have now can get big fast if you're not careful, but I like it.
-
I am updating the site for Page 4. This release has relatively minor data changes so the bin parser required some small updates, already made based on the Alpha server. I was also in the middle of significantly rearranging some data structures around boosts (enhancements). This was all boosts, not just set pieces. To try and summarize what I was up to: boosts are just powers. A damage SO has all the core data attached that, say, a blaster blast or tanker armor has. Powers are usually the largest data structures in CoH. but powers that are boosts usually have, much fewer interesting bits of info that we really care about than non-boost powers. I wanted to expose this boost-specific data in multiple places, like both the powers page and the boostset page, without having to load each boost's whole power object to get at it. So I started breaking the boost-specific stuff out into a smaller object I could nest into the larger power dataset but also pass around on its own. One way I want to use this is to improve how boosts look when displayed as powers. A lot of boost specific info currently has no specific visual display, and the only way to learn about it is to look at the JSON data. Clearly this can be better, giving viewers more "enhancement specific" details more readily when the power they're viewing is, in fact, a boost. When I added boostsets to CoD, I added a bunch of code to handle boosts and to map their raw data to the ways we usually talk and think about enhancements. Think stuff like how "Heal" enhancements boost multiple attributes (Healing, Regeneration and MaxHP) and so on. But because I did it to support boostsets (IOs) I tangled the concepts of boosts and boostsets together in the code. For example, only boosts that were in sets actually got any extra inspection to map out what they enhance. Set pieces (IOs, ATOs, etc.) are not the only fancy enhancements around. Think about the GR "prestige enhancements" given out at character creation. And someday maybe more things like that could exist. To make sure things like that are processed for nice display, I needed to break boost and boostset concepts apart in the code. Boosts that are in sets still get extra info that "plain" boosts don't (like the name of the set it belongs to, etc.) but anything else needed to be inspected on every power that is a boost. Of course achieving that required ripping apart a bunch of code I had not really looked at in close to a year. I broke it a bunch, then slowly found (hopefully) all the places I broke it and pieced it back together. I was (I think) at the end of that today when Page 4 landed. I'm going through what I hope is some final testing and will update CoD shortly. Edit: Still squashing bugs. Getting close though. I think...
-
One small one went live tonight - the "burn rate" stat for toggles. For powers that are toggles with a non-zero endurance cost and a non-zero activate period, you get that parenthetical display of cost / interval divided by intervals / sec.
-
I'll definitely look into it, because it doesn't seem like it should be hard to do. When I generate the site I have all this stuff in memory at once, and I walk all the lists of things like powers and entities one at a time to export them each as their own files. So it's usually relatively easy to build indexes of stuff like that as I go. And hey, I'm working on new features anyway.
-
I've made some back-end updates that, right now, are only visible on the Alpha data. Most of it has to do with "requirements" expressions. As I've posted about in the past, CoH stores the logical and math expressions found in power, critter and other data in what's called postfix notation (AKA "Reverse Polish Notation" or "RPN"). This is an efficient, straightforward way to compute things, which matters a lot in places like attribmods of powers, which can cause many hundreds of evaluations per server "clock tick". However, it's not very friendly for most people to read. Those of us used to math or logical expressions are used to this: (a + b) - (c + d) / 4 not this a b + c d + 4 / - Now, CoD has long handled this conversion. It's something I spent a lot of time on early in the site's life. However, a general postfix-to-infix conversion is not exactly easy. You can find code that does it for simple cases (that handle "binary" operators like +, -, * and /) very easily with a good search engine. Code that gracefully handles things like unary operators (like negation or logical "not"), and proper emission of parenthesis are harder to come by. Early on, my approach to handling this was to use a symbolic math library called SymPy. This has functionality for simplifying expressions, which was a handy way to deal with the fact that my postfix-to-infix conversions were simplistic and so often produced visually ugly infix expressions. For example Input: a b + c + d + e + Output: ((((a + b) + c) + d) + e) Using SymPy to simplify expressions often provides a nice side benefit of taking expressions that make sense as efficient postfix operations, but render as ugly compound infix expressions. My goal in displaying expression info on CoD is for players to (hopefully) be able to comprehend what the expression does, not to preserve its native operation flow. SymPy's simplication logic usually makes expressions easier to mentally digest, combining repeated terms, reducing numeric constants to their simplest forms, etc. However, SymPy isn't able to do everything I want. First and foremost, it refuses to process otherwise valid expressions that combine boolean logic and regular arithmetic. For example, this is a valid CoH expression. (a || b || c) * 1000 That says "multiply 1000 times (if a or b or c)". Said out loud like that, it doesn't make much sense. But CoH's expression parsing engine is written in C, where "boolean" values are really integers. "True" is 1 and "False" is 0, so the expression above really means "1000 if a or b or c, else 0". It's actually quite an efficient way to express a certain subset of "X or 0" values. But SymPy, written in Python (where True and False are not integers) understandably refuses to process such constructs. When this happens, I fall back to the base postfix/infix converter. In such cases I lose not just the nicety of having SymPy rearrange grody expressions, but also it cleaning up after my wildly-nested parenthesis - something that often look particularly bad in long boolean expressions. What's changed is two things. I finally undertook improving the base converter, giving it the ability to emit the least parenthesis for a correct infix form of a postfix expression. Now that the "base" converter now emits nicely formatted infix expressions, I could see that in a lot of cases they're more nicely formatted than the raw SymPy version. SymPy still does extremely nice things my converter does not, usually making complex expressions easier to read. However, it does two things I don't like. It writes some things without spaces that I would prefer it spaced out. It writes "a + b" exactly like that, but writes "a * b" as "a*b" (no spaces). It follows Python operator precedence rules, which have some small differences from C, meaning it omits some parenthesis that could change the meaning of some expressions. This is an edge case, but once I saw it happening, I couldn't unsee it. Here's what the converter used to do: Convert postfix into "raw" infix If the conversion fails, emit the raw postfix as a string that says it couldn't be parsed Mutate the infix expression into valid Python/SymPy expression that still preserves its meaning Simplify the mutated expression with SymPy If SymPy cannot parse the expression, emit the "raw" infix expression Else emit the simplified infix Here's what it does now: Convert postfix into "raw" infix If the conversion fails, emit the raw postfix as a string that says it couldn't be parsed Mutate the infix expression into valid Python/SymPy expression that still preserves its meaning Simplify the mutated expression with SymPy If SymPy cannot parse the expression, emit the "raw" infix expression Else Convert the simplified infix back into postfix. Note that this still preserves changes SymPy made to the expression Convert this post-processing postfix back into infix Emit the final infix The last 3 steps above may seem like madness, but they let me apply the spacing and parenthesis grouping rules I choose instead of the ones that SymPy chooses, while still retaining the benefit of other, more significant expression reductions that SymPy applies. Important Note: I don't do much processing of expressions in CoD, and what I do process is done exclusively in the back end. (That's to say the website does not parse any expression data on-the-fly.) That said, I definitely do some parsing of expression data on the back-end, and when I started making these expression changes I immediately broke a few of them. In every case this was a sign that I was doing something wrong in the new code, not just that the layout of an expression changed slightly. After I got everything working without errors I checked over the modified Alpha data pretty carefully to try and ensure that only expected things changed, but I definitely might have missed something. If you see anything weird, let me know! Note for pedants: The different postfix/infix conversion stages are not exactly the same, since I have to account for the fact that SymPy and C have some different operator precedence, and so have different parenthesis wrapping rules for their infix expressions. Mostly all that changes is a map of operators to their priority, with just a few being different between stages. For the terminally curious, what's different there is that SymPy has higher priority for equality comparisons ("==" and "!=") than for boolean algebra operators ("&&" and "||"), which are themselves higher priority than the inequality comparison operators (">", ">=", "<", "<="). This is different than C, where "&&" and "||" outrank all the comparison operators, and is also actually different from what's documented for the Python language (where all equality and inequality operators have equal priority) which is what SymPy's docs say it follows.
-
I don't think displaying the end cost / time of toggles is a bad idea, but I definitely wouldn't replace the existing info. I'd probably add a derived "endurance burn" value somewhere that only appeared for toggles.