Tutorial – Constants

This tutorial covers one of the most basic concepts of programming/scripting: User defined constants. It is meant for beginning coders and OpenBOR script writers. Upon completion, you should understand all of the following:

  • The definition of “Constant” in computer science (programming) as opposed to other uses of the term (such as mathematics).
  • How constants work in relation to other types of identifiers.
  • Where and how to apply constants.
  • Use of constants within the OpenBOR scripting engine.

Constants vs. Literals & Variables

To fully comprehend why constants are useful it is imperative to understand what a constant really is, especially compared to variables and literals. Literals are of particular note because it is very easy to confuse literals with constants. In the field of computer science, variables, constants and literals are usually defined as follows (Rao, 2017):

  • Variable: A variable is a storage location and an associated identifier which contains some known or unknown quantity or information, a value.
  • Constant: A constant is an identifier with an associated value that the program can not normally modify.
  • Literal: A literal is a notation for representing a fixed value.

Note the unfortunate caveat: “usually”. This is because some languages (C in particular) refer to both literals and constants as “constants” (Constants, 2020). They are then differentiated as “literal constants” and “symbolic constants” respectively. In programing circles, numeric literals are also called “magic numbers” (Definition of constants and magic numbers 2001). To avoid confusion between them we will henceforth only use the references “literal” and “constant”.

In practical terms, you may think of variables as named values that you can modify, constants as named values that you can’t modify and literals as values that mean exactly what they say. The question is how do these definitions and meanings apply in real world programming. To find out let’s start with variables and literals using this example multiplier:

i*2 = y

Applying our definitions above, there are two variables (i, y) and a single literal (2) in play:

  • i represents some number that can be whatever we want.
  • y is the product result.
  • 2 is just two – it’s a literal value.

Now observe as we translate our equation into some code and see it in action:

int i = 0;
int y = 1;

for (i = 0; i < 10; i++)
{   
    y = y * 2;
    print("Result %i: %i\n", i+1, y);
}

This will get us a simple geometric progression. First, we assign variable i a value of zero. Then we increment i by one in a loop until it is no longer less than ten. At each pass we assign y the product of y * 2. Then we print the cursor row and current value of y, giving us the following output:

Result 1: 2
Result 2: 4
Result 3: 8
Result 4: 16
Result 5: 32
Result 6: 64
Result 7: 128
Result 8: 256
Result 9: 512
Result 10: 1024

Observe how our literal value 2 worked in relation to the variables surrounding it. Note the number 10 is also a literal, but for simplicity let’s just worry about 2. We could run this loop to infinity and it will always multiply y * 2 and assign the result to y. The variables i and y are continuously modified while 2 never changes. Easy enough yes? Remember:

Literals are static values written directly into source code; they “literally” mean what they say. Variables are IDs which are assigned values that can be (and usually are) modified while the program executes.

Now what would happen if we need to calculate our equation again, only dividing by 2 rather than multiplying? As an example, we’ll make a copy of our loop with a minor modification and run both in sequence.

int i = 0;
int y = 1;

print("\n Multiply %i:\n\n", 2);

for (i = 0; i < 10; i++)
{   
    y = y * 2;
    print("Result %i: %i\n", i+1, y);
}

print("\n\n Divide %i:\n\n", 2);

for (i = 0; i < 10; i++)
{   
    y = y / 2;
    print("Result %i: %i\n", i+1, y);
}

We’ll get the following output.

Multiply 2:

Result 1: 2
Result 2: 4
Result 3: 8
Result 4: 16
Result 5: 32
Result 6: 64
Result 7: 128
Result 8: 256
Result 9: 512
Result 10: 1024

Divide: 2

Result 1: 512
Result 2: 256
Result 3: 128
Result 4: 64
Result 5: 32
Result 6: 16
Result 7: 8
Result 8: 4
Result 9: 2
Result 10: 1

As you can see in the second example, we start with the geometric progression pattern from earlier and then reverse it. For purposes of our example, the output is not that important. What matters here is how we use the literal 2 four times in succession – once for each label and each operation. No problem thus far. But suppose later we need to substitute 2 with 10? Just edit the code and be done right? With examples like this, of course! Unfortunately real world coding is not so simple. Consider a real script or program. Even a something simple like some of the scripts powering this website may comprise several pages of code. For perspective, the OpenBOR engine contains ~600K lines of source code. Some of the largest applications can number in the millions. Now imagine trying to locate and edit every instance of 2. Or worse, trying to locate specific instances of 2, and leaving the rest alone. Even with advanced regex expressions, assuming those are available at all, copy/paste operations can be effectively impossible. Hand editing is time prohibitive and error prone. This is where constants are so valuable. Let’s look at our example once again, with a little something extra added.

#define SOMENUM 2

int i = 0;
int y = 1;

print("\n Multiply %i:\n\n", SOMENUM);

for (i = 0; i < 10; i++)
{   
    y = y * SOMENUM;
    print("Result %i: %i\n", i+1, y);
}

print("\n\n Divide %i:\n\n", SOMENUM);

for (i = 0; i < 10; i++)
{   
    y = y / SOMENUM;
    print("Result %i: %i\n", i+1, y);
}

As you’ve no doubt guessed, this and the previous example produce identical results. The difference is we no longer rely on a literal 2. Instead, this line creates a constant identified as SOMENUM and assigns it the value of 2:

#define SOMENUM 2

Just as i represents a loop counter value, SOMENUM represents the number 2. But unlike i and Y, SOMENUM can never change while the program is running. It maintains a constant value, hence the name. Effectively we have given a potentially VERY common value (2) its own unique identification. Attaching an identification to values that never change is an extra step that may seem silly at first, but in the long run actually saves you time. It is almost universally considered best practice (Recommended C Style and Coding Standards 2000).

  • There is no need to modify the code in multiple places. If we want to substitute our constant value for something else, we merely change the #define. Depending on scope of the program, this can range from being a simple time saver to enabling adjustments that are otherwise untenable or virtually impossible.
  • You may give constants nearly any imaginable label. That in turn enables creation of organized naming conventions for cleaner, more human readable code. This means superior design malleability, greater run time stability, and easier debugging when anomalies do occur.
  • It is possible to write programs with configuration blocks for simplistic modification of basic behavior and quick porting to other hardware platforms.
  • Separation of code and content! Why write a formula that only adds 2+2 when X+Y can perform the same task with infinite re-usability?

How To Use Constants In Your Code

Using constants is amazingly simple, but like any programming technique also sometimes mercurial. Every coding environment will have its own set of operators, methods, capabilities, and quirks. I will be focusing mainly on the the C based scripting engine of OpenBOR. A cursory Google search should provide all the instruction you need for other tools of choice.

OpenBOR

OpenBOR’s scripting engine is a C derivative and supports the define directive for constants. A define comprises three parts:

  1. Definition: Always “#define”.
  2. Identification: This is the name of your constant.
  3. Token: The value. This is what the computer will interpret whenever the constant is encountered in code.
#define SOME_IDENTIFICATION somevalue

Don’t worry about memory or CPU resources. The define directive is prepossessed, meaning the application handles it on start up. In other words, constants have no memory or run-time CPU cost.

General Tips

Naming Conventions

Decide on a naming convention before you start writing code. You will want names that are unique enough to avoid conflict while remaining reasonably succinct. Common practice is to use all caps for the identifier, with an underscore separator between each segment. The segments themselves should maintain Big Endian order.

#define BOVINAE_BISON			"Bison"	// Best in the west!
#define BOVINAE_BOS				"Cow"	// It's what's for dinner.
#define SIZE_LARGE				16		// Full meal.
#define SIZE_MEDIUM				12		// Light snack.
#define SIZE_SMALL				10		// For the kiddies.
#define TEMP_DONE_MAX			100		// Mmmmummm, that's the stuff!
#define TEMP_DONE_MIN			71		// Nice and brown.
#define TEMP_MEDIUM_MAX			65		// Little cold, but not bad.
#define TEMP_MEDIUM_MIN			60		// In a hurry?
#define TEMP_MEDIUM_WELL_MAX	69		// Not too shabby.
#define TEMP_MEDIUM_WELL_MIN	65		// Add some Worcestershire and we'll talk.
#define TEMP_RARE_MAX			55		// Somebody call a blood bank.
#define TEMP_RARE_MIN			52		// Moo!

Note the larger group of Subfamily appears first, followed by Genus. We follow a similar convention for cut size and cooking temperature. Who’s in the mood for a SIZE_LARGE BOVINAE_BOS TEMP_WELL_MAX?

Text File Use

In OpenBOR, any constants available in a model’s animation script are also available in the model text. This means constants are usable inside of @script tags or as function arguments in @cmd tags.

Reading this function call is very difficult unless the creator has a perfect memory, and it’s impossible for anyone else….

@cmd set_bind_state 7 1

…but with constants, the creator can instantly identify what the function call should do, and if need be can easily find related calls with a text search. Other readers may not understand right away, but they can probably get a rough idea and debug from context:

@cmd set_bind_state BIND_STATE_FACE_DOWN DIRECTION_RIGHT

When/Where Should Constants Be Used?

One of the more common questions involving constants is “When should I use them?” The answer is “whenever possible.” As a more usable interpretation of “whenever possible”, consider the following:

  • Is the value static?
  • Will you use the value more than once?
  • Does the value lack infinite range and variation?

If the value fits these criteria, then replace it with a constant. Remember, defined constants in OpenBOR are “free”, they don’t consume any more resources than the literal values they replace.

Final Words

I hope this helps you to understand how simple, elegant and useful constants can be, and I would encourage you to make full use of them in your own projects. Lastly, please feel free to leave comments below with any questions or opinions you may have, and I will see to them in short order. If you have any questions about the OpenBOR engine, stop by at ChronoCrash and we’ll be glad to help.

Thanks for reading!
DC

References

C Constants. (2020). https://www.w3schools.in/c-tutorial/constants/.

Def. (2001). Definition of constants and magic numbers. https://www.inf.unibz.it/~calvanese/teaching/05-06-ip/lecture-notes/uni04/node17.html.

Rao, S. (2017, January 27). Informit. InformIT. https://www.informit.com/articles/article.aspx?p=2755729.

Def. (2001). Definition of constants and magic numbers. https://www.inf.unibz.it/~calvanese/teaching/05-06-ip/lecture-notes/uni04/node17.html.


Originally published 2013-02-04.

Code Snip – Collision Checking

Notes from 2016-11-26 – Revamping OpenBOR collision detection.

With the possibility of several dozen or more entities on screen, collision detection must be precise with minimal resource intensity.

With the possibility of several dozen or more entities on screen, collision detection must be precise with minimal resource intensity.

Currently coordinates (s_hitbox) exist as static sub-structures in s_collision_attack and s_collision_body. See below…

typedef struct
{
	int x;
	int y;
	int width;
	int height;
	int z1;
	int z2;
} s_hitbox;

// s_collision_attack
typedef struct
{
    int                 attack_drop;        // now be a knock-down factor, how many this attack will knock victim down
    int                 attack_force;
    int                 attack_type;        // Reaction animation, death, etc.
    int                 blast;              // Attack box active on hit opponent's fall animation.
    int                 blockflash;         // Custom bflash for each animation, model id
    int                 blocksound;         // Custom sound for when an attack is blocked
    s_hitbox            coords;
    int                 counterattack;      // Treat other attack boxes as body box.
    ...

This was done for simplicity, and with current logic wastes no memory as coordinates are always required for a collision box.

However, the addition of multiple collision box support has exposed the need to break collision detection down into smaller functions. This in turn requires a lot of passing around the entire s_hitbox structure. Given the rate this functionality is used (multiple collision evaluations on every entity on every animation frame @200 frames per second), efficiency is absolutely imperative. Replacing the static coords declaration with a pointer and using dynamic allocation will add some code complexity initially, but in the long term should simplify breaking down collision logic and save substantial resources.

The following are in progress logic functions, they will need reworking to accommodate new pointer.

// Caskey, Damon V.
// 2016-11-25
//
// Get 2D size and position of collision box.
s_coords_box_2D collision_final_coords_2D(entity *entity, s_hitbox coords)
{
    s_hitbox        temp;
    s_coords_box_2D result;

    temp.z1 = 0;

    // If Z coords are reversed, let's correct them.
    // Otherwise we use
    if(coords.z2 &gt; coords.z1)
    {
        temp.z1 = coords.z1 + (coords.z2 - coords.z1) / 2;
    }

    // Get entity positions with Z offset
    // included, and cast to integer.
    temp.x    = (int)(entity-&gt;position.x);
    temp.y    = (int)(temp.z1 - entity-&gt;position.y);

    // Use temporary positions to get final dimensions
    // for collision boxes.
    if(entity-&gt;direction == DIRECTION_LEFT)
    {
        result.position.x   = temp.x - coords.width;
        result.size.x       = temp.x - coords.x;
    }
    else
    {
        result.position.x   = temp.x + coords.x;
        result.size.x       = temp.x + coords.width;
    }
    result.position.y   = temp.y + coords.y;
    result.size.y       = temp.y + coords_owner.height;

    return result;
}

bool collision_check_contact_2D(s_coords_box_2D owner, s_coords_box_2D target)
{
    // Compare the calculated boxes. If any one check
    // fails, then the boxes are not in contact.
    if(owner.position.x &gt; target.size.x)
    {
        return FALSE;
    }
    if(target.position.x &gt; target.size.x)
    {
        return FALSE;
    }
    if(owner.position.y &gt; target.size.y)
    {
        return FALSE;
    }
    if(target.position.y &gt; target.size.y)
    {
        return FALSE;
    }
}

bool collision_check_contact_Z(entity *owner, s_hitbox coords_owner, s_hitbox coords_target)
{
    int Z_distance = 0;
    int z1 = 0;
    int z2 = 0;

    if(coords_owner.z2 &gt; coords_owner.z1)
    {
        z1 += coords_owner.z1 + (coords_owner.z2 - coords_owner.z1) / 2;
        zdist = (coords_owner.z2 - coords_owner.z1) / 2;
    }
    else if(coords_owner.z1)
    {
        zdist += coords_owner.z1;
    }
    else
    {
        zdist += attacker-&gt;modeldata.grabdistance / 3 + 1;    //temporay fix for integer to float conversion
    }

    if(coords_target.z2 &gt; coords_target.z1)
    {
        z2 += coords_target.z1 + (coords_target.z2 - coords_target.z1) / 2;
        zdist += (coords_target.z2 - coords_target.z1) / 2;
    }
    else if(coords_target.z1)
    {
        zdist += coords_target.z1;
    }

    zdist++; // pass &gt;= &lt;= check if(diff(z1, z2) &gt; zdist)
    {
        return FALSE;
    }
    
    return TRUE; 
}

// Caskey, Damon V.
// 2016-11-25
//
// Compare collision boxes and return
// TRUE if they are in contact.
bool checkhit_collision(entity *owner, entity *target, s_hitbox coords_owner, s_hitbox coords_target)
{
    s_coords_box_2D owner_final;
    s_coords_box_2D target_final;

    bool result;
    
    // First check Z contact.
    result = collision_check_contact_Z(owner, coords_owner, coords_target);    

    // If result is TRUE, then run
    // 2D plane checks.
    if(result)
    {
        // Get final collision box 2D plane sizes.
        owner_final     = collision_final_coords_2D(owner, coords_owner);
        target_final    = collision_final_coords_2D(target, coords_target);
        
        // Compare the 2D boxes and get result.
        result = collision_check_contact_2D(owner_final, target_final);
    }
    
    // return final result.
    return result;
}

// Find center of attack area
s_axis_f_2d collision_center()
{

    leftleast = attack_pos_x;

    if(leftleast &lt; detect_pos_x) { leftleast = detect_pos_x; } rightleast = attack_size_x; if(rightleast &gt; detect_size_x)
    {
        rightleast = detect_size_x;
    }

    medx = (float)(leftleast + rightleast) / 2;
}

Double Dragon Reloaded Update Progress

….

 

Controls

  • Back Kick button is removed. New button Defend replaces it.
  • Punch and Kick are renamed “Attack A” and “Attack B” as their functions differ depending on which Lee brother is used.

New Moves

  • Block.
  • Run.
  • Somersault Throw.
  • Somersault Kick.
  • Backdrop Finisher.
  • Hyper Uppercut.
  • Hyper Knee.
  • Dragon’s Tail Kick (Double team jump kick).
  • Double Dragon Hurricane Kick (Double team Hurricane Kick).
  • Rear Backhand Strike (w/sticks).
  • TKD Kick.
  • TKD Finisher.
  • Knee Thrust.
  • Middle kick (Grab finisher).
  • Roundhouse Kick finisher.

 

Modified Moves

  • Hurricane kick now requires timing with apex of jump as in the original arcade DDII, but is also more powerful.
  • Stick combo is now a faster four step combo with all unique animations, and hit per button press. Take away Chin’s Kali sticks and show him how it’s done!
  • Second strike with chains and whips now has a unique animation.
  • Off wall kick has new animation.

Stages

  • All
    • Updated music to Double Dragon Neon tracks with offsets & loops.
  • Stage 1 (City)
    • Separated background.
      • Path
      • Bush
      • City
      • Sky
    • Upgrade to .png assets. ~73kb vs. ~279kb
  • State 3A (Rooftops)
    • Bridge is now a metallic grate – scenery visible through the bottom
    • Separated background.
      • Path
      • Forrest
      • City
      • Mountains
      • Clouds
      • Sky
    • Upgrade to .png assets. ~136kb vs. ~718kb
  • Stage 3 (Forrest)
    • Separated background.
      • Path
      • Trees
      • Field
      • Mountains
      • Clouds (Clouds consist of four independent layers auto scrolling at different rates to simulate real flowing cloud cover)
      • Sky
    • Upgrade to .png assets. ~166kb vs ~615kb
  • Stage 4 (Invade the enemy base!)
    • Separated background.
      • Path
      • Tree (black)
      • Trees (blue)
      • Sky
    • Upgrade to .png assets. ~322kb vs. ~1478kb

Technical

  • Where possible, rework some scripts with #import rather than #include. This is a huge memory saver.
  • Refine billkey.c with marcos and bitwise operators.
  • Jump animations simplified.
    • Jump animations formerly included multiple identical frames to control the timing for cancels. These have been replaced by velocity evaluation in keyscripts. The extra frames are removed.
  • Eliminate unneeded resources
    • Billy’s weapon sprites that were identical to unarmed version. References in weapon texts switched to the unarmed sprite. Note that small item weapon sprites were unique, but unnecessary and were also eliminated. Small items are normally in the far hand while walking and would be completely hidden from view – the armed versions magically switch item to near hand. Makes more sense to simply use the unarmed sprites.
      • Bomb
        • aaaa5
        • aaaa55
        • aaaa6
        • bk0
        • bk4
        • bkick1
        • climb2
        • J00
        • J0
        • Jk2
        • kna4
        • kna5
        • wu1
        • wu2
        • wu3
        • wu4
      • Chain
        • bk0
        • bkick1
        • climb2
        • climb3
        • climb4
        • climb5
        • jk2
        • pain1
        • wu1
        • wu1
        • wu3
        • wu4
      • Dynamite
        • bk0
        • bk4
        • bkick1
        • kna4
        • kna5
        • pain1
        • Knife
        • bkick1
        • bk4
        • kna4
        • kna5
        • wu1
        • wu2
        • wu3
        • wu4
      • knife
        • wu1
        • wu2
        • wu3
        • wu4
      • Whip
        • bkick1
        • wu1
        • wu2
        • wu3
        • wu4
      • All throwing sprites for heavy objects.

 

 

Multi-Layer Stage Example

Multiple stage layer example with OpenBOR. See gallery below for stage broken into its individual resources.

Layer example

This stage is comprised of eight layers. See text for description of each.

From front to back:

  1. Posts are the default OpenBOR front panel.
  2. Palm fronds are a panel type entity to allow wafting animation.
    1. Layer: 100
    2. Speed: -0.25
  3. Play field is the default OpenBOR panel.
  4. Boat is an animated singular obstacle type entity. It is fully animated and has collision enabled. It can thus be hit and ultimately sunk, but only by throwing enemy characters out of the play field (more on that later).
    1. Layer: -8
    2. Scroll: 0.17
  5. Bay and nearest area of the city are made from a series of panel type entities. This is to allow animation of the various city elements and gleaming water.
    1. Layer: -10
    2. Speed: 0.2
  6. A second series of panel type entities creates another layer of water and city area for smoother scrolling.
    1. Layer: -11
    2. Speed: 0.3
  7. A third and final layer of panel type entities comprises the furthest visible water.
    1. Layer: -12
    2. Speed: 0.4
  8. Background is OpenBOR’s default background, set to autoscroll mode so the clouds are always rolling by.
    1. Bgspeed: 1 0

With eight independently scrolling layers, the visual effect is that of near 3D scrolling when characters traverse the stage. A final touch is an invisible entity resetting the stage palette to the next of ten increasingly darker and redder hues every thirty seconds of real time. This creates a sunset effect during game play.

DC’s Object Core Library – Vol I: Damage

PHP

DC’s Object Core Library is an effort to bring some of the benefits of object oriented programing to the OpenBOR script engine. Although it is technically impossible to define a true object through OpenBOR script, careful structuring of functions into methods properties allows us to closely simulate OOP behavior.

  • Encapsulation
  • Re-usability
  • Forward compatibility
  • Simplicity
  • Expandability

The DC Damage Library coves a fundamental building block; damaging entities. After all, there is little use in something like a bind/grappling system without the means to apply damage. It is very important to not only damage entities using the engine’s built in damage system, but to do so in a controlled way. You will find this system allows you near infinite combinations of settings to cover almost any damage needs.

License

This library is released under license seen here.

Installation

  1. Download and unzip the library.
  2. Place dc_damage folder into your scripts folder.
    • You can always put it elsewhere, but if you do, you’ll need to modify all the #include and #imports accordingly.
  3. Add the line #include “data/scripts/dc_damage/main.c” to any scripts you’d like to use damage objects in, and you’re ready to go.

 

Use

In its most basic form, there are exactly three steps once you’ve installed the DC Damage Object.

  1. Initialize an object. To do that, call dc_damage_create_object({index}). The {index} is a required integer value of your choosing. You can have as many damage objects as you like, {index} identifies which is which. Once initialized an object can used by any script that you installed the library to.
  2. Now you need to define a target to damage. That’s easy too; call dc_damage_set_target({index}, {entity}) and make whatever entity you want to damage.
  3. Now all you need to do is call damage_execute({index}) and your target gets nailed!
frame chars/dude/sprite1.png
    @cmd dc_damage_create_object 0 #Let's create an object with index of 0.
    @cmd dc_damage_create_object 0 findtarget(getlocalvar("self)) #Set the target to be the nearest enemy.
frame chars/dude/sprite2.png
frame chars/dude/sprite3.png
frame chars/dude/sprite20.png
     @cmd dc_damage_execute 0 #Apply damage the target of damage object 0.
frame chars/dude/sprite22.png

Now here’s where it gets interesting. If you do nothing else but the three steps above, you get a simple knockdown with 0 damage. Not all that exciting. But that’s because you applied damage without setting any properties other than the target. So now you’ll want to work with the other properties to crate different effects. The amount of force, knockdown, how far, which direction, and so on are all adjustable on the fly. Just call the relevant mutator function (see below for list) with the index and you desired value. Only worry about the properties you need to – the rest have defaults (you can change these defaults if you like, see Advanced Use). There’s even a set of constants provided to help you along.

Damage a target, change some settings, damage it again. Multiple objects can be used all it once, it really doesn’t matter.

 

Action Methods

These methods are used to execute basic actions.

  • void damage_create_object(int index): Create a damage object identified by and populate with default values. Object is then ready to use, but you will need to set a target before applying damage.
  • void damage_destroy_object(int index): Destroy the object and free up resources.
  • void damage_execute(int index): Apply damage effects to target. You must first set a target. If there is no target set, an alert will be sent to the log and no further action will be taken.
  • void damage_ dump_object(int index): Send all object properties to the log.
  • void damage_import_object(int index, void object): Import all properties from a another damage object to . Will create new object or overwrite existing as needed.

 

Access Methods

Get object properties and status values. Unless noted otherwise, see the corresponding mutate method descriptions for property details.

  • void entity = damage_get_attacker(int index): Get the damaging entity.
  • int atk = damage_get_attacking(int index): Get attacking property.
  • int dir = damage_get_direction_adjustment(int index): Get direction adjustment property.
  • int dol = damage_get_dol_force(int index): Get damage on landing force property.
  • int drop = damage_get_drop(int index): Get drop power property.
  • int force = damage_get_force(int index): Get force property.
  • int force = damage_get_force_mitigated(int index): Get the damage target would receive after its defense and attacker’s offense are applied.
  • int force = damage_get_force_final(int index): Get force that target will receive after all damage mitigation and object settings are applied.
  • int min = damage_get_hp_cap_min(int index): Get target HP cap minimum property.
  • void obj = damage_get_object(int index): Get object array. Useful to copy object or save into global for game persistence.
  • int proj = damage_get_projectile(int index): Get projectile property.
  • int type = damage_get_type(int index): Get attack type property.
  • int flip = damage_get_velocity_flip_x(int index): Get X velocity flipping property.
  • float X = damage_get_velocity_x(int index): Get X drop velocity.
  • float Y = damage_get_velocity_y(int index): Get Y drop velocity.
  • float Z = damage_get_velocity_z(int index): Get Z drop velocity.

 

Mutate Methods

Establish and change object properties. Where applicable default values for the property are listed.

  • void damage_set_attacker(int index, void value = NULL()): Set entity that will cause damage and receive credit for doing so. If no attacker is set when damage is applied, the target itself will be considered the attacker.
  • void damage_set_attacking(int index, int value = DC_DAMAGE_FALSE): Toggle the target’s attacking flag when damage is applied. Combine with projectile to create a blast effect. Uses general Boolean constants:
    • DC_DAMAGE_TRUE: Target’s attacking flag will be turned on.
    • DC_DAMAGE_FALSE: Target’s attacking flag will be turned off.
  • void damage_set_direction_adjustment(int index, int value = DC_DAMAGE_DIR_ADJ_OPP): Determines how target’s direction will be adjusted when damage is applied. Use with following constants:
    • DC_DAMAGE_DIR_ADJ_LEFT: Target will always face left.
    • DC_DAMAGE_DIR_ADJ_OPP: Target will always face opposite direction of attacker.
    • DC_DAMAGE_DIR_ADJ_NONE: Target’s facing will not be adjusted.
    • DC_DAMAGE_DIR_ADJ_SAME: Target will always face same direction as attacker.
    • DC_DAMAGE_DIR_ADJ_SAME: Target will always face right.
  • void damage_set_dol_force(int index, int value = 0): Damage target will receive upon landing from fall. May be mitigated by target’s defenses or ability to land.
  • void damage_set_drop(int index, int value = 1): Drop (knockdown) power that will be applied to target with damage.
  • void damage_set_type(int index, int value = openborconstant(“ATK_NORMAL”)): Type of damage that will be applied to target.
  • void damage_set_force(int index, float value = 0): Quantity of damage that will be applied to target. Float types are only accepted for future expansion. The engine will truncate any decimal value when damage is applied.
  • void damage_set_hp_cap_min(int index, int value = 0): Target’s minimum allowed hitpoints after damage is applied. If after mitigated force will drop target’s HP to at or below , applied force will be adjusted as necessary to allow target’s HP to stay at minimum.
  • void damage_set_projectile(int index, int value = DC_DAMAGE_FALSE): Toogle target’s projectile flag when damage is applied.
    • DC_DAMAGE_TRUE: Target’s projectile flag is turned on.
    • DC_DAMAGE_FALSE: Target’s projectile flag is turned off
  • void damage_set_target(int index, void value = NULL()): Set target entity to damage. You must set a target before applying damage.
  • void damage_set_velocity_flip_x(int index, float value = DC_DAMAGE_VEL_FLIP_X_AWAY): Toggle mirroring of X drop velocity when damage is applied.
    • DC_DAMAGE_VEL_FLIP_X_AWAY: Always send target away from attacker.
    • DC_DAMAGE_VEL_FLIP_X_OPP_ATK: Always send target opposite direction of attacker’s facing.
    • DC_DAMAGE_VEL_FLIP_X_OPP_TARGET: Always send target opposite its own facing.
    • DC_DAMAGE_VEL_FLIP_X_NONE: Apply X drop velocity as is.
    • DC_DAMAGE_VEL_FLIP_X_SAME_ATK: Always send target same direction of attacker’s facing.
    • DC_DAMAGE_VEL_FLIP_X_SAME_TARGET: Always send target same direction as its own facing.
    • DC_DAMAGE_VEL_FLIP_X_TOWARD: Always send target toward attacker.
  • void damage_set_velocity_x(int index, float value = 1.2): X axis velocity applied to target on knockdown.
  • void damage_set_velocity_y(int index, float value = 3): Y axis velocity applied to target on knockdown.
  • void damage_set_velocity_z(int index, float value = 0): Z axis velocity applied to target on knockdown.

 

Advanced Use

  • Efficiency notes:
    • The installation #include is merely to start a file chain of #imports. The only items truly being #included are constants.
    • Objects are actually arrays stored as an index var. Therefore each defined object requires only one indexed var.
  • Because the library is written to behave like an object, it can be easily extended like an object class. Add your own goodies, just make sure to follow the interface rules for forward compatibility and try not to get carried away. Remember this is an “object” and should remained specialized. Things like flash spawns, sound effects and such are the purview of other object libraries (which will be coming soon).
  • Settings.h allows readjusting of object behavior as needed.
    • Array keys
    • Indexed var keys
    • Default properties

 

To Do

  • Clean up some of the calculation formulas. A few of them are pretty crude.
  • % based damage option.
  • Maximum option for HP cap.
  • Min/max damage caps.
  • No reflect option (currently not available in OpenBOR script).

Models – Tyris Flare

Tyris Flare model specific work log. Tyris is a primary player character and so requires a large variety of accessible technique.

Tyris will focus on magic and combining environmental use with advanced attack technique and magic. To place a somewhat more realistic and less cliched’ viewpoint on video game gender, she will not be “weak but quick”, and instead be inferior in all physical aspects (i.e. speed, constitution, strength and reach). But like any clever woman, Tyris has found ways to more than make up for these shortcomings. Advanced players will be able to segue graceful movement, sometimes using walls, allies and even opponents for footing to attack from all angles. This combined correctly with her superior magic abilities and reversal techniques can make Tyris virtually untouchable.

Completed:

2011_08_31

  • Combo finish kick replaced with spin kick (inspired by Genesis Golden Axe III).

2011_09_01

  • Add somersault to running jump animation (inspired by Genesis Golden Axe III).
  • Upgrade running attack (dust, flash, jump/landing frames).

2011_09_02

  • Dust effects.
  • Projectile hit adjustments.
  • Block flash.

2011_09_06

  • Attack1 (Whiffed)
    • Motion trail.
    • Hair animation.
    • More frames (Start up and recoil).
  • All main entity .gif sprites replaced with optimized .png format.

2011_09_07

  • Attack Chain
    • Applied transparent motion trails.
    • Most animations have additional frames and improved animation.
    • Flash/Sound effects.

2011_09_13

  • Attackbackward
    • Motion trail.
    • Sound effects.
    • Flash.
    • Hair .

2011_09_19

  • Jump landings now have smooth hair animation.
  • Jumpattack complete.
  • Run Jumpattack complete.
  • Jump now has looping hair flow.
  • Run attack now has looping hair flow.

2012_01_11

  • Rise attack replaced. Is now based on Millan Flare’s upward sword spin attack (Golden Axe The Duel).
  • Flip attack replaced. Is now an inverted forward somersault using fully customized sprites.
  • Forward Spin attack added (F+A against a wall during a run jump). Tyris rebounds off of wall (real walls only, not screen edge) while spinning weapon in a powerful flying attack. Based on Millan Flare’s horizontal sword spin attack.
  • New rise animation. Now performs a cartwheel to feet. Based on Millan Flare’s rise animation.
  • Fixed block animation (had accidentally included some jumping sprites).
  • Added voice effects (Random voice taunts when knocking enemy down, attack shouts, pain grunts, etc.)
  • Auto throw during short range combo is now a trip throw (based on rarely seen alternate throw in Genesis GA 3).

2012_02_07

  • Finished Boomerang sword throw. It’s a convoluted mess of script, but works. Seems for projectiles, the engine will only run didhit event once.
  • Fixed player control conflict with wall jump. Required reinstating script jump control in place of default engine control.

2012_08_27

  • Fix Chicken Leg attack types and knockdown values.
  • Set Chicken Leg jumpmove 0 1.
  • Chicken Leg sidestep bbox removed.
  • Fix Riseattack type.

 

To Do:

  • Boomerang sword throw for charge attack.
  • Pogo jump off of enemies.
  • Team moves.
  • Fix wall jump/player jump control conflict.
  • Double jump.
  • Counter throw on timed block.
  • Replace counter attack (Special when being attacked).
  • Side step.
  • Magic.
  • Normal grapple moves.
  • Backward dash.

Move-list Notes (finished only):

Combo (long range): Sword strike*2, Stab.

Combo (med-long): Sword strike*2, Spin kick.

Combo (med-short ): Sword strike*2, Pommel butt*2, Spin kick.

Combo (short): Sword strike*2, Trip throw (alternate throw from Genesis GA3)

Run + A: Flying kick.

A+J: Flipping kicks.

B, A: Back strike.

U, A (when knocked down, can use F or B to aim): Rising sword spin attack.

Hold A, release: Boomerang sword.

Jump, A: Downward strike.

Jump, D+A: Double kick (Genesis GA III J, D+A).

Running Jump A: Downward thrust.

Jump near wall, F+J: Wall jump

Running Jump near wall, F+A: Lunging sword spin attack.

Defense: Parry.

Running Jump

Running Jump

Stab (Combo Ender)

Stab (Combo Ender)

Spin Kick (Combo Ender)

Spin Kick (Combo Ender)

Models – Ax Battler

Ax Battler model specific work log. Ax is a primary player character and so requires a large variety of accessible technique.

Ax’s unique abilities will be somewhat pedestrian compared to the other characters. His statistics are good but not extraordinary and he lacks any sort of projectile or evasive capabilities. However, he is equipped with several effective sword techniques and is a proficient wrestler. Players can chain together throws one after another to cause extreme damage, and even grapple two enemies at once.

Completed:

2011_06_27

  • Block animation tweaked. Can no longer hit opponents.
  • Added A+J special, based on Uppercut/Jumpstrike from Golden Axe II (Genesis).

2011_06_28

  • Updated binds to knock down opponents at correct point (see bind0010).
  • Double Powerbomb attack added. It is a follow up to Powerbomb (D, F, A).
  • Giant swing can be performed as a follow up to Double Powerbomb or Powerbomb.
  • Proper turn animation added.

2011_06_30

  • Upgraded Double Breaker to Spin Breaker. Instead of a simple repeat of Backbreaker, Ax now carries opponent through a short hop and spin into another backbreaker on his opposite knee.
  • Rise and wake up from camping animation tweaked for smoothness.
  • Several minor animation tweaks.

2011_07_06

  • Added “Hun Suplex” as follow up to Backdrop and future air to ground throw.

2011_07_07

  • Add “Melon Splitter” as follow up to Hun Suplex. Allows further follow up of Flying bomb.

2011_07_20

  • Add “Ax Destroyer” air to air throw. Inspired by Zangief’s Siberian Blizard. Still needs splash damage effect.
  • Minor animation and attack type tweaks.

2011_07_22

  • Follow up series for Atomic Drop.
  • Short stab.
  • Align Shock/Burn flash effects.
  • Smoke effect when landing from Shock/Burn fall.

2011_07_20

  • Add stationary grabattack (Barbarian Fury, based on Stern Blade’s stun combo from Arcade Golden Axe II)

2011_07_26

  • Add counter. If player defends against a running or jumping attack just as it hits, Ax will catch the attacking opponent and perform a Power slam, even from behind or if the attack could not be blocked normally.

2011_07_31

  • Add Air to Ground throw (Python Drop – A swing DDT style throw).

2011_08_07

  • Add Ground & Pound. Follow up for Powerslam and planned tackle.

2011_08_09

  • Add tackle. Fwd or Back + Atk when running very close to opponent. Takes good timing but unblockable and allows follow up ground & Pound, possibly some others in the future.

2011_08_10

  • Aesthetic improvement for Backdrop and some other minor sprite touch ups.

2012_08_21

  • WALKOFF
  • Backstep includes landframe and no longer acts as jump.

To Do:

  • Follow up for Backdrop. German whip? Rolling cradle?
  • Follow up for Atomic drop.
  • Follow up for jump slams.
  • Mid air catch slam of some sort.
  • Burn/Shock sparks play perpetually after KO.
  • Shock flash is not aligned.
  • Air to ground throw of some sort.
  • Splash damage for hard slams.
  • Rolling cradle. Possible follow up for Backdrop or as an otg maneuver.
  • Catch and Powerslam when blocking non weapon attacks.
  • Wall alternate for Powerbomb.
  • Move for Grab, A command. Stunned enemy beating from Arcade GA II?
  • AI cancels and patterns.
  • Re tool magic effects.
  • Bored pose?

Move-list Notes (finished only):

Combo (long range): Sword attack*2, Uppercut punch (Arcade GA II long range combo)

Combo (Med-long): Sword strike*2, Thrust kick (Genesis GA II long range combo)

Combo (Med-short): Sword strike*2, Pommel butt*2, Stab (GA I med-short combo with end from Arcade GA II )

Combo (Short): Sword strike*2, Lift and throw – Can change direction of throw with Forward/Backward (GA I combo with end from Genesis GA II)

Run, A: Shoulder check.

A+J: Uppercut, turn and hop strike (Genesis GA II A+J)

D, F, A: Batter swing (Arcade GA II A+J)

B, A: Back strike (Arcade GA I A+J).

U, A (when knocked down, can use F or B to aim): Upper strike.

A (during Sidestep, Back strike, Batter swing, or Upper strike, can use F or B to aim): Second strike.

Hold A, release: Twirl weapon, hard down strike (Genesis GA III F+A+J)

Jump, A: Downward strike.

Jump, D+A: Dive strike (Genesis GA III J, D+A)

Run, Jump, A: Downward thrust.

Defense: Parry.

Defense (just as a run or jump attack hits): Powerslam (catch and counter opponent’s attack)

Defense (when grabbed or hit): Grab and hurl (GA I short combo end).

Defense (when grabbed or hit, opponent can’t be grabbed): Kick (GA I med-short combo end)

Grappling:

Atomic Drop (B+A with back to wall): 14

Ax Destroyer (F+A or B+A during jump when close to midair opponent): 15 + 20% of target’s remaining HP.

Backbreaker (U, D, A):6

Backdrop (B+A): 8

Barbarian Fury (A): 22

Body Press (Short range combo):NA

Body Throw (Automatic after Body Press, may use F or B to control direction): 10

Flying Bomb (D, F, A): 4

Giant Swing (D, U, A): 12

Ground & Pound (D, D, A): 20

Gutbuster (J): 5

Hun Suplex (D, B, A): 4

Melon Splitter (U, B, A): 4

Powerbomb (F+A): 8

Powerslam (Counter throw; Defense just as an incoming run/jump attack hits): 12

Piledriver (D+A):2 + 30% of target’s remaining HP.

Python Drop (F+A or B+A during jump when near standing opponent): 8

Spin Breaker: (F, U, A): 5

Tackle (F+A or B+A while running near opponent): 12

Throw (F+A or B+A): 10

 

  • Atomic Drop
    • Giant Swing
    • Gutbuster
      • Giant Swing
      • Piledriver
      • Throw
    • Spin Breaker
      • Giant Swing
      • Gutbuster
        • Giant Swing
        • Piledriver
        • Throw
  • Backdrop
    • Hun Suplex
      • Melon Splitter
        • Flying Bomb
          • Giant Swing
          • Spin Breaker
            • Giant Swing
            • Gutbuster
              • Giant Swing
              • Piledriver
              • Throw
    • Melon Splitter
      • Flying Bomb
        • Giant Swing
        • Spin Breaker
          • Giant Swing
          • Gutbuster
            • Giant Swing
            • Piledriver
            • Throw
  • Body Press
    • Backbreaker
      • Giant Swing
      • Spin Breaker
        • Giant Swing
        • Gutbuster
          • Giant Swing
          • Piledriver
          • Throw
    • Body Throw
  • Gutbuster
    • Giant Swing
    • Piledriver
    • Throw
  • Powerbomb
    • Flying Bomb
      • Giant Swing
      • Spin Breaker
        • Giant Swing
        • Gutbuster
          • Giant Swing
          • Piledriver
          • Throw
    • Giant Swing
    • Gutbuster
      • Giant Swing
      • Piledriver
      • Throw
    • Spin Breaker
      • Giant Swing
      • Gutbuster
        • Giant Swing
        • Piledriver
        • Throw
  • Python Drop
    • Hun Suplex
      • Melon Splitter
        • Flying Bomb
          • Giant Swing
          • Spin Breaker
            • Giant Swing
            • Gutbuster
              • Giant Swing
              • Piledriver
              • Throw
    • Melon Splitter
      • Flying Bomb
        • Giant Swing
        • Spin Breaker
          • Giant Swing
          • Gutbuster
            • Giant Swing
            • Piledriver
            • Throw
  • Powerslam
    • Ground & Pound
  • Tackle
    • Ground & Pound

Models – Bitter

Lt. Bitter

Lt. Bitter

Lt. Bitter

Lieutenant Bitter enemy development. In the original game, character is presented as a slow moving but very quick striking armored knight. However, Bitter’s armor was entirely visual; the only defensive advantage he enjoyed over players was immunity to throws. As throws were simply a more appealing visual combo bookend, even this defense had little to no effect from a mechanics standpoint.

The remake Bitter will gain a slight mobility boost, with greater walking speed, ability to “run” (actually a faster walk), and attack on the move to catch unwary players. He will also be given very powerful defenses to match his armored appearance. Weak attacks of any type will not affect him at all, and bladed weapons will cause half their normal damage. As a last addition, Bitter will use his existing shield slam attack against projectiles… batting them back to potentially hit the originator.

2011_06_13

  • Added running. Visually it is a hustled walk due to lack of running sprites. No where near as fast as most other characters true running capability, but still much faster then normal walk.
  • Added RUNATTACK; a horizontal back stroke with same range as normal sword slash attack.
  • New blocking sprite. Playable version can block indefinitely.

Models – Heartland

Heartland (Bad Bros.)

Heartland (Bad Bros.)

Heartland (a.k.a. Bad Brothers) enemy development. Original game version is a simplistic boss enemy with high range and damage but slow speed and practically no means to defend himself against player attacks.

Updates are to include improved animation, standard upgrades to motion trails, and voice effects. Difficulty increased with slighter higher movement speed, an even longer reach, and near immunity against bludgeoning type attacks. Will also become more effective at close range, with a dangerous bear hug grapple that will severely damage targets.

2011_05_30

  • Removed sprites:
    • False transparency (replaced with true transparent motion blurs):
      • a5
      • a7
      • a9
    • Fall/Pain (replaced with standardized defense poses):
      • p1
      • p2
      • p3
      • thrown1
      • thrown2
      • thrown3
      • thrown4
      • b1
      • b2
      • b3
      • s1
      • s2
      • s3
    • New Sprites
      • 0001, Jump/Land.
      • 0002 – 0005, Decapitation.
      • 0006, Kick blur.

      Motion blurs added.

    • Attack1 (Hammer strike) now steps forward for slightly more range.
      • Hammer smash attack now includes transparent motion trail and steps forward or extra range.

  • Run attack includes landing/jumping frames and dust.
  • Animation offsets tweaked for Kick, hammer Sweep and Hammer Smash. Rang settings also tweaked to ensure each one is used at proper distance.
  • Defense settings added. Now takes .25 damage from bludgeoning attacks. Attackers attempting a bludgeon knockdown are paused briefly and laughed at.

2011_05_31

  • Added grappling animations.

2011_06_01

  • In game profile:

    Resolved animation issue with Heartland performing Bear Hug against another Heartland. Caused by order of damage/bind/flash calls.

2011_06_02

  • Riseattack complete.
  • Need to resolve Special and special2 for AI vs. Player control.

2011_06_03

  • Special sequence completed. Will now toss opponents; a modified version of riseattack will be performed instead if target is immune to grabs.

2011_06_08

  • Playable version can no longer perform “Special2”. It is identical in function to “Special” and intended for AI to break away from infinite combos.

Attack Types

Attack types for Golden Axe need rearranging to accommodate addition of fatalities. As of 2011_05_26 I have cataloged the following:

Type Pain Fall Death Block Notes
Attack1 Normal Normal   Normal Bludgeoning
Attack2 Head knock while kneeling Normal Normal Normal Bludgeoning
Attack3 Unused
Attack4 Collapse to kneel Normal Normal Normal Cut
Attack5 Normal Normal Normal Normal Ax Battler’s level 1, 2 and 3 earth magic.
Attack6 Unused
Attack7 Unused
Attack8 Unused
Attack9 Unused
Attack10 Normal Normal Normal Normal All cutting attacks for playable characters.

Script Catalog

NOTICE (Updated 2018-02-23):

I no longer host scripts from this blog – they are now located at my github repository. Most of the scripts below have broken download links and nearly all of them are out of date. I am in process of re-writing them to match the latest OpenBOR engine updates.

In the list below, you will find several items already linked to the library that replaced them. If you do not see a replacement link, I would suggest browsing my my github – you will likely find what you’re looking for.

Thanks,
DC

 

Update log for common script and functions used by all modules. I have found that I often forget which script from identical working copies is the newest version. This should help track them.

License

A copy of or (preferably) link to this license is required for use of the materials below or any other resources provided by Damon Caskey.

 


Event Scripts

Self contained scripts run immediately in response to an engine event. Most will be used to call a user custom defined function.

z_ani

Generic animationscript event script.

z_blank

Blank script file. Allows @cmd tags with entities that do not need user defined functions.

z_block

Universal didblockscript event script.

z_blocka

Universal onblockascript event script.

z_datk

Universal ondoattackscript event script.


Functions

Custom predefined functions to be called by event scripts.

ani0009

Animation switching wrapper. Validates animation before a switch attempt is performed and allows quick use of both available animation switch methods. Handles basic animation switching needs for almost every other function.

ani0012

Specialized animation switch; performs Grabattack2 if opponent is “Bad Brother”. I normally prefer more a more generic approach using parameters, but this is in place already and it does do the job.

Moved to Avalanche repository.

ani0014

If target can be grappled, caller is set to passed animation. Otherwise alternate animation is used if available. If not, nothing is done.

ani0016

Perform alternate animation if target is rising or performing a rise attack.

ani0020

Wrapper to perform animation when triggered by key script.

bind0010

Primary grapple binding function. Binds and sets target entity into desired pose, or sets position and releases.

bind0017

Find preexisting entity with same name and warp to location. Primary use is to spawn self on top of old corpse. Creates effect of a “dead” character standing back up when player continues or has lives remaining; much less jarring then a new copy appearing out of nowhere.

bind0021

Shunt self away from wall if bound entity is inside of it (wall). Prevents getting a bound entity stuck within areas meant to be inaccessible or bounced to infinity by wall functions.

dama0004

Damage caller’s bound entity by index. Differs from dama0001 in that a mode is provided to allow non-lethal damage, and attack types are passed as integers rather than a string.

  • 2010_02_02Fatal Fury Chronicles
    • Authored.
  • 2011_07_19Golden Axe The Hackjob
    • iDam variant now initialized as 0. It seems OpenBOR will occasionally keep the value of a NULL initialized variant in a given script across multiple callings. Such a bug would be virtually impossible to find and eliminate, especially given its inconsistency; it is more pragmatic to simply adapt scripts accordingly. In the case of dama0004, retention of an iDam value of -1 could cause targets to have their hit points reduced to 0 immediately. In turn applied damage would always be lethal regardless of intended amount.

debug0001

A very messy but (to me) invaluable function to view and modify various system values in game. Its most powerful use is to edit grapple move poses during live game play and log the resulting command for use in a model text.

draw0001

Primary setdrawmethod() wrapper. Enables the classic pseudo 3D scaling and rotation effects when entities move about the screen as in many golden age arcade games, particularly the Neo-Geo.

draw0002

Support function for draw0001. Applies ratio parameter to offset parameter, ensuring the result is always a whole number. Main use is to integrate zoom effect with binding (bind adjustments must be whole numbers).

draw0003

Assign a group of draw method parameters to model, to be applied by draw0001.

ht0001

Returns entity’s current height, including current draw adjustment.

jump0003

Enable double jumping, wall jumping, etc.

Replaced by Hansburg library.

jump0005

Enable Mario Brothers style jump height control.

Replaced by Hansburg library.

mode0001

Wrapper to switch entity’s weapon and model name.

mode0002

Find out what weapon models (if any) players have and store them for placement into next level. Originally written to enable the feature in Golden Axe where an animal was retained from previous level, only to automatically run away during bonus stage.

  • 2011_03_29Golden Axe The Hackjob
    • Copied directly from “saveanimal” by Utunnels (contains a previous modification by myself to accommodate Joe & Alex). Will likely need a rewrite to take advantage of new string functions; it currently uses a limited static list and I am enabling playability for nearly every character in the game.

parr0001

Parry functionality. Check for Key timing and apply parry settings accordingly.

path0001

Returns full path of passed entity, minus file name.

path0002

Returns folder of passed entity.

rnd0001

Generate random numbers.

Replaced by Eggball library.

run0001

Simple “stop running” function useful for adding a controllable dash movement.

soun0005

Sound catalog and player. Catalogs sounds by tiers and selects sound from group at random. :

  1. entity/sounds folder
  2. global sounds/throwdamage
  3. global sounds

May also play specific sound from group if needed.

soun0009

Sound effect wrapper. Verify sample and last play time, then play sample with location based stereo effect.

velo0001

Wrapper for velocity control.

wall0001

Primary wall function. Damages and bounces self in opposite direction of current X velocity when falling and obstructed by wall/platform. Also provides optional jumping/climbing onto an obstacle along Z axis for AI controlled entities. OpenBOR already allows optional Z jumping, but AI controlled entities always use their full jump height/length and may overshoot if the target platform is small. There are also cases where a custom animation would simply provide greater aesthetics.

  • 2009_10_10 – Fatal Fury Chronicles
    • Authored (wall bounce only). Optional climbing added later (unknown date).
  • 2011_07_22Golden Axe The Hackjob
    • Wall bounce velocity is now a % of original velocity instead of a static value. This adjustment adds nuance to the timing needed for wall juggles. It also improves visual appeal, as a harder impact is now rewarded with a harder bounce. Additionally, victims caught between two walls will no longer infinitely bounce and “climb” upward; the gradual loss of velocity means they will eventually lose momentum and fall as expected.

z_block

Universal ondidblock function.

z_datk

Universal ondoattack function.

z_spawn

Universal onspawn event function.

Model Switching Caveats

Model switching is a concept I have used to centralize the model sheets for different types of the same character. Traditionally, a character in OpenBOR is represented as a player, enemy, or npc, each labled by the type parameter int heir model text files. Should an author desire to create a character that is both playable and an enemy ( a common example would be making enemy bosses playable as a bonus feature), the usual method is to copy the model text file, change type, and fix some header settings. The same holds true for adding an npc type.

The problem arises when models begin to get highly complex, and/or changes are made after the initial design. Every change must be copied over by hand, else-wise they won’t match. In some cases this may not be so noticeable, but if a major animation change or other redesign is made to one model and not the other, their differences will be glaringly obvious. Naturally maintaining two identical models can quickly get tedious and confusing, especially when scripts or other advanced features are involved.

The model switching concept is an attempt to somewhat alleviate the problem of maintaining multiple texts. Through the script command changeentityproperty({ent}, “model”, {model}, {ani flag}) OpenBOR allows any entity to switch over to another model text. This switch behaves in many ways like the built in weapon system:

  1. Animations from the new model replace those from the old.
  2. The model retains its original name and path, along with most header commands. A few are overridden or not retained, see below.

The initial model switching itself is an easy process; organization and ensuring the right model is always in use during game play events can get more involved, especially when combining with the default weapon system. Step by step, this is the process:

  1. Each character contains a single centralized model text of enemy type. This file contains every animation and header setting that is possible to share. The name header setting and file name must be identical to the folder it resides in (data/chars/example/example.txt).
  2. Each of the other types (player, npc) the character may represent are given their own model sheets, as in the traditional method. These models however, only contain the bare minimum of settings unique to a type or required by circumstance and serve as a staging model. They are labeled by a name plus type identifier. These are the models spawned into play by the engine.
    • examplep: Player type.
    • examplen: Npc type.
  3. When a staging model is spawned into play its onspawnscript immediately runs a model switch to the main model.
  4. No other steps are needed unless weapons are in use.
  5. If weapons are in use, the weaponframe command is replaced by a scripted alternate.
  6. Weapon removal in response to being killed or knocked down works normally. However, as this effectively sets the model back to it’s staging version, the switch from staging to main must be performed immediately afterward.

I have found this method to be effective and surprisingly stable. The slight complication with weapon use and issues below is more then made up with having with a few exceptions only one large set of animations to work with.  It does however require paying careful attention to property behavior, as most properties are retained from the original model. The following is a list of these as I catalog them find them and a work around for any issues. Unless noted otherwise, these properties must be included in all model sheets.

  • atchain
  • bflash
  • cancel
    • Requires inclusion of the full animation, including cancel command, in original model.
  • com
  • combostyle
  • dust
  • gfxshadow (until new model moves on Z axis).
  • jumpmove
  • weaponframe
    • When reverting to primary model (no weapon), scripts from weapon are retained in place of primary model.
    • There is no true workaround. Solution is to replace weaponframe with scripted substitute.

Work Log

2010_07_12

  • Start of work log. I cannot recall all of the changes I made today, thus the point.
  • How To Play revamped. I’m not really satisfied due to limitations of the feature and preferably would remove it outright in favor of an in game replacement. Unfortunately the option itself is hard coded into engine’s start menu. Having it do nothing or lead to a blank file would be too unprofessional.
  • Ax’s piledriver damage is now 30% of opponents remaining health + 5 (similar to Mike Haggar in Final Fight). This will make move useful for causing heavy damage to strong enemies without being the end all be all technique of choice.
  • Ax’s powerbomb damaged reduced to 8 from 12.

2010_07_15

  • All remnants of legacy sound players (soun0001(), soun0002()) removed from module and replaced with soun0005.

2010_08_07

2010_09_18

2011_02_13

  • Name based model switching on spawn application in progress. This is to combine NPC, Enemy, and Player versions of a character into a single central model.
  • Work Log separated from Bug & To Do List.

2011_02_20

  • Fixed bflash for Ax Battler.
  • Switched log dates to Big Endian form.

2011_02_21

  • Removed all instances of “loop 0”.
  • Defense pose moved from follow10 to follow51 to comply with standard from my other modules.
  • RUNJUMP and range settings for JUMP added to ax.txt.

2011_02_22

  • Ax’s sidestep is now a roll instead of a jump.
  • Added dust setting to ac_pc staging model.
  • Added extra frame to Ax’s rise animation.

2011_02_23

  • Ax Battler:
    • Removed Lateral High Jump from all models.
    • Added jumpmove 0 1 to all models.
    • Removed “Stats” entry.

2011_03_27

  • ai0002
  • ani0001
  • Longmoan
    • Successfully integrated single model concept. Longmoan is now player type in model sheet and selectable at start screen, but behaves like enemy as a level spawn.
  • common/attack.h rolled into enemy.h
  • Merging of animation scripts to enemy.c (enemy.c is to be moved and renamed).

2011_03_28

  • enemy.h rolled into z_ani.c
  • All slide {x} calls replaced with velo0001 {x} {y} {z}. Slide.h removed.

2011_03_29

  • All remaining scripts from common folder removed. Some functions copied directly to z_ani.c and still need to be given individual files.
  • bgs2 folder renamed to bgs, old bgs removed.
  • scenes2 folder renamed to scenes, old scenes removed.
  • levels folder renamed to levels.
  • Individual constant lists consolidated.

2011_05_16

  • Multiple enemy lifebar and icon display now takes advantage of sprite array feature. This solves issue of integration with conflict with player icons and also allows enemy icons to reflect status. Icons added to individual model sets:
    • Amazon
    • Bitter
    • Henninger
    • Longmoan
    • Skeleton

2011_05_17

  • Removed all instances of entity vars ADBLEND and ADREMAP. They are no longer needed for passing blend and map respectively to draw0001().
  • Upgrade following effect models to Fatal Fury Chroniclesfolder layout.
    • flash

2011_05_20

  • All flash models now moved to ->misc->effects->models->flash->folder layout.
  • Flash models now run spawn0002.c, with spawn0012 eliminated.
  • Flash bugs (wrong size, palette, alpha) fixed and accurate effects added (sword vs. hand vs. blunt, etc.) as part of reorganization.

2011_05_24

  • Fix complete for bind0023; dragon throws now use Defender’s custom flash if it has one.
  • Bad Brother’s flat fall and fall on head added.

2011_05_25

  • Menu text added.
  • Backstep now mapped to Down + Defend (formerly Attack2). This cuts total action keys to four (Attack, Jump, Defend, Magic).
  • Magic fail moved to keyall.c with generic code to work with all characters.

2011_05_27

  • Resolved issue with Ax Battler’s Piledriver and Jump throw knocking himself down. Caused by landframe call being incompatible with engine’s updated landframe array.
  • Added Ax battler’s “Second Strike” general purpose follow up swing to be canceled from several other animations. Still needs motion blur.

2011_05_29

  • Completed Ax Battler’s Second Strike.
    • Motion blur.
    • Cancels.
      • Backattack
      • Riseattack
      • Sidestep
      • Power Swing
  • Replaced all “switch_combo” calls to ani0012.
  • Removed unused functions from z_ani.
    • adjust_ftoss
    • adjust_ftoss2
    • ftoss
    • ftoss2
    • change_slam1
    • change_slam2
    • change_slam3
  • Bone break medium sound (253_0) and model added (bonem).

2011_05_30

2011_05_31

2011_06_02

2011_06_03

  • Resolved issue with draw0001 crashing game on certain stages when an entity touched Z boundary. A simple typo was setting both the fMinZ and fMaxZ to = minimum Z boundary instead of min/max respectively.
  • See Heartland.

2011_06_08

  • Resolved issue with revive on spot system (see bind0017) when player lost lost all lives and continued with different character (thus leaving original character’s corpse behind). If any player later selected the left behind character, script would attempt to warp them to off screen corpse.
  • See Heartland.

2011_06_13

2011_06_14

  • Removed script functions/files:
    • scripts\drain.c
      • Used to gradually remove life when playing skeleton mode in GA Remake. Skeleton will be playable as normal bonus character without drain effect.
    • data\levels\duel\sleep.c
      • Cause crowd to attack by setting “sleep” global var to NULL(). A validation in each individual model’s looping SLEEP animation would then set model’s animation to IDLE and stealth property to 0.
    • data\chars\skeleton\scripts\npc_ani.c
      • Rolled into data\scripts\ z_ani.c
  • Removed global variants.
    • countdown
    • cstring
      • Support for drain.c.
    • levelmaxz
    • levelmaxz
      • Replaced with openborvariant() calls.
    • inscreen
    • sleep
      • See sleep.c above.
  • Removed models.
    • data\chars\gilius\g_npc.txt
    • data\chars\tyris\t_npc.txt
      • All versions (NPC/PC/ENEMY) to be rolled into single model.

2011_06_27

  • Holdblock capable characters no longer use special unless they are actually in pain (see z-spawn and keyall).
  • See Ax Battler.

2011_07_26

  • Several minor script updates and fixes.
  • See Ax Battler.

2011_07_31

  • Added EX1 and EX2 defense poses to several models (will complete during individual model phases) to accommodate Golden Axe’s odd offsets when binding self to target instead of target to self.
  • See Ax Battler.

2011_07_26

  • Several minor script updates and fixes.
  • See Ax Battler.

2011_07_31

2011_08_31

2011_09_01

2011_09_06

2011_09_07

2011_09_19

2011_10_19

  • Fixed wall0001 function.
  • Replaced TLTDN with proper Tilted Down sprite for all characters. Old TLTDN (custom lift pose for Golden Axe) moved to EX3.

2012_01_11

2012_02_07

  • z_hit now calls function function hit0004, made from z_hit’s original code.
  • soun0005 now includes a final entity check. This fixes bug where entity killed with killentity() would still send call to soun0005, which would then result in empty string call, and ultimately a shutdown by string functions.
  • See Tyris Flare.

2012_08_21

  • Chicken now releases opponent in FALL7 (Fall on head) pose.
  • See Ax Battler.
  • All remaining known instances of “openborconstant” in chars folder replaced with preprocessed constants from constans.h.

Ray McDougal Sprite Set Improvement

Animation and sprite color upgrade complete for Ray McDougal. Several improvements were required, as this sprite set is being used as a generic thug. It is imperative to have quality color, animation, and attack technique variety since it will be seen repeatedly.

  1. Sprite set was procured from second game, Fighters History Dynamite. This sequel was missing several animations and had lower quality animation in general then the already sub-par original.
  2. Sprite set featured almost no color separation. Identical shades of blue used for shirt, gloves, pants and shoes. This combined with other shortcuts by original artists such as liberal application of #ffffff and #000000 made alternate palette creation nearly impossible.
    • Solution: Hand color entire sprite set (approximately 270 units) with individually dedicated colors for each portion of the sprite:

      Ray's base palette. All major sectors of the sprite now have dedicated color sets.

  3. Even with all animations combined from both games, animation was still lacking overall. In particular, attack recoils are simply the strike frames played in reverse. This is very jarring when seen next to more painstakingly created sets from other sources.
    • Solution: Combine hand drawing and franken-sprite techniques to create new frames for attack sequences. Most non attack sequences have satisfactory animation.

In addition to the above improvements, Ray also received a “rounding out” of available techniques. Effectively he is now a complete player character with weaker statistics. This is really somewhat overboard given the large number of basic moves available to players, but again as Ray will be seen quite often, I believe he should have a wide array of abilities and tactics to avoid repetition.

Owing to most of the work requiring hand drawing, the total time needed was just over a month. I am pleased with the results however. This should make an effective generic thug to oppose the players without boring them.

Ray combo I

Ray's basic far and close attack chain pre improvement.

Ray McDougal basic attack chain as of 02092011.

Ray's basic far and close attack chains as of 02092011.

Tutorial – Random Names

Random names may seem like a superfluous addition at first, but they can go a long way toward giving characters in any game a bit more variance and personality. This is particularly true for low level enemies that are reused repeatedly throughout an OpenBOR module. This tutorial will demonstrate how to apply random names to entities as they are spawned into play. It is meant primarily for level spawns, but can easily be applied to any other type of entity, including player characters.

Objectives:

  1. Apply a random name when entity is spawned from set of predefined choices.
  2. Easily edit name list without disturbing other models or modifying scripts.
  3. Support of both random and non-random names without need for time consuming edits or storing additional data.
  4. Fail over support if random name is called for but not available.

To accomplish this, I have put together a system that takes advantage of kbandresson’s text file stream reader. A single text file contains all the random names each model will use, allowing for quick edits. The entity’s starting alias determines if randomizing is applied or not, so that specific naming is not interfered with. Finally, should randomizing be called for but no names provided, the script will use that model’s default name.

This system has been in place since around November 2008, and has served well in all of my WIPs so far.

Getting Started:

You will need the following files before beginning. Download and unzip each of the following to the specified locations in your module’s data folder.

Note: These scripts are formatted in Allman Style and written with MS Visual Studio 2010. You can use other applications if you wish, but if you do, the formatting will not render correctly and you may find the code difficult to read.

index – data/scripts/vars
z_spawn – data/scripts
name0001 – data/scripts/com
rnd0001 – data/scripts/com
name – data/bin

Step by Step:

Once you have the files above unzipped to their respective locations, open the text file of any model. For testing, I would recommend a commonly occurring enemy. Add the following to its header:

onspawnscript data/scripts/z_spawn.c


Next, open a level text file that contains spawns of the model you just modified. For every spawn instance you would like a random name, add or change the alias to “Random”.

All that is left now is to set the list of names up for your model to use. Open the name example file you unzipped earlier. It should look something like this:

To add your model, just insert another row between Model and End, and add your model’s default name to the first column. Note the last column must always be “1“. Insert as many alternate names as you want in between, separated by at least one space (tip: I recommend tabbing so that names from each row line up, it makes the text easier to work with). For obvious reasons you cannot uses spaces in names, but remember that OpenBOR does not display underscores “_”, so you may use those instead, as with Andy B. above. When your model is spawned into play, it will be given one of the names from its row. You’ll notice for example, I am using a theme naming scheme similar to Streets of Rage.

Andy_B: Doesn’t have any alternates, so will always uses default name.
Ray: Hair Care
Mika: Famous female wrestlers from the WWE.
Brian: Famous real life boxers.
Rick: Common boxing lingo.

You are of course free to use whatever naming style you like. You can add as many or as few as you want, so have fun!

Congratulations, you have added random naming!

Extra Credit:

  • Like any other function, name0001() can be called at any time. You can use it to rename characters at any point in the game. Try some things like changing names when life is low or when the entity is about to perform a certain attack.
  • The overall concept isn’t limited to names. Try applying it to story narrative, character dialog (“Ouch, that hurt!”, “stop hitting me!”) or anything else you can think of.
  • When I created this system, writing to the text file was not possible, but as of OpenBOR version 2.7111 that limitation no longer exists. With a little fine tuning, you could actually edit the name list in real time to create player name entry systems and other nifty game features.
  • Why stop with text? Try things like random AI modes, or even different models entirely. Use your imagination!

DC

Work Log

This is a general work log for my Fatal Fury Chronicles module project. The goal is to replicate game play elements found within SNK’s Fatal Fury series in a side scrolling Final Fight style environment, while presenting the back story in a more cohesive layout. At the start of this log (11292010) the module is in a playable beta state.

11292010

  • Start of work log.
  • Project back under way after being idle for approximately one year.
  • Resolved issue of crashing instantly during menu on newer revisions. Issue turned out to be nothing more then a leftover configuration save file. Module is in beta status; it has one fully playable stage and one test area, but I would like to add more content before releasing any kind of demo.

11302010

  • Andy Bogard now uses randomized sound effect system. See soun0005() function.

12012010

  • Merge old MS Word based work log.

12022010

  • Andy Bogard model scripts converted to latest convention.
  • Terry Bogard model scripts converted to latest convention.
  • AI Ray McDougal model scripts converted to latest convention.
  • Bug fixes.

12032010

  • Cut JUMPDELAY from 18 to 8; too much of a pause before jump executes.
  • Parked cruisers in Sound Beach stage now catch fire immediately when damaged (previously not until destroyed) and sink with scripted velocities instead of offset/base manipulation.

12052010

  • Added entity verify to draw0001(). Previously it would cause immediate shutdown if called on non existent entity.
  • Andy Bogard & Raiden sprite files converted to nameless serial convention.
  • Bug fixes.

12062010

  • All models and sprites in data/misc/effects updated to serial name convention.

12072010

  • Function bind0010() merged from Golden Axe Hackjob.
  • Function dama0004() merged from Golden Axe Hackjob.
  • All models and sprites in data/misc/flash updated to serial name convention, cataloged in master sprite database and moved to data/misc/effects.
  • All models and sprites in data/misc/dust updated to serial name convention, cataloged in master sprite database and moved to data/misc/effects.

12082010

  • Terry Bogard and Ray sprites updated to nameless serial convention. This completes update of all primary models to date.
  • Latest draw0001() and it’s support functions now use target’s current alpha setting instead of an entity var to get and store the blend parameter. Exact same functionality, but with one less wasted variable and one less script parameter to worry about initializing when entities are spawned. I should have spotted it two years ago.
  • Flashes use MP as a sound constant in place of if/list based on alias.
  • Flashes use Nodrop property as random rotation range.
  • All previously uncatalogued sounds removed from main sound folder. Model specific sounds moved to their respective owners still need cataloging.

12092010

  • Script removal. Several spawn scripts are no longer needed; they basically performed the same function with minor differences. Their functionality is now consolidated into spaw0002.c with sound cataloging and free variable application.
    • spaw0003.c
    • spaw0006.c
    • spaw0007.c
    • spaw0008.c
    • spaw0009.c
  • Ray and Raiden’s sounds cataloged. Both still need sound calls upgraded to soun0005.c function.
  • Flash spawning function created (bind0022()).

12102010

  • Flash spawning fully integrated. Required new functions (summ0002() and bind0023) see below.
  • New function: summ0002(void <vEnt> char <cModel> char <cAlias> int <iMap> int <iBlend> int <iX> int <iY> int <iZ> int <iDir> int <iAni> int <iFrame> int <iKill>)

    • Spawns an entity (usually a flash) by name unless <vEnt> has a custom flash defined by the flash model header command, in which case the defined custom flash will be spawned. Location is screen based.
  • New function: bind0023(void <vTarget> char <cModel> char <cAlias> int <iMap> int <iBlend> float <fAX> float <fAY> int <iAZ> int <iDir> int <iAni> int <iFrame> int <iKill>)
    • Spawns an entity (usually a flash) by name and binds to location of <vEnt>. If <vEnt> has a custom flash defined by the flash model header command, the defined custom flash will be spawned instead.
  • Adjusted block push back (bloc0002(), called in z_hit.c). Previously multiple incoming hits could force the blocking character a ridiculous distance across screen.
  • Merging bind0010() functionality:
    • Andy Bogard
      • Grabbackward
      • Grabforward

12132010

  • Imported key0006() from Golden Axe Hackjob and finished updating keyall.c to latest standard. Had missed these earlier; debu0001() cannot work without them.
  • Added font3.png (it’s a copy of font2 for now). Not normally needed in game, but is used by debu0001().
  • Removed final frame from Andy Bogard’s taunts. Idle animations already include transition frames.

12142010

  • Further progress for “bind to target” capability in bind0010(). Only needs velocity application.

12152010

  • debu0001() now includes ability to toggle autozoom from draw0001().
  • key0006() given new parameter <fQnt>. Allows increments/decrements by specified quantity instead of static 1.
  • bind0010() modes rearranged (in progress). See function.

12162010

  • New function: ani0012(void <ent>, int <iH>, int <iFrame>)
    • Skips to <iFrame> if target’s Y axis position is <= <iH>. Allows jump animations to adapt to variable height (i.e. don’t start a full somersault during a short hop).

12172010

  • Taunt/Poses now mapped to Special + Attack + (optional) Direction instead of Pose + (optional) Direction. This cuts action keys back to Attack, Jump, Special, and Backstep. A fifth action key dedicated to poses just seemed cumbersome and didn’t mesh well with the overall control scheme.
  • bind0010() modifications complete. Now accommodates binding based on attacker or defender’s location and automatic adjustments to deal with larger/smaller characters without switching animations.

12182010

  • Separated Work Log from Bug List/Notes. It was getting unwieldy to sift through, and separation will also allow tabbing between “to do” and current progress rather then scrolling. The Bug List/Notes article will probably need breaking down later as well.
  • Updated dama0002() function:
    • Grapple binds are now released correctly when taking damage.
  • Updated pain0001() function:
    • Hit level animation switching now verifies alternate pain animation before applying.
    • Application of hit effects. See effe0001() function.
  • Updated fall0001() function:
    • Hit level animation switching now verifies alternate fall animation before applying.
    • Individual checks broken down to separate if calls for readability.

12192010

  • Updated kill0001() function.
    • draw0001() no longer called to reset parent map for effect models (not needed as draw0001() is not used for standard mapping).
    • Entity variable cleaning code replaced with vars0001() function.
  • Updated spaw0002() function.
    • Entity variable cleaning code was missing. Replaced with vars0001() function. Shouldn’t be needed since cleaning is done on entity removal by kill0001(), but adding it anyway in case an unforeseen engine glitch does not allow kill0001() to finish.
    • Random name code replaced with name0001() function (function is identical to original name code).
  • Updated fall0001() function:
    • Application of hit effects. See effe0001() function.
  • Adjusted Ray’s Burn animheight accommodate burn effect.
  • Added SPAIN and SHOCK animation to Ray; shock effect works as designed.
  • On death fatality adjustments in progress. Is komap setting open to script?

12232010

  • New function: draw0006(void <vEnt> void <vMatch>)
    • Enables matching of draw scale between two entities using their height settings. Replaces the “quick and dirty fix” that was in kill0001() for almost two years. Previously the fatality model spawned on burn death was given a static size adjustment of 75% as its sprites were over sized; the adjustment is now automated. An obvious added benefit is that it will also self adjust to match abnormally sized characters with any further amendments.
  • Replaced burn fatality sequence with ball explosion and Komap switching. See kill0001(). A better solution would be to turn Komap off, but due to the engine’s layout this is not yet possible. An engine modification is needed to fix this issue long term, but in game everything works as needed.
    • Look into using hmap property; if available to script, will remove need for static map constant when resetting Komap.
      • 12262010 – property open to script and can be used to replace static map constant as described.

12242010

  • For whatever reason stupidity on my part jump0005() function was embedded in z_movez.h. Function moved to its own file.

12252010

  • Setting for komap in deat0001() now uses hmapl property in place of MAPX constant.
  • Function soun0003() (random KO sounds) removed. Functionality long since replaced by soun0005() and numeric based sound cataloging.

12262010

  • Variables iRemap and iAlpha removed from draw0001() function. There is no need for them as the passing -1 to either as a parameter in setdrawmethod() allows target entity to use its own property setting. Previously setdrawmethod() would override entity’s map and alpha properties, meaning they had to be adjusted through draw0001().
  • New function: targ0002(void <vEnt> int <iAni> int <iType> int <iSType> int <iTD>)
    • Find nearest entity within range of a base entity’s animation range setting that matches type, subtype and throwdamage parameters. Intended use is to replace item based music change and similar Easter eggs, but is useful for finding any specific entity not otherwise detectable with global findtarget() function.
    • Step 1 for replacing item based music switching; detects when user presses key in close proximity to music switching trigger obstacle.
  • Script removal:
    • dust0001.h
      • Was a name based spawn function only used by Sound Beach cruiser to spawn water splash. Water splash can be replicated by another function. General use for script has otherwise long since been replaced by my dust model header additions.
    • dust0002.h
      • Similar to dust0001.h but with numerous parameters added. Functionality similarly replaced by recent additions to engine’s default dust system and was not in use at all.

12282010

  • Andy Bogard’s palette sprites moved to <char>/pals folder and converted to nameless serial. Palette 0015 (black) retouched to match KOF2000.
  • New function: file0001(int <iVar> char <cFile> char <cRow> int <iColumn>)
    • Wrapper for basic text file reading; finds row by text passed through <cRow> and returns value located at column number <iColumn>.
    • Step 2 for replacing item based music switching. Will locate music by by being passed music switch obstacle’s <aggression> value. Desired column will be passed as looping numeric cycle (not complete at this time).

12292010

  • New function: musi0001(void <vEnt> int <iNotch>)
    • Locates text file argument by using target entity’s aggression setting as row search and nodrop as column number. Argument is passed to global playmusic() command and <iNotch> is added to nodrop setting to determine column selected next time function is called on target entity. This allows use of obstacle as an interactive switch in general instead of music only. Furthermore, as aggression is a spawn parameter, the same item can be used for multiple sets of music with no modifications, variables, or additional scripts. Additionally, soun0005() is activated on use, passing the obstacle’s maximum health as sound group. In the same manor as aggression setting, adjusting the heath spawn parameter allows choice of sound effect group without any adjustments to model/scripts.
    • Step 3 for replacing item based music switching; will be added to global keyall.c script.
  • New entity: data/chars/misc/pickups/swit0001
    • Is an inert obstacle made to replace item based music switching and other types of stage interactivity as noted above.
  • Sound effects 100_0 and 100_1 (both are radio tuning sound effects) added, and moved to /swit0001/sounds folder.
  • Music switching upgrade complete.

12312010

  • New script: z_datk
    • Called by most entities as their ondoattack script.
  • Script updates:
    • parr0001:
      • Retool in progress to take advantage of engine features available as of version 2.955.
        • Parry animation.
        • Air Parry animation.
        • Pause for Defender and Attacker
        • Switch direction to face Attacker.
        • 30% MP recovery for Defender.
        • Engine default collision disabled.
      • Remaining:
        • Parry flash.

          • 01012011
        • On screen alert?
        • Adjust timing threshold for parry command? Current timing of 0.3 seconds seems too easy at the moment, but test was in controlled environment with single opponent using a predictable attack.

          • 01012011
  • Raiden:
    • Added Drop Kick.

01012011

  • New Entities:
    • bflash: Block flash.
    • pflash: Parry flash.
    • fflash: Fire flash.
    • eflash: Electric flash.
    • iflash: Indirect flash.
  • All flash models now located in folder data/chars/misc/effects/models/flash.
  • Script updates:
    • parr0001:
      • Parry flash.
      • Check for state (can’t be in pain or blockstun).
      • Command mapping finalized: Press Special within 0.3 seconds or less before incoming attack makes contact.
      • On screen prompt?
  • Ray:
    • Old sound calls replaced with soun0005(). Now fully upgraded to self cataloging random sound system.
    • Aggression speed increased from 130 to 0.
    • Shock fatality.
  • Andy Bogard:
    • Minor bbox correcting in BLOCK animation.

01022011

  • Andy Bogard
    • Additional voice effects.
      • 3_0
      • 3_1
      • 3_2
      • 7_4
      • 26_2
      • 27_1
      • 28_2
      • 28_2
      • 103_1 (Geki Hishoken 2)
      • 111_0 (“hatz”)

01032011

  • Andy Bogard
    • Additional voice effects:
      • 110_1 (Zaneiken 2)
      • 112_0 (“zan”)
      • 113_0 (Speaking to Tung Fu Rue)
      • 114_0 (“Master Tung”)
      • 115_0 (“Geese”)
      • 116_0 (“san”)
      • 117_0 (Max attack unleash)
  • New entities:
    • Hyper sparks:
      • Hyper sparks separated back into individual models. Previously a single model (paus0001) contained animations and palettes for all hyper effects. The idea was to reduce memory consumption. While text files are minimal, each model loads its own copy of any given script. However, by separating each into their own models, the sound cataloging system can be implemented in the same manor as normal models (less confusion). Furthermore, this eliminates need for animation scripts within the hyper spark models; only a one time spawn script is needed. The overall result will be slightly greater memory consumption, but with better run time performance. The latter is of greater concern as this module will not run on a memory shy platform anyway due to sheer quantity of animation.
        • hype0001
        • hype0002
        • hype0003
  • New sound files:
    • /hype0001/11_0
    • /hype0002/11_0
    • /hype0003/11_0

01062011

  • Revamp of projectile system in progress to take advantage of ondoattackscript:
    • Projectile models are to be separated back into individual models (previously they were combined, see hyper sparks in 01032011 entry).
    • Current projectile function proj0002 to be greatly simplified, it currently requires 33 parameters.
    • Addition of numeric indexed global vars (see grapple binding) to track all projectiles?
    • Engine modification:
      • Script access to throwframewait property. It is another excellent candidate for Free Variable use.
      • Script access to custom attack flash. Will greatly simplify and improve efficiency of spawning custom flash entities.

01112011

  • New function: debu0002 void <vEnt>
    • Uses script access of attack/bbox properties to display collision boxes during gameplay.
    • Includes temporary sub function shap0001() to perform draw actions.
  • Model updates:
    • Andy Bogard:
      • Updated collision boxes using new debug capability for following animations:
        • attack2
        • attack3
        • attack4
        • attack5
        • attack6
        • attack7
        • attackbackward
        • attackdown
        • attackup
        • block
        • blockpain
        • blockpain3
        • blockpain4
        • bpain
        • burn
        • cant
        • charge
        • chargeattack
        • death
        • duck
        • faint
        • fall
        • fall3
        • fall5
        • fall6
        • fall7
        • fall8
        • fall9
        • follow1
        • follow4
        • follow5
        • follow6
        • follow7 (switched to editor)
        • follow70
        • follow71
        • follow72
        • follow8
        • follow80
        • follow81
        • follow82
        • follow83
        • follow84 (Sidestep Up attack)
        • follow85
        • follow86
        • follow87
        • follow88 (check purpose)
        • follow89
        • follow92
        • forwardjump
        • freespecial
      • Consolidated death animations; removal of following:
        • death11
        • death6
        • death7
        • deaht8
      • Counter block impact remnant removal (long since replaced with dodge and parry).
        • follow2
      • Tall target alternate for Shiranui Spider Clutch removed. Updated bind allows auto adjusting to opponent’s height.
        • follow3

01122011

  • Model updates:
    • Andy Bogard:
      • Updated collision boxes using new debug capability for following animations:
        • freespecial10  (Shoryudan) *LF
        • freespecial12 (Zaneiken)
        • freespecial13 (Shippu Oken)
        • freespecial14 (Gen’ei Shiranui)
        • freespecial15 (Gen’ei Shiranui – Shimo Agito)
        • freespecial16 (Gen’ei Shiranui – Uwa Agito)
        • freespecial17 (Yami Abse Geri)
        • freespecial18 (Cho Reppa Dan)
        • freespecial19 (Bakushin)
        • freespecial2 (Plane Force Up)
        • freespecial21(Ku Bakushin)
        • freespecial3 (Plane force Down)
        • freespecial4 (Plane shift attack up)
        • freespecial40 (Low Step Attack)
        • freespecial41 (Low Dash Attack)
        • freespecial42 (Low Step Attack II – Low side kick)
        • freespecial43 (Low Step Attack III – Low palm strike)
        • freespecial5 (Plane shift attack Down)
        • freespecial6 (Hishoken)
        • freespecial7 (Geki Hishoken)
        • freespecial8 (Ku Ha Dan)
        • freespecial9 (Zaneiken)
        • get
        • grab
        • grabattack
        • grabattack2
        • grabbed
        • grabup
        • idle
        • idle2
        • idle3
        • idle4
        • jump
        • jumpattack
        • jumpsttack2
        • jumpsttack3
        • jumpdelay
        • jumpforward
        • jumpland
      • Low Dash Attack is now shoulder ram. Old low dash attack (a lunging low palm strike) will be used for SDM attack.

01132011

  • Model updates:
    • Andy Bogard:
      • Updated collision boxes using new debug capability for following animations:
        • pain
        • pain2
        • run
        • runattack
        • runjump
        • runjumpattack
        • runslide
        • slide
        • special2
        • walk
      • Sidesteps now have invincible start up.
    • Ray
      • Updated collision boxes using new debug capability for following animations:
        • attack1
        • attack2
        • attack3
        • attack4
        • attackbackward
        • attackdown
        • attackup
        • blockpain
        • blokcpain2
        • blockpain3
        • blockpain4
        • bpain
        • burn
        • chargeattack (wheel kick)
        • fall
        • fall2
        • fall3
        • fall5
        • fall8
        • fall9
        • slide
      • Renamed follow40 to Slide.

01172011

  • Color separation in progress for Ray model. Original model used 16 color sprites with white as a highlight and inappropriate color sharing. New color layout provides 64 colors, separated into individual groups for hair, skin, shirt, pants, gloves and shoes.
    • Complete:
      • aapa0000
      • aapa0011
      • 0001 through 0035

02092011

Free Variables

List of outdated or superfluous model and global level values used as script parameters in place of their intended purpose. The idea is simple enough: The variables exist in the engine anyway, so why not save a kilobyte or two and use them instead of adding more to a script?

*Used as normal otherwise.

  1. MP*
    • Projectile priority for obstacle types. See prjo0001() function.
  2. Throwdamage
    • Custom Subtype:
      • 0 = Human Male.
      • 1 = Human Female.
      • 2 = Mechanical.
      • 3 = Music change.
      • 21 = Default value.
  3. Speed*
    • Manual zoom adjustment for flash effects. See spawn0002.c script.
  4. Alpha*
    • Function draw0001() reads in entity’s current alpha setting and uses it as alpha/blend parameter when applying settings to setdrawmethod().
      • 12262010 – Removed. No longer needed as passing -1 to the alpha parameter of setdrawmethod() allows entity’s current alpha property to be used instead.
  5. Nodrop*
    • Flash effects pass random number from 0 through <nodrop> to ADROTATE (results in single random rotation on spawn).
  6. Flash
    • If <Noatflash> parameter is set ( != 0), Flash effects will spawn <Flash> model as a secondary effect. If <Noatflash> is not -1, the secondary model will have its animation set to follow+<Noatflash>. See spaw0002.c for details.
  7. Guardpoints
    • Parameter to identify and differentiate one shot entities (flash & dust) from each other. This allows a single spawn script to deal with most one shot entities and still treat them uniquely (i.e. a dust entity uses a splash animation when out of Z bounds in a beach stage, but a flash entity does not).
  8. Nodrop
    • Music Switching
      • Music text file stream column position marker. See musi0001() function.
  9. Aggression
    • Music switching
      • Music text file stream row position marker. See musi0001() function.
  10. Max Health
    • Music switching
      • Sound effect to play when music switch takes place. See musi0001() function.

Notes & Bug List

This is a general work log for my Fatal Fury Chronicles module project. The goal is to replicate game play elements found within SNK’s Fatal Fury series in a side scrolling Final Fight style environment, while presenting the back story in a more cohesive layout then the original. At the start of this log (11292010) the module is in a playable beta state.

Known Bugs/Issues:

Major

  • Andy Bogard’s shadow trails are not palette matched during certain jump frames. This means sprite set as a whole needs re mastering to synchronize palette.
    • 11302010 – All palettes are correct. Problem seems to be specific sprites are corrupted:
      • 0044
      • 0045
      • 0046
      • 0171
      • 0174
      • 0176
      • 0177
      • 0180
      • 0181
      • 0182
      • 0240
    • 12022010 – Fixed itself. After a year and numerous failed attempts on my part. Go figure.
  • As of OpenBOR revision 2717 the reactive command has been removed due to bugs. This means music changing item in Sound Beach stage is now consumed on use. Possible solution is to replace with inert obstacle that triggers animation and music change via keyscript and proximity.

    • 12292010 – Sound switching now based on keyscript according to proximity to obstacle matching certain parameters. See keyall.c and musi0001() function.
  • Andy Bogard’s Bakushin visual flash has incorrect palette and does not disappear if Andy is interrupted during pose.
    • 12052010 – Updated palette parameter. Failure to disappear and release defender on interrupt is result of a singular script binding Andy to defender. It is a temporary solution that will be replaced by complete throw system from Golden Axe Hackjob.
  • Andy Bogard’s Hishoken caused instant shutdown on hit.
    • 12052010 – Caused by removal of superfluous characters and execution of draw0001(). Andy did not have load command for proj0001. When called, projectile was not spawned since its model had not loaded. When draw0001() was subsequently called on non existent model, the use of setdrawmethod() produced error and shutdown. Fixed by verifying entity in draw0001() and adding load command for proj0001() to Andy.
  • Missing back dash animation for Terry Bogard is causing shutdown. Obviously needs animation added, but also need to roll in newest ani0009 to module; this will verify a given animation before applying it and avoid unexpected shutdowns.
    • 12052010 – Missing animation was actually for “power up”, and added to key script for testing. All known animations intended for game play use have verifying script. Testing line removed.
  • Entities are not getting up more quickly when attacked while down.
    • 12022010 – Staydown values had been adjusted out of playable bounds for testing. Readjusted.
  • Nearly every core script has been updated and/or simplified during Golden Axe Remake project. These scripts need merging to Fatal Fury; will be a difficult undertaking to fundamental differences in modules but ease development in the long run.
    • Use of KO Map feature (reduce variables).
      • 12192010
    • Retrieve and apply default color map without storing it in a variable.
      • 12192010
    • Verifying any animation before application.
      • 12052010
    • Debug system.
      • 12132010
    • Group based random sound effects.
      • 12092010 – Some models still need adapting, but scripts are imported and all sound files cataloged.
    • Grappling system:
  • Lateral auto zoom not working on playable Ray.
    • 12182010 – Playable Ray removed. May be added later using model swapping.
  • Parry system is completely broken. Needs re tooling.
  • Sound Beach stage needs editing at start; palm trees and house appear cut off.
    • 12022010 – Added palm frocks and shorted trunks.

Minor

NA

To Do:

  • Add How To Play images.
  • Remaster music to .ogg format.
  • Random personalities for AI characters.
  • Fatalities
    • Pit.
    • Collapse (normal).
    • Sound Beach Stage.
    • Mr. T.
    • Acid.
    • Shock.
    • Bleed out.
    • Bisect.
    • Decapitation.
    • Incineration
  • Spawn system needs parameters
    • Victory animations.
    • Taunt animations.
    • Others, general.
  • Add Block/Parry flash.
  • Random names
  • Shake effect during grab.
  • Character Specific
    • Andy Bogard
      • Portrait fix.
      • Zaneiken causing instant shutdown.
        • 12022010 -Energycost script property now includes a {parameter} setting. Adding setting.
      • Team attacks
      • Zanei’ Reppa Super
      • Roll, running roll, and rolling attacks.
      • Spider clutch throw needs retuning.
      • Instant shutdown when Cho Reppa Dan KOs opponent.
      • Swept animation.
      • Add dust to CHARGEATTACK animation.
      • Bakushin (“facebomb”) throw, with alternate if opponent is in air.
        • 12012010 – Using wrong voice effect. Visual flash palette incorrect.
    • Ray McDougal
      • Spawn Animations
      • Land sound
        • Covered by land flash
      • Voices.
        • 12012010 – Voices work, but need adapting to latest sound system.
    • Raiden
      • Finish move set.
    • Terry Bogard
      • Finish move set.
      • Rising Tackle causes engine shutdown.
        • 12022010 -Energycost script property now includes a {parameter} setting. Adding setting.
      • Team attacks.
  • Need heavy ground impact flash.
  • Scripts failing after repetitions. Memory leak?
  • Special effects moved to onpain script, need attachment to onfall script as well.
  • Stage Specific
    • Sound Beach
      • Estrada Music item needs longer offscreenkill setting.
      • Sinking boat needs initial sound effect.
      • Panels killed due to lack of offscreenkill setting.
      • Gradual time based sunset should be slower.
      • Boats have too many hit points. Needs destruction animation and prize for doing so.
  • Lasthit x/y/z values are not erased until next real hit. This occasionally messes up throws. Need to add check.
  • Special effects (beams, flame, etc.) are not being zoomed by Z axis on spawn.
  • Proximity hit system needs completing with addition of normal/low/medium/high override support.
  • Add “bounce effect” to screen and obstacles.
  • Flash and dust entities occasionally lock in animation. This is an engine bug; add lifespan as a fail-safe.
  • Finish Taunting system.
    • 12012010 – Complete? Original log is marked finished, but I don’t recall doing so. Need to check.
    • Taunting refers to taunting poses, not special effects on opponents. Taunting pose system is in fact completed and only needs the prerequisite animations for playable characters.
  • CHARGEATTACK animation is canceled by alternate idle system. Possible solution would be script access to chargetime.
  • Some special effects no longer use correct remap after 12062010 update to serial name convention. Palette parameters need updating.
  • Create flash spawn function. Currently flash effects during grappling are spawned by generic spawn function. This works, but is somewhat ungainly and does not support custom flash effects certain defenders may use when taking hits.
    • 12092010 – Created bind0022() function.

Work Log:

  • 12182010 – Moved here.

Notes:

Hit Effects (as of 12012010, new system from GA should be merged)

  1. Defender’s onpain & onfall scripts evaluate incoming attack type and any self immunity. If effect is needed, effect function is called. Note this is done here instead of in the takedamage script to accommodate animation forced binding. While takedamage is running, the defender has not yet assumed reactive animation, and effect entity would be killed instantly upon spawn.
  2. Effect function checks BINDHE variable on defender for a previously bound effect entity.
  3. If an effect entity is found in step 2, and is a different model then what would be spawned in step 5, then it is killed.
  4. If an effect is found, but is the same as what would be spawned in step 5, nothing is done and the effect function exits immediately. This prevents pointless spawning/killing and also maintains smooth animation of the effect.
  5. A new effect entity is spawned and bound to caller.
  6. Effect entity’s onkill script clears the defender’s BINDHE variable.

Projectile handling (from old log and script comments. Probably needs separate article):

Default engine projectiles are extreamly limited. Projectiles are therefore scripted to allow following:

  • Single entity acting as different projectiles.
  • All types (enemy, NPC, player, etc) sharing the same projectile command/entity.
  • Projectiles clash and both are destroyed.
  • Projectiles clash and one simply smashes through the other.
  • Projectiles clash and one overpowers the other but is weakened.
  • Projectile is stopped with normal attack.
  • Projectile is hit by normal attack but is not affected.
  • Stationary projectiles/blasts (ex: Andy’s Geki Hishoken).
  • Any combination of the above.
  1. Projectile is obstacle type. It can take hits but is immune to damage. This allows the themselves projectiles be hit, and have the result scripted based on particular needs.
  2. Animation and map is set at spawn. This means a single entity can be used for as many different projectiles as there are maps available.
  3. Candamage is set at spawn. This allows interchangeability between firing of projectile from player, enemy, npc, etc.
  4. Projectile attack box is “no reflect”, “no pause”, “no flash”, and “no damage”. This means unless a reaction is scripted, a hit detection will have virtually no effect.

Directly from script comments:

/*

Since the defender is an obstacle with MP, then it must be another projectile. To simulate projectile priority, we’ll use MP as a free variable.

When two projectiles collide, both must have 2 or more MP, else they will both be unaffected. Otherwise the one with lower MP looses 1HP for each point

of difference. If MP is equal, both take the equal MP amount as HP damage.

0 MP = Only true obstacles have 0 MP.

1 MP = Intangible and has no effect/does not affect other projectiles.

2+MP = Compare. If equal, both take the full MP as HP damage. Otherwise, looser

takes the difference.

Some examples of how to apply this system:

1. Flame (I) vs. Knife (II):

I   = 1MP, 2HP.

II  = 1MP, 1HP.

I & II collide. Both have 1MP, so neither takes any damage from the other.

In Game: A light knife meets a wave of fire, but the fire is immaterial and

so they simply pass through each other.

2. Hadouken (I) vs. Knife (II):

I   = 2MP, 2HP.

II  = 3MP, 3HP.

I & II collide. II has 1 more MP, so I looses the difference (1HP) and is destroyed. II is unaffected.

In Game: A light knife is no match for the Hadouken and gets

knocked cleanly aside while the Hadouken continues unscathed.

3. Hadouken (I) vs. Hadouken (II):

I   = 3MP, 3HP.

II  = 3MP, 3HP.

I & II collide. MP is equal, so both loose 3HP and are destroyed.

In Game: Classic projectile war. Hadoukens hit and negate each other.

4. Hadouken (I) vs. Shinku Hadouken (II):

I   = 3MP, 3HP.

II  = 3MP, 15HP.

I & II collide. MP is equal so both loose 3HP. I is destroyed, II continues

and may withstand 4 more similar collisions.

In Game: Ryu blasts through several enemy projectils with his Shinku Hadouken. It

plows over 4 lesser projectiles and negates head to head with a 5th.

5. Geki Hishoken (I) vs. Hadouken (II):

I   = 20MP, 1000HP

II  = 3MP,  3HP

I & II collide. I has greater MP by 17, so II looses 17HP and is destroyed. I is unaffected.

In Game: Andy’s short range energy attack is effectivly non negatable and easily stops most normal

projectiles while still hitting anyone nearby.

6. Geki Hishoken (I) vs. Haohshokoken (II):

I   = 15MP, 1000HP

II  = 20MP, 20HP

I & II collide. II has greater MP by 5, so I looses 5HP. I easily withstands the loss. II is unaffected.

In Game: Ryo’s Haohshoken and Andy’s Geki Hishoken hit each other with almost no effect. Both

continue unhindered; Andy is almost certain to be hit, but Ryo could be hit as well if he was

close enough to Andy.

7. Haohshokoken (I) vs. Haohshokoken (II):

I   = 20MP, 20HP

II  = 20MP, 20MP

I & II collide. MP is equal, so both loose 20HP. Both are destroyed.

In Game: One Haohshokoken projectile meets another. While both are capable

of overpowering and eliminating most other projectiles, they negate each other.

*/

Attack type handling:

Hit reactions are set using a combination of script and attack type.

  1. When attack hits but does not kill opponent, the appropriate reaction script (onblock/onpain/onfall) will reset the defender’s reaction based on the Y coordinate of impact (see pain/fall in chart) to visually represent an accurate reaction from hit location (face, gut, feet, etc.).
  2. Y coordinate can be overridden with a hitflag (see didhitscript) if desired.
  3. If the attack KOs defender, attack type determines default fatality animation. The resulting fatality may be modified based on Y coordinate, the stage, character and other conditions. See ondeathscript.
  4. Exceptions are attack 6+. If 6 or 7 cause a fall without killing defender, the defender’s animation is NOT reset. This is because resetting a defender’s fall animation does not change the rise type that will be used, and it would be undesirable to change the actual attack type.
  5. 8+ are for special purposes and not used under normal conditions.
Type Pain Fall Death Block Reset to this type (pain/fall/block) condition: Notes
Default: Normal Normal Normal Normal None (default). Bludgeoning (hand to hand, clubs, sword hilts, etc.)
Attack 2 Middle Collapse Bleed out Middle Hit up to 75% of height. Piercing (daggers, arrows, thrown weapons, etc.)
Attack 3 Low Sweep Bisect Low Hit below 30% of height and standing. Slashing (swords, claws, saw blades, etc.)
Attack 4 High Normal Decapitation High Hit 75%+ of height and attacker is airborne.
Attack 5 Normal Flip over end (thrown) Normal
Attack 6 Spin or flip Background fatality
Attack 7 Spin or flip Mr. T fatality
Attack 8 Normal Slammed on head Normal
Attack 9
Attack 10
Shock Shocked Shock Explode Normal
Burn Burned Immolated Incinerated Normal

Sound List (12012010 – no longer relevant due to numeric based sound system; sounds are in conversion process to new naming convention)

Sound List
Generic Sounds
Sound001 Horse Gallop.
Sound002 Soft thump (jump landing).
Sound003 High beep.
Sound004 Electronic “selected” sound.
Sound005 Echo slide (Hanzou slide).
Sound007 Revenge of Shinobi box break.
Sound008 Lighting strike.
Sound009 Liquid spray.
Sound010 NGBC super move start.
Sound011 Blade launch (Hanzou Rekkozan).
Sound012 Loud “raspy” whoosh sound.
Sound013 Electrocution.
Sound014 “Warp/blade”.
Sound015 Fire burst.
Sound016 WH head butt.
Sound018 WH Body Whoosh.
Sound019 Multiple wiffs.
Sound020 Street Fighter 3 super burst.
Sound023 Water splash.
Sound024 Heavy metal klunk.
Sound025 Hydraulic press/drill.
soun0001 Fatal Fury 1 fall land.
soun0002 Fatal Fury 1 jump.
soun0003 Fatal Fury 1 coin.
soun0004 Fatal Fury 1 hit.
soun0005 BOR bike.
soun0006 Fatal Fury 1 block.
soun0007 SOR “gulp” food pick up.
soun0008 SOR indirect hit.
soun0009 Fatal Fury 1 confirmation.
soun0010 World Heroes jump land.
soun0011 WH choke.
soun0012 Bone snap.
soun0013 SF3 Hard ground impact.
soun0014 World Heroes’ hard ground impact.
soun0015 Real Bout maximum power strike.
soun0016 Real Bout multi pitch power up.
soun0017 KOF “catch”/hand clasp.
Assorted Voices
Voic001 DD2 Burnov laugh.
Voic002 DD2 evil double laugh.
Voic003 Female long alto yell (Kasumi high jump).
Voic004 Female short alto yell (Kasumi short jump).
Voic005 Canine growl 1.
Voic006 Canine growl 2.
Voic007 Canine bark 1.
Voic008 Canine howl 1.
Voic009 Horse neigh1.
Voic010 Horse neigh 2.
Voic011 Canine howl 2.
Voic012 Horse neigh 3.
Voic013 Joe Muashi yell with flame burst sound.
Voic035 KOF Yamazaki Snake Hand
Voic036 DD2 Abore Shoulder attack.
Voic037 DD2 Abobo throw.
Voic038 DD2 Ohara shoulder attack.
Voic039 Unused
Voic040 DD1 Abobo throw.
Voic041 Canine howl 3.
Voic042 Shadow Dancer spell scream.
Voic043 Shadow Dancer Jump yell.
Voic044 Shinobi3 Joe run attack.
Voic045 Shinobi3 Joe death kick.
Voic046 Shadow Dancer fire spell chanting with detonation sound.
Voic047 Shadow Dancer wind spell chanting.
Voic048 Shadow Dancer totem spell chanting.
Voic049 Shadow Dancer spell scream with wind and tornado siren sound.
Voic050 Shadow Dancer Yamoto poof, bark, and charge sound.
Voic051 DD2 Chin jump kick.
Voic052 DD2 Chin attack.
Voic053 SO2 Shiva jump attack/throw.
Voic054 SO2 Ninja throw.
Voic055 Dragon roar (Hanzou Ko ryu ha).
Voic056 DD2 Unknown attack.
Voic057 Female soprano scream.
Voic058 Female pain grunt.
Voic059 Vendetta male burned.
Voic060 Vendetta male burned with incineration sound.
Voic061 Male choke.
Voic062 Alto female scream.
Voic063 SOR2 male death 1.
Voic064 SOR2 male death 2.
Voic065 SOR2 Axel death.
Voic066 SOR2 female death.
Voic067 SOR3 male death 1.
Voic068 SOR3 male boss death.
Voic069 SOR2 Max death.
Voic070 Male scream with cut/bisect sound.
Voic071 SOR2 Skate death.
Voic072 Shadow Dancer boss death.
Voic073 Vendetta male falling sound (“owww!!”).
Voic074 Vendetta boss death.
Voic075 Ninja Spirit PC death.
Voic076 Male scream with dog mauling sound.
Voic077 DD2 Burnov death.
Voic078 DD2 Chin death.
Voic079 Male multi-pitch scream.
Voic095 Male “Tuhh!!”
Voic096 Male “Ha!”
Voic097 Male “Humph!”
Voic098 Male “Uegh!”
Voic099 Male “Ummph!”
Voic100 Male “Yeeah!”
Andy Bogard
vand0001 “Seh!”
vand0002 “Huah!”
vand0003 Light exhale
vand0004 “Gah” pain.
vand0005 “Mrah” pain.
vand0006 “Mowah” pain.
vand0007 “Baby cry” pain.
vand0008 Light attack
vand0009 “Shoken!”
vand0010 “Geki”
vand0011 “Shoooooken!!”
vand0012 “Ku ha dan!”
vand0013 “Shoryudan!”
vand0014 “Zaneiken!”
vand0015 Super finish scream.
vand0016 “Humph”
vand0017 “Yoshi!”
vand0018 Exhale.
vand0019 “Sayaaa!”
vand0020 “Cho reppa dan!”
vand0021 Super finish scream 2.
vand0022 “Shetz!”
vand0023 “Namusan”
vand0024 “Ienoash”
vand0025 Prelude to Tung match.
vand0026 “Tung Sensei!”
vand0027 “Zengu Ikkyu!”
vand0028 “Geese!”
vand0029 “Sono tadoka.”
vand0030 Short growl.
vand0031 “Arryaaah!”
vand0032 “Siiiiiiii!”
vand0033 Wild Ambition overdrive initial attack.
vand0034 “Shrureahh!” ***ERROR** Cannot be exported.
vand0035 “Zanei Reppa!”
vand0036 “Hutz!”
vand0037 “Geki!”
vand0038 “Juhn!”
vand0039 “Metsu!”
vand0040 “Son!”
vand0041 “Baaak!”
vand0042 “Meeetsu!”
vand0043 KO 2 (“uhph.. gomen!”).
vand0044 “Oniotaaaah!”
vand0045 “Shuryahhh!”
vand0034 “Shrureahh!”
sand0001 Hishoken
sand0002 Geki Hishoken
sand0003 Special slash/whoosh
sand0004
sand0005 Fire burst
sand0006 Long whoosh
sand0007 Strong fire burst
sand0008 Cho Reppa Dan burst.
Hanzou (WH)
Voic022 WH Hanzou light attack.
Voic023 WH Hanzou med. attack.
Voic024 WH Hanzou heavy attack.
Voic025 WH Hanzou “Nin!”
Voic026 WH Hanzou “Victory.”
Voic027 WH Hanzou “Double Rekkozan!”
Voic028 WH Hanzou “Koh Ryu Ha!”
Voic029 WH Hanzou “Lariat!”
Voic030 WH Hanzou “Slash of Shimmering!”
Voic031 WH Hanzou ‘Ninpo Korin Kazan!”
Voic032 WH Hanzou “Rekkozan!”
Voic033 WH Hanzou KO.
Voic034 WH Hanzou “Come on!”
Kasumi (DOA)
Voic014 Attack 1.
Voic015 Attack 2.
Voic016 Attack 3 (waterwheel kick).
Voic017 Attack 4.
Voic018 Attack 5 (Hard throw).
Voic019 Attack 6.
Voic020 “I have no time to spare.”
Voic021 “Farewell.”
Muscle Power
Voic080 WH Muscle Power “Number one!”
Voic081 WH Muscle Power quick grunt.
Voic082 WH Muscle Power “Dahhh!!”
Voic083 WH Muscle Power “Gwaoow!”
Voic084 WH Muscle Power “Hungah!”
Voic085 WH Muscle Power pain 1.
Voic086 WH Muscle Power Jab.
Voic087 WH Muscle Power KO.
Voic088 WH Muscle Power “Number onnnnne!”
Voic089 WH Muscle Power “Hoawwww!”
Voic090 WH Muscle Power medium grunt.
Voic091 WH Muscle Power pain 2.
Voic092 Real American sound clip.
Raiden (Big Bear)
vrai0001 “I’ll dance on your grave!”
vrai0002 “Say your prayers wimp!”
vrai0003 “You’re dead meat!”
vrai0004 “Come on!”
vrai0005 “Hum!”
vrai0006 “Hyeee!”
vrai0007 “Hey!”
vrai0008 “Jurreahh!”
vrai0009 “Jeeh!”
vrai0010 “Oooowahhhooo!”
vrai0011 “Nwaaoo!”
vrai0012 “Huaah!”
vrai0013 “Bomba!
vrai0014 “Ready…”
vrai0015 “Go!”
vrai0016 “Dropkick!”
vrai0017 “G…End!”
vrai0018 “I am Raiden!”
vrai0019 “Ichimon!”
vrai0020 “Heh hahahaha!”
vrai0021 “Gwah!”
vrai0022 “Gwhaaaa!”
vrai0023 KO.
Rainbow Mika
vmik0001 “Guh!”
vmik0002 “Uggh!”
vmik0003 “Nuuuh!”
vmik0004 “Euuaggh!”
vmik0005 KO with echo.
vmik0006 KO.
vmik0007 “Kuu!”
vmik0008 “Huh!”
vmik0009 “Uuuah!”
vmik0010 “Bombaaah!”
vmik0011 “Attack!”
vmik0012 “Crush!”
vmik0013 “Victory!”
vmik0014 “Igamaaah!”
vmik0015 “Morataaa!”
vmik0016 “Kimatah!”
vmik0017 “Uryou!’
vmik0018 “Shaah!”
vmik0019 “Oraah!”
vmik0020 “Yah!”
vmik0021 “Kuu!”
vmik0022 “Kona!”
vmik0023 “Rainbow!”
vmik0024 “Ikuze”
vmik0025 Happy bounce.
vmik0026 “Doshta.”
Ray McDougal
vray0001 “DDT!”
vray0002 KO.
vray0003 “Wheel Kick!”
vray0004 “All right!”
Vray0005 “Yeah!”
Retsu
Voic093 SF Retsu Grunt
Voic094 SF Retsu Grunt 2
Ryo Sakazaki
Voic101 Ryo Sakazaki attack 1 (heavy).
Voic102 Ryo Sakazaki “Zanretsuken!”
Voic103 Ryo Sakazaki “Hoah Sho Ko Ken!” (low pitched)
Voic104 Ryo Sakazaki “Raijinsetsu!”
Voic105 Ryo Sakazaki “Hoah Sho Ko Ken!” (normal pitch)
Voic106 Ryo Sakazaki attack 2 (light).
Voic107 Ryo Sakazaki attack 3 (light).
Voic108 Ryo Sakazaki pain 1.
Voic109 Ryo Sakazaki “Ko Oh Ken!”
Voic110 Ryo Sakazaki attack 4 (Kohou).
Voic111 Ryo Sakazaki attack 5 (heavy).
Voic112 Ryo Sakazaki “Ora! ora! ora! ora! ora!”
Voic113 Ryo Sakazaki “Ichi!”
Voic114 Ryo Sakazaki “Hissestu”
Voic115 Ryo Sakazaki attack 5 (heavy).
Voic116 Ryo Sakazaki “Ora! ora!”
Voic117 Ryo Sakazaki “Osu!!”
Voic118 Ryo Sakazaki “Hien Shippu kakyu!”
Voic119 Ryo Sakazaki charging.
Voic120 Ryo Sakazaki KO.
Sho (Breakers Revenge)
vsho0001 Jab.
vsho0002 “Mmpuh!”
vsho0003 “Shwop!”
vsho0004 “Hah!”
vsho0005 “Shoo!”
vsho0006 “Eyahh!”
vsho0007 “Hup!”
vsho0008 “Whuyeah!”
Vsho0009 “YEAAHHH!”
vsho0010 “Kureaaah!”
Terry Bogard
vter0001 FF2 KO.
vter0002 CVS KO.
vter0003 “Uuh!”
vter0004 “Owughh!”
vter0005 “Hey! Come on, come on!”
vter0006 “Geese!”
vter0007 “Hey you!”
vter0008 “Okaaay!”
vter0009 “Burn Knuckle!”
vter0010 “Crack shoot!”
vter0011 “Rising tackle!”
vter0012 “Power wave!”
vter0013 “Power dunk!”
vter0014 “Power…!”
vter0015 “Geyser!”
vter0016 “Are you OK?”
vter0017 “Buster wolf!”
vter0018 “Hah!”
vter0019 “Humph!”
vter0020 “Heyyy!”
vter0021 “Agggh!”
Tung Fu Rue
vtun0001 Roid rage.
Generic Female
voif0001 Long KO scream.
Generic Male
voim0001 High pitched “Ewwluah!” KO.
voim0002 Midtone burst KO.
voim0003 Vendetta on fire scream.
voim0004 SOR3 male KO scream.
voim0005 SOR2 male KO scream 1.
voim0006 SOR2 male KO scream 2 (from sword of Vermillion).
voim0007 Ninja spirit PC death.
voim0008 Long large male KO.
voim0009 Large male “erroooooo!”
voim0010 Quick “Ya!”
voim0011 Punisher male KO 1
voim0012 Punisher male KO 2 (high pitched OW!)
voim0013 Punisher male KO 3 (“yeaahhhh!”)
voim0014 AVP soldier KO 1.
voim0015 AVP soldier KO 2.
voim0016 Fatal Fury 1 “GO!”
voim0017 MK Pain 1.
voim0018 MK male long fall 1.
voim0019 MK male long fall 2.
Generic Voice (robot, alien, etc)
voig0001 High pitch alien screech.
voig0002 Crowd cheer.
voig0003 MK crowd in awe.

Reserved Maps

Use Map
Default 0
Death 1
Burn 2
Shock 3
Freeze 4
Poison 5
Reserved 6 – 10
Color selects 11+

Reserved icons

Icon ID
Default icon0001
Death icon0002
Pain icon0003
Acquire icon0004
Weapon icon0005

Variants List

Listing of known global variants used in Golden Axe Remake. Many of these are holdovers from Utunnels original scripts and can be eliminated or replaced with value retrieval.

Note this is not an accurate count, as some name strings are created by inserting a relevant index to simulate an array. Binding, shadow trails, and auxiliary damage system all operate in this manor. The door spawn system appears to use a similar technique, but it is a carry over from Utunnels coding that I have not yet viewed in detail. I would also like to convert the names to Hungarian Notation, but for now I think best to leave them be.

  1. corpse
  2. adder
  3. snake
  4. inscreen
  5. a_npc
  6. p
  7. dummy
  8. al_npc
  9. wake
  10. smallexp_count
  11. largeexp_count
  12. bbdelay
  13. g_npc
  14. “player”+index+”mp” (index = player index)
  15. darkone
  16. sleep
  17. levelminz
  18. levelmaxz
  19. t_npc
  20. doorindex
  21. “doortimer”+ind (ind = door index. Unknown how index is assigned).
  22. “doorspawn”+index
  23. “dooralias”+index
  24. “doormap”+index
  25. release
  26. pal
  27. maxpal
  28. sdx
  29. sdz
  30. addtime
  31. darkskeleton
  32. “trailer”+k+”.s”
  33. “trailer”+k+”.x”
  34. “trailer”+k+”.z”
  35. “trailer”+k+”.a”
  36. “trailer”+k+”.f”
  37. “trailer”+k+”.c”
  38. “trailer”+k+”.color”
  39. “trailer”+k+”.alpha”
  40. “trailer”+k+”.m”
  41. pot0
  42. pot1
  43. runanimal
  44. bbdelay
  45. countdown
  46. cstring
  47. player0mp
  48. player1mp
  49. player2mp
  50. “pot”+(c%100)
  51. doortimer1
  52. doorspawn1
  53. doormap1
  54. doortimer2
  55. doorspawn2
  56. dooralias1
  57. dooralias2
  58. doormap2
  59. switch
  60. etime
  61. time1
  62. time2
  63. vSelf + “.bind.” + iIndex (grappling binds)
  64. “hit”+i+”.a”
  65. “hit”+i+”.c”
  66. “hit”+i+”.t”
  67. “hit”+i+”.d”
  68. “hit”+i+”.k”
  69. “hit”+i+”.o”
  70. debug_bind0010_iMode
  71. debug_bind0010_iIndex
  72. debug_bind0010_iPose
  73. debug_bind0010_iX
  74. debug_bind0010_iY
  75. debug_bind0010_iZ
  76. debug_bind0010_iDir
  77. debug_bind0010_iFrame
  78. debug_bind0010_Rebind