Explanation of How I Did My ABS:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
I am getting tired of all these people constantly asking me about the ABS for my unfinished
RM2K project. So, I have decided to assemble this bare bones explanation of how it works so
that you too may explore RM2K fully and rip it off as best you can.





First Off:
ŻŻŻŻŻŻŻŻŻ
The system is COMPLICATED, and it gets MORE complicated the more ideas I think up and
impliment. There are 441 common events that control every aspect of my project, THUS FAR. There
are common events for the weapon fire and control, variable setting and control, managing Max's
sprite for when he attacks/uses magic, detecting the menu press/item & magic use, showing the
HUD, managing magic regen, managing the menu/freezing enemies when the menu is up, damage
display for when you/the enemy is hit, managing the custom level system, managing the custom
inventory, managing the three status effects, showing the enemy HP bar, showing the magic
range when a spell is equipped, showing the level up text when a level occurs, managing the
shop system, managing map transitions, detecting and managing climbing, cutscene skipping,
managing the save point system & custom save information, managing treasure chests, the game
clock, managing the achievements you can get in the game, showing the EXP and Lucre bar when
you kill an enemy, the ice platforming events for walking over water, managing the follower
script for when you have people tailing you around, spawning enemies, managing enemy stats &
deaths, playing sound effects, enemy commands, enemy physical and magical damage, detecting
player death, managing enemy dropped items, and managing status effects on enemies.

Now, why did I just list off all the different groups of common events I have? Simple. To
emphasize this isn't some copy/paste task, or something to be taken lightly. This WILL take
you a shitton of time to complete if you do decide to copy it.

Let us begin.





How the Weapon Works:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
The weapon is an event that is on EVERY map. I have a base map with 80 events on it I
copy/paste when I want to create a new map. Each event is used in the system, and is controlled
by common events. Since they're controlled by common events, they have to be the same event ID
across ALL maps. Now. The way the weapon works is with a common event set to parallel process
so that I can use an Enter Password to detect if the player has pushed the attack button. If
they have, and all other factors add up (the weapon isn't currently firing, the weapon is
enabled to fire on that specific map, the weapon isn't going through it's "cooldown" phase
after it was fired last, the player isn't currently walking on an ice platform, the player
isn't climbing, the player isn't in the menu, the player isn't moving, the player isn't
currently using magic, the player isn't in a shop & the player has a directional equipped),
then the weapon event sets it's position at the player's position, changes it's graphic to
match the currently equipped weapon, and moves along a specific path according to the
directional equipped, and the direction the player is facing. As an example, the first
directional you get, facing up, goes along the path of;

<>Start Slip Through
<>Up
<>Up
<>Up
<>Down
<>Down
<>Down
<>Change graphic (to a blank one)
<>Stop Slip Through
<>Switch [Weapon cooldown trigger] ON

There are 4 directions for each directional, all hardcoded to follow a specific path from the
player. That is 32 hardcoded paths for the weapon to follow. Now, the detect fire parallel
process also detects if the cooldown has triggered. If it has, then it turns off the weapon
firing trigger, waits 0.2 secs, and turns off the cooldown. Since we've already established
that the weapon won't fire unless the cooldown's off, the waiting before turning it off
satisfies the basic logic of waiting for the cooldown. :-p

Now, that is only ONE piece of the puzzle. So what if we move an event? It's not going to know
how to hit an enemy. It's just going to move along it's predefined path. That's where a second
parallel process comes in, which constantly sets variables to the weapon's current position,
among other variables it updates every frame. We use that in the enemy logic to see if the
weapon position is the same as the enemy position, and fire off an enemy damaged common event
if so.

That's it for how it fires. The meat of how the weapon works is 100% in the enemy logic, and
NOT in the weapon itself. The weapon firing is just what gets the weapon on the map to be
detected.





How the Enemies Work:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
The way the enemies work is entirely by common events. The sprites are 20 events on every map,
with 20 additional events for enemy item drops. Each of those enemies have 12 switches and 29
variables to control the AI. Each AI is independently controlled by a common event specifically
coded to work with that enemy. This means for each map, there can be a maximum of 20 enemies.
What this also means is that since RM2K REALLY sucks for object oriented programming (or any
programming, really), AI can't be controlled by some universal set of rules. Each enemy event
is copy/pasted with all of the relevant information changed to reflect that specific enemy
number. BEYOND that, there's 20 events for each enemy dropped item, 20 events for each status
effect affliction, removal, and control (of which there are 3 status effects, making 180
total), 20 events to spawn the enemy, 40 events to control damage they have done to them (both
physical and magical), and 20 events to control their death. Luckily I was able to work setting
the stats (HP, MP, Str, etc, etc [17 total]) into one variable based on the type of enemy
being spawned.


The commands that power the enemies are in 3 groups; Position & Hit Detection, Movement, and
Actions. The position and hit detection set the enemy's range from the player (enemy x minus
player x [absolute value if < 0] plus enemy y minus player y [same if < 0]), counts down a hit
counter that triggers when the enemy does an action, to give the enemy a cooldown before it is
able to attack again, and a movement counter so that the enemies can have variable speeds, and
sees if the enemy position and weapon position match (therefore the weapon hit the enemy) to
call the "damaged" event for that enemy. The one thing this section does NOT do is detect magic
damage, which is calculated when the player casts magic, and not every frame.

The Movement section has a big fork for each enemy (so basicly "if enemy ID is 1 [a rat], then
do the movement protocols for the rat enemy - if not, move on"), since each enemy has a
different movement speed. So, it's basicly "Can the enemy move?" Yes: [do event movement
commands] - No: [count down the pause variable, skip moving]. Now, some enemies have the same
movement all the time (rats, bats), so it doesn't matter. But the rest of the enemies move
based on how close they are to you, or other specific things. Since I set the range in the
position and hit detection part, I can check how close the enemy is, and run one set of
movement commands if they are close to you, or another if they are not. As an example, the
slime enemies move in a random direction slowly unless they are within 4 squares of you, at
which point they start moving towards you fast.

The Actions section is where everything happens. The "logic" behind the AI. I can't
specifically go into detail about how it works, except to give you a few actual examples. The
Rats, the very first enemy you fight, have a simple logic;

[Is the enemy within 1 square of me?]
  : [Is my attack available?]
      <>Set a random variable from 1 to 100.
      [Is this variable less than or equal to 4?]
        <>Call damage event.
      [END]
    [END]
  [END]

This basicly gives the rat a 1 out of 25 chance (4%) that it will attack the player when they
are within 1 square of it, every frame (I am not entirely sure how many frames per second there
are, but I think it's 20). This basicly gives the idea that the rat doesn't REALLY want to
attack you, but it will if you get close. So, altogether with the movement, the rat wanders
around aimlessly, and if you stand next to it, it might get upset and bite you. Tah dah! Enemy
AI. :-D

As you can imagine, higher logic such as magic, and MP usage, and other effects are entirely
possible. The bat uses MP to cast blood suck, which takes damage off you and restores the bat
slightly (used very rarely). A fork controls it so it doesn't happen if the bat doesn't have
the MP to do so. The wolf uses Howl, which increases his Str by 2 each time he uses it.
Basicly anything you want.


Now how the enemies are spawned are how any basic "function" works when using RM2K; in normal
programming, functions take on parameters, and do stuff with them to get some end result. In
RM2K, you set those parameters by setting variables before the event is called. Thus, I have it
setup so all I do is set the enemy ID (which controls which enemy logic and graphic it'll use),
the X and Y of it, and then call the spawn function. The spawn function runs through all the
variables for each enemy, checks which ones are dead/not being used, and calls that specific
enemy's spawn event. The way I use that, is an auto-run event that I put on whatever map I
want the enemies on that uses a basic "ENEMIES SPAWNED?" switch to spawn them, then stop itself
once it has. Complicated mess that I simplified for myself, basicly. :-)


Now, the enemy drops. As I said before, each enemy event has a corresponding enemy event that
works with it as it's drop (or, conceivably, anything else I can program in, like, as an idea;
a knife thrown by the enemy acting as it's graphic). Each enemy has an item it will drop, and
the percentage it will drop that item. Of course, enemies can have NO drop as well. When the
enemy dies, a random variable is set, and if it's at or below the drop percentage, it drops!





How the Menu Works:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Since there are only 2 buttons in RM2K that can be detected, I use one for firing the weapon,
and one for using an item or opening the menu. If you hold the button down for 2 seconds, it
opens the menu. If you just press it, it uses the equipped item. If you have magic equipped
instead, pressing it shows the area of effect the magic will have, and holding it for 1
second "charges" the magic to be used, and fires it off. Because of this, I show pictures in
the bottom left corner to indicate what will happen if you release the button, from the menu,
to an item, to a magic icon.

How it specifically works to call up the menu and such is it is a parallel event that detects
if you're holding the button, and if you are, increases a variable. It then displays the icon
or target zone or whatever depending on the value of that variable. If at anytime you release
the button, the script checks how long you held it for (based on the value of the variable),
and casts the magic, uses the item, or opens the menu.

Now, the menu itself is NOT on another map screen like in other CMS's I've seen. Instead, it
is all done on the same map, working within the limitations of the 20 picture limit. Because
it's all done on the same map, I have an event that triggers when the map is open that is
nothing but an auto-run with a 0.0 wait, basicly freezing the entire game just to do the menu
functions. That does NOT stop parallel events though, such as enemies. For that, enemies have
built in logic to check if the menu is open, and simply bypass processing their actions if so.
The menu functions, and picture displays of course rely on the switches being set if it's open
as well.


As for how the menu itself works, it's just variables that store what "position" the cursor is
at, and giant forks to control where to move it, or what to do based on that. I really can't
simplify it further. The main menu position controls what category you're on - the sub menu
position controls what part of the main menu you're on - the pop-up position controls which
pop-up option you're on if you've selected an item, and the final confirm position controls if
you're on yes or no for a drop/use confirm. So, if you're at main menu position 0, you're in
the Items menu. If the sub menu position is anything other than 0, you're actually inside that
menu. If not, then the up/down keys control which main menu you're on instead of navigation
within the Items menu. If you then select an item, it brings up the pop-up position menu,
with controls specifically if you're in that. Then further if you're in a yes/no dialog. If you
need any further instructions on how that is setup, then you need to mess around with RM2K
longer, and teach yourself a thing or two.

One thing to note is that I have 4 specific "display number" functions that will display a
3-digit number at a specific location. Let me tell you that programming those was the best
thing I could have done. I use them in all the menus, and on the HUD for displaying HP/MP. They
basicly all do the same thing, which is split the number into hundreds, tens, and ones, and
displays pictures based on them, but each one displays them using different Pictures numbers.
The first using 2, 3, 4, the next using 5, 6, 7, and so on.

In case "How do I split a number into it's separate digits?" is one of your questions, it's
just simple math. You take the number, and divide it by the higher tens for that digit. So
for 999, take that and divide it by 100. You get 9. Bingo, your first digit. To get the middle,
simply modular divide the number by the first digit's tens, so, 999 % 100, which leaves
a remainder of however many is below that. In this case, 999 divided by 100 is 9 with
the remainder being 99. So, now we take that 99, and do the same thing with that tens we want.
So, divide it by 10. Now we have our second digit. In this case, the number is 999, so simply
modular dividing it by 10 will give us the remaining digit without the need to divide it once
again.

As an example, in actual RM2K code;

<>Variable Ch:[0003:Third Digit] Set, 123
<>Variable Ch:[0001:First Digit] Set, Var.[0003]val.
<>Variable Ch:[0001:First Digit] / , 100
<>Variable Ch:[0002:Second Digit] Set, Var.[0003]val.
<>Variable Ch:[0002:Second Digit] Mod , 100
<>Variable Ch:[0002:Second Digit] / , 10
<>Variable Ch:[0003:Third Digit] Mod , 10

Now variable 0001 = the first digit, variable 0002 = the second digit, and variable 0003 = the
third digit. You can deconstruct a 6 digit number the same way;

<>Variable Ch:[0006:Sixth Digit] Set, 987654
<>Variable Ch:[0001:First Digit] Set, Var.[0006]val.
<>Variable Ch:[0001:First Digit] / , 100000
<>Variable Ch:[0002:Second Digit] Set, Var.[0006]val.
<>Variable Ch:[0002:Second Digit] Mod , 100000
<>Variable Ch:[0002:Second Digit] / , 10000
<>Variable Ch:[0003:Third Digit] Set, Var.[0006]val.
<>Variable Ch:[0003:Third Digit] Mod , 10000
<>Variable Ch:[0003:Third Digit] / , 1000
<>Variable Ch:[0004:Fourth Digit] Set, Var.[0006]val.
<>Variable Ch:[0004:Fourth Digit] Mod , 1000
<>Variable Ch:[0004:Fourth Digit] / , 100
<>Variable Ch:[0005:Fifth Digit] Set, Var.[0006]val.
<>Variable Ch:[0005:Fifth Digit] Mod , 100
<>Variable Ch:[0005:Fifth Digit] / , 10
<>Variable Ch:[0006:Sixth Digit] Mod , 10

And you should be able to see how that works.





How Magic Works:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Magic is one of the simplest things in my game. When magic is cast, if it's a curing spell,
then it heals for however much it's supposed to, or removes whatever statuses it's supposed to.
If it's a damaging spell, then it calculates it's damage based on the element of the spell, and
the element of the enemy (same element = 0 damage, strong vs = 150%, weak vs = 50%), checks all
20 enemies to see if they're alive, and within the spell's range, and then calls the magic
damage calculation function and enemy magical damage function if so. If the enemy is not in
range (as set in the individual enemy commands mentioned above), it skips them.

When a spell is cast, the player is frozen for a bit using the same method used for freezing
events as used in the menu system. They also can't attack, climb, or do whatever other actions
they normally could, since when magic is being used, a switch is on that other events can check
and cancel whatever commands they would normally do if magic wasn't being cast.

Also, the main character's graphic changes when magic is being cast, and along with the graphic
for when he is throwing a weapon, that is all controlled by another parallel process that
constantly checks for the switches that are triggered when these things happen and changes the
sprites as necessary. They also change based on what armor the player is wearing, so it's a
big fork for which armor and which stance to display. :-)





How the Shop Works:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
The shop is the only feature that takes place on another map, instead of all within the same
one the player is on. Because of this, when the shop is called, the player's current X, Y, Map,
BGM and direction is saved to go back to it when they're done. The REASON why the shop is
on another map is because of the numbers needed to display the Lucre the player has, as well
as the selling/buying price. To make it all on the same map as the menu would mean coding a
giant new menu-like system for it. And I wanted to be a little bit lazier with the shop. :-D

There's not really much to say, except it's basicly the same as the menu with it's menu and
sub positions, pop-up positions, etc. The way it works in the end is setting variables to item
IDs and calling the shop menu, since all the items in the game all have their own IDs for what
they are, and the shop and menu use these to display information about it (a picture), as well
as to determine their use when used/equipped/etc.





How the Level, Stats & Damage Calcs Work:
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
The level system is theoretically limitless, as the limit is so high that there's no easy way
to reach max. The max level is 999, however, with each level giving the player 4 points to
use to increase their stats. Each stat maxes at 999, and the HP and MP stats increase by 2 for
each point. These specifics are NOT concrete, as balancing issues may make me change it all
later. But, if you go from starting stats - 40 HP/MP, and 14 Str/Def/Mag/Wis, at level 999,
you will still not have gained enough points to max out every stat. You'd be short by 908
points. :-D

How the EXP system works, is based on what level you're currently trying to get to. Right now
(and I plan on keeping it), once you hit level 100, the EXP needed for the next level maxes at
99,999, and every additional level past that requires that much EXP. However, the game is short
enough that I don't plan on the player ever even reaching that far. Again, balancing issues
might change all of that. Already the system can easily be overpowered early on.

Anyway, the formula I use for calculating EXP needed for the next level is as such;

x = ( [current level] * ( [current level] * 100 / 31 ) / 100 )
x = x * x
[new EXP] = ( [current level] + [current level] + x + 20 )

So, at level 1, the EXP needed is 22, 24 at 2, 26 at 3, 28, 30, 33, 35, 40, 42, 49 at 10 to
99 at 15, 204 at 20, 470 at 25, 864 at 30, and so on to 99443 at 99, and 99999 at 100.

This is specific EXP needed, which resets when you gain a level. So after you gain to level 2,
you then need 24 more EXP to get to level 3, and so on.


Now onto how stats affect damage, the calculations involved, how they affect magic, etc. First
off, physical damage is affected by Str and Def. For SOME reason the most common thing I am
asked is "how do I calculate damage and stuff?" - the simple (and usually scourned) answer is;
there is no universal formula to figure that out! I just messed around until the formula I used
worked in a way I liked. I didn't spend years researching it, I just threw something together
until it started calculating out the damage I'd expect from the stats at specific points. It
really is something you have to figure out yourself. Or, you can use the RM2K damage
calculations which can be found in the manual. Just search for the "combat calculation" page,
which is under the "Material Data" category in the index.

However, as I said, physical damage is affected by the person attacking's Str, and the person
defending's Def, regardless of if it's a monster or player. It's then affected by a random
chance between 90% and 110% of the calculated damage, and finally affected by the element the
player is (equipped boost), and the element the enemy is. So the basic calculation is;

[damage] = ( [Strength] * 80 / 100 ) - ( [Defense] * 40 / 100 )

If the calculation is less than 0, it's minimizes at 0, and if it's higher than 999, it maxes
at 999.


Now, Magic works the same way calculation wise, but each spell has a power that affects the
actual damage done. The first level spells do 80% of the normal damage, while the second level
spells do 200% of the normal damage. The non-elemental spells, however, do 120% damage for the
first level, and 300% for the second level. Of course, the magic damage is based off of Magic
instead of Strength, and Wisdom instead of Defense. The same elemental rules apply, in that
the same element = no damage, strong vs = 150% damage, and weak vs = 50% damage.





Conclusion:
ŻŻŻŻŻŻŻŻŻŻ
Hopefully now you won't need to ask me a bunch of questions about how the system works. I am
NOT going to write an actual step-by-step tutorial on how I did it, as that is absurd. The
systems I use were not made to be generic. They are very specific to my game and my designs.
If/when I release the game, you are more than welcome to look at the code I used and try to
copy it however you want, but I guarantee that it will not be entirely useful to you.

So, good luck with your own complicated systems.