top of page

Scripting

 

 

 

 

 

Scripting (also referred to as automating) your combat strategies allows you to put your combat knowledge into practice without limitations such as ability to read everything fast enough, ability to make complex mathematical calculations on the fly, or not being able to type things fast enough.


One of the key requirements of Achaean combat is being able to reference (in code) as much information as possible.  By combining the mathematical powerhouse that is Godzilla with a few basic tools (like limb trackers), along with your active control, you will have every bit of information you could possibly need to turn your combat dreams into a reality.

 

 

One thing that Godzilla, and by extension, automation, will not do for you: It will not make you an amazing fighter overnight.  Godzilla provides you with the information you need to do amazing things, in code, but in the end, it falls on the player to use these tools to succeed.  It also comes with some relatively "decent" examples of basic offense strategies for your class.  It should be noted early on that these examples are not there for you to simply install, then use for the rest of your days!  (Although, you're certainly welcome to.)   They are there to get you started, by showing you some very basic concepts that can easily be dramatically expanded by putting what you know about combat into script.  The goal of this tutorial is to help you do that.

Before you get started, you should have already read the Introduction, Manual, and API sections of this page.  To effectively use Godzilla, you will need to understand how it works, and what exactly it enables you to do.

 

 



The Basics - Affliction selection

 

If you've read the manual, and you understand the basics of affliction tracking and how probabilities work, then you're ready to start tapping into that wealth of information.  The best place to start is with one of the most basic - yet most useful - type of offensive scripting - Affliction selection.

One of the fundament rules of afflicting in Achaean combat is that it's typically best to avoid over-afflicting (afflicting an opponent with something they already have).  Many other basic concepts of what to afflict may also apply, based on your class.  Since knights are the most basic class, we'll use DSL envenoming as a basic example in this tutorial.

Lets jump right in to some examples of a logical sequence for what venoms to afflict with in combat.  For now, we're just going to start with a single combat strategy.  Later, we can branch out into multiple strategy options.

Step 1:  Define a goal.  A nice easy one we'll use for now is: Permanently stick sensitivity.

Step 2:  Define your strategy for achieving your goal, using what you know about combat theory.  At this point, we're not talking about code, we're talking about actual combat theory.  Do not limit your combat strategy based on what you know how to code.  Simply learn as much as possible about the combat theory involved in achieving what you want to achieve with each strategy.

If your goal is to stick sensitivity, there are several methods of achieving this.  All of these strategies will involve stripping deafness and ideally preventing the use of hawthorn to re-def it (or punishing your opponent for doing so mid-combat).

The most common method of sticking sensitivity is a kelp stack.   This method is actually not very reliable, as several of the kelp afflictions you'll require are higher priority than what you're actually trying to stick.  For example, if you use asthma, and even clumsiness, your opponent might not even be trying to cure sensitivity, but will do so on accident while trying to cure these typically high-priority afflictions.  The up-side to this method is that you can stop afflicting for a considerable amount of time (enough time to Impale and DSB, ideally) with a decent chance of sensitivity still being afflicted for a high-damage finisher.  While understanding how curing priorities work is important here, the real challenge of this strategy is determiming when to re-afflict with kelp afflictions (as their probabilities will generally be very uncertain due to large amounts of kelp being eaten, especially if you use asthma in your strategy).

The most effective way to guarantee that your opponent always has sensitivity is to afflict it, and constantly maintain higher priority afflictions on your opponent, that are not kelp-cured.  This will require understanding the basic concept of curing priorities.  For instance, the following afflictions are higher priority than sensitivity in SVO's default settings, and are available to all Knight classes:  asthma, slickness, paralysis, stupidity, recklessness, peace, clumsiness, and darkshade.  


Lets focus on the second method for now, as it is relatively simple.  As we already mentioned, if we want to maintain 100% certainty that our opponent has sensitivity, then we want to avoid forcing them to eat asthma to cure other afflictions.  Thus, we are free to use Weariness (lower priority than sensitivity).  For simplicity's sake, lets just avoid all other kelp afflictions.  That way, if a kelp is ever eaten, we know that sensitivity was cured.  

The use of focusable afflictions is normally avoided by classes that cannot afflict with impatience (notably, knights).  Indeed it is generally better, when stacking afflictions, to use herb-only cures.  However, the only herb-only cures above sensitivity in standard curing priority that aren't kelp afflilctions are paralysis and darkshade.  In fact, many players move sensitivity up above darkshade (while others react dramatically to serpents by placing darkshade far too high).  It is imperative that you learn to recognize this in combat if you can't already!

 

In this case, the strategy we'll use is stacking a combination of higher-priority (than sensitivity) afflictions on the target, using Godzilla to ensure that as little (if any) over-affliction occurrs as possible.  We can also use Godzilla to handle tracking of deafness, for highly efficient use of prefarar venom.

 

So lets figure out how to code this.  First of all, lets generate ourselves a list of afflictions we want to use, in order of how we want them to be used.  For example:

stick_sensitivity =
{

     "paralysis",

     "sensitivity",

     "stupidity",

     "recklessness",

     "darkshade"
}

 

It's pretty easy to make a basic function in lua script to go down that list, in order, and only use the associated venom if your target doesn't have each affliction.

However, if your opponent (in an extreme example) only has a 10% chance of having sensitivity, or paralysis, would you really want to skip over the affliction?  Perhaps you'd like to re-afflict with paralysis any time you're not 100% sure they have it, but you only want to re-afflict sensitivity if there's a pretty good chance that they cured it (lets say, 25%).  As for the other afflictions, lets say (for example's sake) that you only want to use a venom if you're 67% sure they have cured the affliction.   Since you're only using those afflictions to force your opponent to not cure sensitivity, you don't actually need to be very sure they have each affliction. It's more important to minimize over-affliction of these, and go for quantity, instead of quality.


So, lets add some numbers to our table:

 

 

stick_sensitivity =
{

     "paralysis",     100,

     "sensitivity",   75,

     "stupidity",     34,

     "recklessness",  34,

     "darkshade",     34,
}

 

Firstly, note that this is a normal table (aka a list), not a key-val pair table.  This is intentional, and we'll talk about why, in a moment.

 

Now, we can make a simple script that goes through this list, and selects two afflictions (for DSL), but will only select each venom if the probability that your opponent has each affliction is less than the number you specify.  So for example, as was our goal, paralysis will be used any time that you're not 100% confident that they have it, even if there's only a 1% chance that it has been cured.  (This is probably not the best strategy - it's just an example!)

As for why we're not using a table, consider this:  What if early on in combat you aim to be efficient, and only afflict with darkshade if you're fairly confident that they don't already have it (lets go with < 25% probability).  However, later in your strategy (further down the list) you have already ensured your opponent has everything you want them to have, and now you want to use darkshade a bit more liberally.  Now, you want to be 100% sure they have it, and even 90% doesn't sit well with you.  You could modify the list like this:

 

stick_sensitivity =
{

     "paralysis",     100,

     "sensitivity",   75,

     "stupidity",     34,

     "recklessness",  34,

     "darkshade",     34,

     ..

     ..

     .. // other stuff

     .. 

     ..

     "darkshade",     100,


}

 

 

In lua, you can't have multiple keys with the same name.  This is I use a normal table.  Other solutions are possible, but this one works great!Ok, lets take this one step further.  Instead of having a completely pre-defined affliction list, let's give your strategy some brains.Instead of making a statically defined list, we'll make a really simple function that returns a list.

 

stick_sensitivity = function ()

    table =
    {

        "paralysis",     100,

        "sensitivity",   75,

        "stupidity",     34,

        "recklessness",  34,

        "darkshade",     34,

    }

    return table

 

 

end

 

The above function would return the exact same string as the example we created above. However, since our table is now in a function (which is called every time you DSL), you can now add in math or logic as you please.  For example, let's say you don't want to use the "nausea" affliction against monks or knights (who have the constitution defense).  Additionally, instead of 34%, you want to use 100% for recklessness, but only if you're >= 66% sure they have stupidity.  Your function would look like this:

 

stick_sensitivity = function ( class )

 

    local nausea = 34

 

    if table.contains({"monk","runewarden","infernal","paladin"},class) then

        nausea = 0

    end

 

    local recklessness = 34

    

    if gz.prob("stupidity") >= 66 then

        recklessness = 100

    end

 

    table =
    {

        "paralysis",     100,

        "sensitivity",   75,

        "stupidity",     34,

        "recklessness",  recklessness,

        "darkshade",     34,

        "nausea",        nausea,

    }

    return table

 

end

 

 

So, now we have a "smart" strategy.  As you may have noticed, we used class information (passed to the function) and your opponent's affliction status, using gz.prob ( ), to alter how you make your venom selection.

The next step is making a simple function to call when you want to actually DSL someone using the strategy you've built.  Let's call it auto_dsl ( ).

Because we're using a normal table, intead of a key-value table, we'll be using the modulus function to basically jump through the function one affliction at a time.

 

auto_dsl = function ( )

 

    local strategy = stick_sensitivity( ndb.getclass(target) )

 

    local first = false

    local second = false

 

    for x, val in ipairs(strategy) do

        if x%2 == 1 then

            if gz.probability(val) < strategy[x+1] then

                if first == false then

                    first = val

                    if first == "prefarar" and gz.def_status("deaf") then

                        second = "prefarar"

                    end

                elseif second == false and first ~= val then

                    second = val

                end

            end

        else x=x+1

        end

    end

 

    chiv.dsl(first,second)

end

 

 

Notice that at risk of overcomplicating things, I put a check involving prefarar into the function.  While in fact, many venoms do not function as simple venom-affliction pairs (prefarar strips deafness first, for example).   I've only included prefarar, just to show you how to handle such things.

If this kind of script confuses you, don't panic!  First of all, it's actually very simple, it's just a bit verbose.  Step through it one line at a time and see if you can understand exactly what's going on.  Note that if your class uses something like DSL or doublestab, then your offense example included with Godzilla will have something similar already built into it.  You can start with that, and add/change things as you embelish your combat strategy.


Notice that in even the most basic function, you're referencing all sorts of information to make decisions.  Here's a list of some things you can reference to make your combat scripting more powerful:

Within Godzilla (see API section for more info)

gz.prob(aff)           returns the probability (0-100) that your target has a specified affliction
gz.might_have(aff)     returns a boolean, true if your opponent may have an affliction (probability >= 0 )

gz.def_status(def)     returns true, false, or "unknown" based on your opponents' defense statuses.

gz.is_prepped(def)     returns true if your opponent's specified limb is prepped to break. (requires SVO)

 

External references

ndb.getclass(target)   returns true, false, or "unknown" based on your opponents' defense statuses.

svo.ml_list[limb] | svo.kl_list[limb]  directly access limb counts from SVO's class limb counters

 

 

 


More to come soon!
 

 

 

 

 

bottom of page