Developer Log - August 2023
The end of the month is approaching, so that means it is time for our August Developer Log. This is a brief summary of some of what the team has been actively working on over the course of the last month. While this does not include details about absolutely everything, we hope these sneak peeks pique your interest.
Dungeon Difficulty
Over the course of this month, we have been actively running tests of higher-level dungeons as we begin to properly tune around the greater player power that is available on Project Epoch via itemisation, extra talents for your level, and TBC classes. We've had swells of things being too simple, through to borderline one-shotting any class except a tank, but we're slowly reaching a point where we're happy with our findings, and realistically, only mechanical changes are required for future bosses, not raw values.
Below is an example of a recent test that we completed in the Blackrock Depths, facing off against Bael'gar. Please note that since this recording, some changes have occurred to things like ability lengths and power, but it shows a rough overview of the difficulty of content we're aiming for.
Racial Knowledge
In the not too distant past, we announced our plans for Racials and we're happy to say that progress down the path of building our Racial Knowledge system is reaching its end. Included is the addition of the content that surrounds the acquisition of Racial Knowledge, such as quests, new locations and new NPC's to meet on your journey. With that in mind, we wanted to not only show off a full end-to-end process of acquiring some Racial Knowledge but also tease some of the various locations you might uncover.
For those who are unfamiliar, Racial Knowledge is a simple system allowing you, as a player, to uncover how to replicate the Racial abilities from another race across class and faction boundaries, allowing the freedom to tailor your character as you see fit. These are acquired through lore-related quests available exclusively at max level, designed for solo play. An example of how this works can be found below, in which an Alliance player is embarking on the journey to uncover the Racial Knowledge for the Undead race.
An equivalent of the above has been created for every race and for each faction taking you across the world to uncover details about both friend and foe alike. As a tease for future content within the Racial Knowledge system here are some previews and teases of locations you may visit.
Bugs, Bugs, Bugs
Since Beta 2 we have fixed many bugs, including class related bugs. Some notable bugs players may be familiar with are the following:
- Fixed the remaining Shaman totems that did not appear on the Totem Bar and did not require their respective totem item.
This was caused by an interesting difference between TBC and WotLK. During TBC, a spell could have an assigned "Totem" item. This was used for shaman totems, of course, but it was also used for profession tools. Most blacksmithing recipes require the Blacksmithing Hammer "Totem". In WotLK, Blizzard expanded the Totem system to accept a category ID instead of a single item ID, meaning you could now have multiple items fill the requirement. This meant that when we ported over the TBC Spells, they had incorrect Totem IDs. The client searches for that totem requirement when assigning a spell to your Totem Bar!
- Fixed an issue that caused Priests to start with Mana Burn Rank 1 on character creation.
This bug has a long backstory, but we will try to shorten it. During Beta 1, it was discovered that Mana Burn Rank 1 dealt an incredible amount of damage. This was difficult to fix and prompted us to clone Mana Burn onto a new ID to get around TrinityCore's hardcoding of 3.3.5 functionality. We considered this bug important enough to hotfix onto the live Beta 1 servers, removing the old Mana Burn on login and replacing it with this new version. Unknown to us, however, there was a small typo that made Mana Burn rank 1 auto-learned for priests, causing it to show up when you made a new character. This small, single-number typo eluded us all throughout Beta 2!
- Kill Command now correctly becomes usable after the hunter deals a Critical Strike.
Kill Command uses a function called "Caster Aura State," which means that the ability lights up and becomes usable when you meet a certain condition. In this case, the condition is "When the player Critically Strikes." However, in Wrath of the Lich King, this condition went completely unused, meaning TrinityCore did not have it implemented.
- Fixed the proc chance of Omen of Clarity to match 2.4.3. It now has a PPM of 2 and a 10 second internal cooldown.
This one is pretty self explanatory, but it's an interesting one because its one of the few instances where Blizzard themselves confirmed the values!
This isn't all of the bug fixes we have made since Beta 2, just some of the more notable ones.
Classic Itemisation - Spells
If you remember our June log, we used data from TBC Classic to bring in proper spell scaling for all classes with great accuracy. We're excited to announce that this was utilized again to bring in item spell information from Classic 1.14! This means every spell effect on every item should behave as it did back in Classic, including spell scaling. Note that there will be exceptions; Diamond Flask will not scale with +Healing, for instance. This also fixes a great number of instances where TBC Ratings were appearing on Classic items, enchantments, and consumables.
While working on this, one of our developers got distracted with the Nightfall item, which he was using for testing. Nightfall had a broken texture up until Cataclysm, but even then, the skull on the axe never looked anything like a skull. So, Nightfall has received a new texture, fixing the issues Blizzard never did!
Loremaster Rework
Loremaster is an iconic achievement in World of Warcraft, and we needed to reimagine how this would work in Epoch with the additional custom content. Rather than require a simple number of completed quests in each continent, we've broken the requirements out into the main storylines found in each zone, by faction. The goal of this achievement is not necessarily to complete literally every quest, but to complete the major stories in the game.
Custom quest content is generally straightforward to add, but every Blizzard quest has been reviewed to see if it is a fit for the Loremaster achievement, and if so, where does it belong? Some quest chains live in single zones under a recognizable name, but many do not. As a result, there are some changes to Epoch Loremaster when compared to Blizzard's version. The general rationale for what is in each zone's achievement is as follows:
- Quests that are breadcrumbs only with no follow-up are excluded (example: Until Death Do Us Part)
- Escort quests inside of larger chains are excluded (example: From the Hold)
- Quests from items that aren't guaranteed drops are mostly excluded unless they're iconic (out: The Demon Scarred Cloak; in: Captain Sander's Treasure)
- Quests from one zone that are entirely completed within another zone are included in the zone where the action takes place (example: Whiskey Slim's Lost Grog is a Hinterlands quest)
- Key dungeon quests, especially if they're the end of longer chains, are included
- A few quests that don't have a geographic home are excluded.
Quest storylines are listed by name in the achievement. Most of the time, this is the name of the final quest in the chain, but we've tried to select the most recognizable identifier for the storyline. Sometimes this is the first name, or a general description. For example, "The Beasts of the Barrens" describes the quest chain that begins with killing Plainstriders and ends with killing Isha Awak, in which no two quests have the same name. The storyline name should be something you can easily find in a third-party resource if you're stumped on what it is referring to. It's our hope that this method makes it easier and more fun to complete Loremaster.
Creature AI Overhaul
Every now and again, a topic comes up where we as the developers and designers know that we can kill two birds with one stone and end up in a situation where we are not only more Blizzlike in nature but also able to produce accurate custom content at a more rapid pace. This topic, in particular, is Creature AI when casting spells in combat and the trickle-down effects.
Before
We are built using a foundation of TrinityCore; however, much of this section also applies to pretty much any public 3.3.5 based core that is currently available. Under the hood, the spells that a creature casts repeatedly while in combat are functionally run on a very simple timer-based system named SmartScripts, which functionally is more designed for RP events and general scripted actions such as talking, emotes, one-off spell casts, and so on, rather than designed for use as a Creature AI system.
In the following scenario we assume that a Creature has three spells at it's disposal:
- Fireball - 3 second cast - Does basic fire damage.
- Fire Blast - Instant Cast - Does basic fire damage and applies a DoT.
- Arcane Explosion - Instant Cast - AoE Arcane damage.
Each of the above has been set to initially cast between 0 and 5 seconds after combat begins and repeatedly cast it every 5 to 10 seconds after the initial cast. Functionally, with the existing TrinityCore behaviours, this plays out as follows.
- Every server tick (10ms -> 50ms) we reduce an internal timer for each of the above Spells.
- If the timer for a spell reaches 0 we attempt to cast the spell.
- If the cast succeeds or fails then we reset the spells timer to a fresh cooldown which is a random number between 5 and 10 seconds.
- Move on to next spell.
This leads to the behaviour of a Creature essentially trying to cast every spell it has as fast as possible, without any real care for if a previous spell has recently gone off or any number of other conditions. This rapid behaviour could lead to the following occuring:
- Server Ticks (50ms).
- Cast Fire Blast Instantly.
- Server Ticks (50ms).
- Cast Arcane Explosion.
Within a 100ms window, the Creature has casted two spells in quick succession, leading to what feels like very bursty gameplay and just feels 'off'. When timers don't overlap in a manner like this, then the basic TrinityCore system can function quite nicely, but there is always the chance for these awkward encounters. Trying to prevent overlap is essentially impossible with this system.
After
Thankfully, we at Project Epoch are always standing on the shoulders of giants, and information about how Creature AI should work is readily available and has been for many years. It is simply a lack of effort that has prevented the usage. The most commonly used 1.12.1 server core available is vMangos, birthed originally from Nostalrius, with the torch carried by many since, and this core contains a Blizzlike interpretation of how this should function. While we could not simply lift code directly due to fundamental core differences, the logic within served as our basis for an overhauled Creature AI system. Much of the research for how a system such as this should function has been heavily documented and validated by other teams such as Felmyst, and we heartily recommend reading through the linked research notes to better understand.
At its core the general concept of this is very simple:
- A Creature has a list of all Spells it has access to with the following properties:
- Probability (Chance) to occur.
- Initial Cast Time Min / Max Seconds.
- Repeat Cast Time Min / Max Seconds.
- Internal Cooldown.
- Target Type.
- Every server tick reduce the cooldown of the Spells a Creature has.
- Every 1200ms a Creature should attempt to cast one of its spells by doing the following.
- Loop through every Spell the creature has and try to do the following:
- Check the spell is off cooldown, if not abort and move onto next Spell in list.
- Check we can find a target for the Spell.
- Attempt to cast Spell on Target.
- If failed then abort and move onto next Spell in list.
- If successful consider this "decision" complete, reset 1200ms timer.
This means that in every 1200ms window, a creature can only ever actually cast 1 Spell but may attempt to cast many; whichever succeeds wins. This leads to natural variation in what can occur and when and entirely prevents overlaps.
Within this comes a variety of baked in behaviours controlled by flags that we can set on each Spell within a creatures combat behaviour. For example:
- Interrupt previous casts.
- Ignore Totems.
- Only cast on Players.
- Cast on target who is casting (Interrupts).
- Don't cast on CC'd targets.
- Only cast on Mana / Rage / Energy users for Mana Burns etc.
- Only cast in Melee range.
- Only cast when out of Melee range.
- Marking a Spell as a "main" ranged Spell eg Shoot. Creature will remain stood without moving until this Spell cast fails.
- Force facing a target.
- Per Spell control if it can be interrupted.
- Much more.
As part of this, we imported thousands of creature spells from vMangos and also converted thousands more within TrinityCore to use this system for almost all in-combat behaviours across the game world.
Based on the research done by vMangos, Felmyst, and analysis of Blizzlike behaviour and tools, we have been able to conclude that this is functionally as close to how it runs on Blizzard servers as possible and introduces a greater level of dynamicism to the Creature decision-making process.
Mind Control
One secondary benefit of this system is that we now have a definition for what every Blizzard Creature and every Custom Creature casts in combat, as well as the upper bounds of their cooldown. With this, we've been able to fix one of the most iconic abilities in World of Warcraft: Mind Control.
As players of the Priest class know, this allows you to take control of a Humanoid NPC within the world and cast the abilities that they have. By hooking into this new spell system, we essentially have all the data we need to fix this problem across the board. This should fix thousands of individual issues related to Mind Control, such as being able to spam powerful abilities and solo clear certain encounters. This logically extends to custom creatures too.
If needed, we can exclude certain abilities from Mind Control data, as well as include abilities that aren't cast in combat and only exist in Mind Control, such as Master Elemental Shaper Krixix within Blackwing Lair.
Next Steps
Once we had this Blizzlike foundation in place, we realized both the power and potential within, and knew that with only a few simple tweaks, we would be able to expand this to allow for the quick implementation of complex boss mechanics, including within raid encounters, much like Blizzard did with Onyxia as shown in the above internal tools image.
The key feature we needed was a way to both define the phases of a boss encounter, how they are transitioned, and limit the casting of spells to certain phases. We have since converted all custom boss encounters within custom dungeons (The Deadmines, Wailing Caverns, Glittermurk Mines, and Tol Barad) to utilize it to great effect.
Conclusion
This month has been a primarily systems and data-driven affair, without huge amounts of visual content to showcase to our community, but we're overall extremely happy with progress made and the drastic strides on game 'feel' that we have accomplished.
We look forward to hearing all of your thoughts and stay tuned for our next update.