Showing posts with label resources. Show all posts
Showing posts with label resources. Show all posts

Saturday, March 5, 2016

My First Serious Plugin - Peep Skill (MV)

(Download at bottom of post).

I'm happy to report that I've pretty much gotten the hang of scripting in RPG Maker MV. Doesn't mean that any problem that crops up will be easy to solve, or that I will be able to solve any and all problems I encounter (especially the more complex ones, although the fact that there is a nice community of even better scripters than I working on commonly desired features helps a lot), but it means my abilities to get what I want out of this program (and my confidence in being able to do so) are stronger than ever.

I'm fairly confident coding in JavaScript by now - which isn't to say that I know the language back and forth, but I know the basic syntax, and figuring out how to do specific things is as easy as typing a question into Google and surveying the answers. The hardest part remains diving into the - as I said - tens of thousands of lines of code that make up RPG Maker MV, and a) finding the code you need to modify to get the results you want and/or b) trying to understand not so much the JavaScript, but how the actual program RPG Maker has been designed to function.

On the other hand, I haven't had this much of an opportunity to program since I finished my schooling (the barrier of learning a foreign language is surprisingly intimidating, even if most of the logic behind computer programming is the same no matter what language you're using), and I had forgotten just how much fun it is to code (barring all those frustrating times that your code fails, and you assume you've screwed up the logic, when it so frequently ends up being nothing more than a parenthesis or a semicolon out of place). It's the thrill of problem-solving. Some people like to fix things with their hands. Computer programming is the same, except you're using your mind - and that's always been my strongest tool.

So over a couple of weeks I pretty much absorbed myself into programming, and worked out a nice little plugin that I'd like to offer up to the community. It started out with me trying to figure out how to create an enemy that mirrors the player's stats, no matter what they happen to be when the battle is initiated. I couldn't find a way to preload those stats into the enemy's properties in the database, so I opted to run an event at the start of the battle that reads the player's current stats and then feeds them into the enemy (to do this, I made all the enemy's base stats 1, and then added the player's stats minus 1 on top of them).

It was an adequate solution, but in the process of working on it, I wanted to have a nice way to read the enemy's stats in-game to make sure they were what I wanted (and expected) them to be. So I embarked on creating something of a skill akin to the Peep command in Final Fantasy IV (since, to my knowledge, RPG Maker comes with nothing like it by default). It's probably come up in other places (although that's the first one that came to my mind), but basically it's a skill you can use in battle to investigate an enemy's stats (HP, MP, etc.) as well as its strengths and weaknesses (e.g., strong against fire, weak against poison, immune to sleep).

So this plugin started out very basic and functional, but as I went along, I realized how well it presented itself to user customization, and I decided to use it as an opportunity to learn a lot of valuable techniques in scripting for MV - like proper aliasing, utilization of plugin parameters, as well as plugin commands (although I finally opted for notetag functionality over plugin commands, in order to bypass the extraneous step of having to call a common event). It started out as pretty much one big function that did everything I needed it to do, but then I decided to split it up and write it in the format of the rest of RPG Maker's code, which is very modular and method-based.

The end result is a fair-sized monster of a thing (by my standards, that is - it's tiny next to some of those professional-level plugins you can find). And even though I still consider myself to be a beginner - or beginner-intermediate, at best - scripter, it's something I'm pretty proud of. I can't claim that it will be compatible with any and all other plugins, but I don't anticipate it having any significant problems (most of it is contained within a brand new class that I've written). So, if you get a chance to try it out, please tell me how you like it, and if there are any bugs you encounter.

My plugin in action.

Now, let me briefly describe what my Peep Skill plugin can do. (The plugin itself is fully annotated, so you should be able to figure out how to work it just by reading the description at the top of the file, or through RPG Maker's Plugin Manager). After the plugin is installed, all you gotta do to use it is type <peep> alone or with arguments (see the file for details) in the note box of the skill or item that you want to execute the peep skill when used in battle. When you use it, if successful, it will display on screen a list of the target enemy's properties. You can fully customize which properties are displayed and in what order, choosing from the following options:

Enemy's Name
Current and Max HP and MP
Basic Parameters (Attack, Defense, Magic Attack, Magic Defense, Agility, Luck)
Current States applied (e.g., sleep, poison, mute)
Current Buffs (attack up, agility down, etc.)
Elemental and State strengths, weaknesses, and immunities (all according to the enemy's traits listed in the Database)
Enemy's worth in both experience and gold
Potential drops (with probabilities)

As I said, you can choose any or all of these to be displayed, and you can even format them by adding in blank lines. The plugin is designed to wrap lines that exceed the length of the text box (you have to input the max character limit if you're not using the default font and size). And all of the text prefixes and terminology is modifiable. Plus, you can add the tag <peep:no> to the note box of any enemies that you don't want the player to be able to read the stats of, and even customize the failure message that is displayed! All in all, I'd like to think it's a pretty robust plugin. It does have a few limitations (it only works on enemies, and not actors; it only works on one enemy at a time; and it only works in battle), but hopefully it will be useful for whatever your specific purposes are!

Download: Peep Skill Plugin (for use with RPG Maker MV)

Tuesday, February 16, 2016

Plugin: Terrain Battle Backs (MV)

The struggle to adapt my game to the latest version of RPG Maker continues, in spite of the frustrating limitations of developing a game inspired by classics that were designed for the desktop on a mobile platform.

You might remember my efforts at customizing the battle backgrounds automatically chosen based on terrain type on designated world maps in VX Ace, which I detailed in this post from two years ago (egads, has it really been that long?). That there isn't a built-in, user-friendly way to adjust these choices is one of those things in RPG Maker that amazes me.

Previously, I had opted to run a Parallel Process event on the world map to constantly check the tile ID (and thus, type of terrain) of the spot the player was standing on at any given time, in order to manually override the choice of battle background. It's a testament to how much has changed in the past couple of years that my first instinct this time around was to try and develop a scripted solution that modifies the way the backend code functions, instead.

So, I opened up the hood and jumped into the code. As a potentially relevant side note, MV is programmed in JavaScript. Trying to make sense of the tens of thousands of lines of code - and, particularly, trying to find the parts that do the stuff you want to modify - is no easy task. But I was able to track down the very function(s) that determine which battle background goes with which type of terrain. They are located (for reference) in rpg_sprites.js on lines 2530-2572. I'll copy them here:
Spriteset_Battle.prototype.terrainBattleback1Name = function(type) {
    switch (type) {
    case 24: case 25:
        return 'Wasteland';
    case 26: case 27:
        return 'DirtField';
    case 32: case 33:
        return 'Desert';
    case 34:
        return 'Lava1';
    case 35:
        return 'Lava2';
    case 40: case 41:
        return 'Snowfield';
    case 42:
        return 'Clouds';
    case 4: case 5:
        return 'PoisonSwamp';
    default:
        return null;
    }
};

Spriteset_Battle.prototype.terrainBattleback2Name = function(type) {
    switch (type) {
    case 20: case 21:
        return 'Forest';
    case 22: case 30: case 38:
        return 'Cliff';
    case 24: case 25: case 26: case 27:
        return 'Wasteland';
    case 32: case 33:
        return 'Desert';
    case 34: case 35:
        return 'Lava';
    case 40: case 41:
        return 'Snowfield';
    case 42:
        return 'Clouds';
    case 4: case 5:
        return 'PoisonSwamp';
    }
};
If you're not familiar with switch statements, they're basically extended conditionals, which check the value of a variable - each "case" basically tells the program "if this, then do that". The first thing you should note is that there are in fact two separate functions, corresponding to the two parts of the battle background - the bottom or ground section, and the top or wall section. This should be familiar to you if you've ever worked with the battle backgrounds, or looked at the associated image files that are named in these functions.

Another thing you might notice is the numbers that are being dealt with here. The function takes an argument (named "type") that, as you might guess, corresponds to the terrain-dependent tile ID, which is then evaluated in the switch statement. What's interesting is that these numbers are much smaller than the unwieldy tile IDs we dealt with before, which ran the gamut from 2048-4350. There's a rather obvious reason for this, that I must admit I discovered in an embarrassingly roundabout fashion. Those larger numbers are still relevant, as by using the Get Location Info event command, you'll find in-game that they haven't changed from VX Ace to MV. But for coding purposes, a little bit of math has been performed to make them more palatable. You can find that calculation in another function located on lines 5912-5915 of rpg_objects.js:
Game_Map.prototype.autotileType = function(x, y, z) {
    var tileId = this.tileId(x, y, z);
    return tileId >= 2048 ? Math.floor((tileId - 2048) / 48) : -1;
};
Basically, what this function does is take the tile ID corresponding to a location on the map determined by the x, y, and z (or layer level) coordinates, passed into the function as arguments. It then subtracts 2048 (since, I don't know why, but the IDs start at - and are thus offset by - a base value of 2048), and divides that number by 48. This makes sense because if you take the time to scrutinize, as I have, you'll find that there is a space of 48 numbers between each different type of terrain. These correspond to the various orientations of autotile placement which I have annotated in detail in my previous post for VX Ace.

But since choosing a battle background doesn't depend on whether you're standing on a "border" tile or a "center" tile (or what have you), you can essentially boil each set of 48 IDs down to a single terrain-dependent index. Which is exactly what the above calculation is doing (note also that if the tile ID doesn't fall into the expected range, the function returns a -1 instead, presumably for fallback purposes). Now, the thing that made me feel stupid for not realizing it sooner was the fact that, after you perform the calculation, what you're left with is nothing more than the placement index (starting at 0) of the tiles as they appear in the editor for the World_A tileset!

To illustrate, where we had this before:


We now have something much simpler (and more predictable!):


I'm not sure if this had crossed my mind before, but the indices (and the tile IDs they correspond to) are all unique. Meaning that, although they're stacked on either of two separate layers - so that a given tile can have both a Layer 1 ID and a Layer 2 ID - the numbers on either layer never overlap. So if you give me a number, I can tell you exactly what type of terrain it corresponds to without knowing whether it's a Layer 1 or a Layer 2 ID. Which, it turns out, is exactly what the functions with the long switch statements that I copied above are doing. So then, you might ask, are those functions evaluating Layer 1 or Layer 2 IDs? And how is that determined? Exploring the functions that call those two functions will answer those questions. You can find them in rpg_sprites.js at lines 2518-2528. Here they are:
Spriteset_Battle.prototype.normalBattleback1Name = function() {
    return (this.terrainBattleback1Name(this.autotileType(1)) ||
            this.terrainBattleback1Name(this.autotileType(0)) ||
            this.defaultBattleback1Name());
};

Spriteset_Battle.prototype.normalBattleback2Name = function() {
    return (this.terrainBattleback2Name(this.autotileType(1)) ||
            this.terrainBattleback2Name(this.autotileType(0)) ||
            this.defaultBattleback2Name());
};
As well as I can figure, these functions run when the game is trying to load a battle and determine which battle background to use. Again, you'll note that there are two separate functions, one for each half of the battle background. They each do essentially the same thing, however, which is to call the long switch functions we've already seen (hereafter referred to as "the terrainName function(s)") to determine which battle background to use based on the terrain corresponding to the index evaluated via the autotileType function (the one with the math that we examined above).

If you're paying attention, you'll note that here the function only takes a single argument, whereas before it took three. This is confusing, but the explanation for it is quite simple. The previous autotileType function belonged to the Game_Map class. But here, we're dealing with the Spriteset_Battle class, which has defined its own autotileType function. But before you throw your arms up in frustration, this local version of the function is nothing more than a shortcut to that other version, but with the x and y arguments already predetermined to be the player's x and y map coordinates. You can examine the function yourself. It is located in rpg_sprites.js at lines 2590-2592, which I will reproduce here:
Spriteset_Battle.prototype.autotileType = function(z) {
    return $gameMap.autotileType($gamePlayer.x, $gamePlayer.y, z);
};
So, returning to the normalBattlebackName functions (hereafter referred to as "the normalName function(s)"), when they call the terrainName functions, they're passing in an index corresponding to a tile ID at either the first or second layer, depending on whether the autotileType function is being passed a 0 or a 1 (note that since counters in programming usually start at 0, the 0 corresponds to Layer 1, and the 1 corresponds to Layer 2 - try not to get confused). There's something a little weird going on here, though, because each normalName function is trying to return the value of a call to the corresponding terrainName function (which would be the name of the battle background file associated with the given terrain), but it's tangled up in an OR operator ("||"). Let's take a closer look:
return (this.terrainBattleback1or2Name(this.autotileType(1)) ||
            this.terrainBattleback1or2Name(this.autotileType(0)) ||
            this.defaultBattleback1or2Name());
It took me a while to get a firm grasp on what exactly is going on here, even though it's largely intuitive. (Sometimes explicit instructions are helpful). For a detailed explanation of the behavior of JavaScript's OR operator, read this. Suffice to say, the operator responds not just to true/false evaluations, but also to the wishy-washy properties of truthiness/falsiness. Sounds messy, doesn't it?

I'm pretty confident, though, that what's going on in these normalName functions is that they're trying to call the corresponding terrainName function first with the Layer 2 ID (giving it precedence). If the tile the player is standing on has no Layer 2 ID (presumably resulting in a "falsey" value), then it calls the function instead using the Layer 1 ID. And then, if for some reason there's no Layer 1 ID either, it falls back to a default (calling a simple function that does nothing more than return the 'Grassland' battleback - whether top or bottom).

---------

Are you with me so far? Because here's where we get to start customizing things. Now that we know which indices correspond to which terrains (see the second image above), it would be a simple matter to just change the names of the battle backgrounds in those functions with the long switch statements, or even to add new cases to designate other battle backgrounds for terrains that the default function doesn't account for.

(Disclaimer: I don't advise changing the original JavaScript files that come packed in with the program. But if you copy the important functions into a new JavaScript file, and make your adjustments there, then you can add it in the same way you do with your other plugins (MV terminology for scripts), and add it to your game via the plugin manager. That way, if there are any problems in the future, you have the simple option of either turning off or getting rid of the plugin completely, and reverting to the game's default functionality).

But in the process of doing this, I hit a little snag, because I like to have a little bit more fine-tuned control over the choice of battle background depending not just on either the Layer 1 or Layer 2 ID, but in some cases the result of their combination. In different cases, the Layer 2 ID might take precedence, whereas in others, the Layer 1 ID will be more important. My way of dealing with this via the eventing solution I used in VX Ace was to simply handle both Layer IDs simultaneously and check them against each other. But the functions we're dealing with here only consider one ID at a time. So what to do?

I tried a few different ways to get around this limitation, but I ultimately decided to modify the function itself to actually take two arguments instead of just one - one for each of the first two Layer IDs. I checked through all the core scripts (Ctrl-F is your friend), to make sure I knew every place the terrainName functions were being called, so as to avoid any discrepancies in the code. And it turns out that the only time the functions come up is in those cases we've already explored here.

(Another disclaimer: if you use another plugin that attempts to use or modify these same functions, you may encounter problems. I'm only a beginner MV scripter right now, so I wouldn't know how to minimize that possibility, e.g. by aliasing or whatever. Feel free to add in some contingency code yourself if you know how to go about doing that).

So all I had to do was change the (type) part of the function to a (type1, type2), and then in the normalName functions where the terrainName functions are being called, replace the first part of the confusing OR evaluation (while preserving the default fallback), so as to call the terrainName function just once with both arguments - one that retrieves the autotileType for Layer 1, and one for Layer 2. This is what the modified functions look like:
Spriteset_Battle.prototype.normalBattleback1Name = function() {
    return (this.terrainBattleback1Name(this.autotileType(0),
            this.autotileType(1)) || this.defaultBattleback1Name());
};

Spriteset_Battle.prototype.normalBattleback2Name = function() {
    return (this.terrainBattleback2Name(this.autotileType(0),
            this.autotileType(1)) || this.defaultBattleback2Name());
};
All that was left then was to modify the terrainName functions, by manipulating the switch statement(s), and in my case, adding in a couple of extra if/else statements for better flow, to tie the proper battle backgrounds to the proper combination of terrains. Here's what I ended up with (although I may make some more fine-tuned adjustments in the future):
Spriteset_Battle.prototype.terrainBattleback1Name = function(type1, type2) {
    if (type2 === 29) {
        return 'Cobblestones2';
    } else if (type2 === 37) {
        return 'Cobblestones4';
    } else {
        switch (type1) {
        case 4: case 5:
            return 'PoisonSwamp';
        case 8:
            return 'Ship';
        case 10: case 40:
            return 'Snowfield';
        case 16: case 18:
            switch (type2) {
            case 17: case 19:
                return 'Meadow';
            case 20: case 21:
                return 'GrassMaze';
            default:
                return 'Grassland';
            }
        case 24: case 26:
            return 'Wasteland';
        case 32:
            if (type2 === 33) {
                return 'Desert';
            } else {
                return 'Sand';
            }
        case 34:
            if (type2 === 35) {
                return 'Lava2';
            } else {
                return 'Lava1';
            }
        case 42:
            return 'Clouds';
        default:
            return null;
        }
    }
};

Spriteset_Battle.prototype.terrainBattleback2Name = function(type1, type2) {
    if (type2 === 30 || type2 === 38 || type2 === 41 || type2 === 46) {
        return 'Cliff';
    } else if (type2 === 21 || type2 === 36 || type2 === 44) {
        return 'Forest1';
    } else {
        switch (type1) {
        case 4: case 5:
            return 'PoisonSwamp';
        case 8:
            return 'Bridge';
        case 10:
            return 'Snowfield';
        case 16: case 18:
            if (type2 === 20) {
                return 'GrassMaze';
            } else {
                return 'Grassland';
            }
        case 24: case 26:
            return 'Wasteland';
        case 32:
            if (type2 === 33) {
                return 'Desert';
            } else {
                return 'Sea';
            }
        case 34:
            return 'Lava';
        case 40:
            return 'Snowfield';
        case 42:
            return 'Clouds';
        }
    }
};
A couple of notes to help you understand what's going on here. In the first function, I used an overriding if statement to return the appropriate ground textures for map tiles that feature roads (indicated by a Layer 2 ID), no matter what Layer 1 terrain is involved (grass, desert, snow, etc.). The rest of the cases are pretty straightforward, except that I provided some alternatives such as a different lower background for plains (indicated by a Layer 1 ID) versus grassy plains (indicated by a Layer 2 ID), and a similar alternative for ashy wasteland versus cracked lavafield (the subtle difference between the Lava1 and Lava2 battle backgrounds).

In the second function, I've used another conditional to override the texture for any tiles that require the Cliff or Forest1 wall texture, since they tend to crop up over a number of different Layer 1 ID terrains. The rest of the switch statement is again pretty straightforward, although here you'll see that I've designated one of the two desert terrains as a "beach" (as opposed to a landlocked desert) by giving it the Sea wall texture instead of the usual Desert wall texture.

And that's pretty much it! Feel free to take these code snippets and play around with them to suit your purposes. I'd love to make a fully customizable plugin out of what I've done here, but I fear that the individual needs of each user will be so specific as to require a heavily personalized combination of conditionals. Come to think of it, that may be why the original programmers haven't already done it.

Just a few last notes. It should be mentioned that in these examples, I've replaced all of my MV image files with resized versions of the VX Ace graphics (because I like them better). So my filenames may not match yours (although many - but not all - of the battleback filenames have remained the same from VX Ace to MV). Make sure the names you use in your code match the filenames in your img/battlebacks folders (1 and 2), minus the file extensions.

On a related subject, if you want to change the default battle background for use while riding the ship, you'll find that in a separate pair of functions that are really simple to modify. Look for them in rpg_sprites.js at lines 2582-2588.

I don't know how or to what extent the solution I've come up with here will dovetail with an airship encounter system, as I haven't tackled that problem in the MV version of my game yet. But if I have anything to say about that in the future, you can be sure to find it here on this blog!

Saturday, December 12, 2015

BGM Delay

I haven't had a lot of time to work on my games in the past couple of months - much of my free time has been taken up by my ongoing X-Files marathon (nearing its end now, though), and December is a busy, stressful time for me (bah humbug and all that). But I had a little time this weekend, and ended up figuring out how to record a video of me playing RPG Maker so as to demonstrate one of the enduring problems I have with the new MV program. I'll copy the video and the description I wrote up for it here, so you can see for yourself (I used a blank project just for this video):


BGM Delay - A demonstration of the problem I have in RPG Maker MV with BGMs (Background Music) taking several seconds to load each and every time they're played. MEs (Music Effects) and SEs (Sound Effects) as well as BGS (Background Sounds - not tested here) all play instantly, but not BGMs, which is true during map transfers and also when the game first loads the title screen. That multiple second delay is very annoying and frankly unacceptable in a professional product.

There's a little discussion (although not nearly enough, if you ask me) over on the RPG Maker Web Forums about this problem and potential fixes, but so far I haven't come across a satisfactory solution. Frankly, I'm surprised the program shipped with this little bug, although the fact that it did gives me little hope for a competent fix. I've read some theories that would explain it away as an inevitable symptom of the program having been designed to stream games on the fly in web browsers and/or on mobile devices.

In other words, just another sacrifice of advancing technology (and the trend towards mobile internet). I so wish I could go back to using the superior engine of RPG Maker VX Ace, but I just can't give up the cross-platform support and the side-view battle system. It's a frustrating quandary.

Sunday, March 1, 2015

Variable Graphics

Mention to any group of RPG Maker VX Ace users that you want to learn how to write scripts (which give you unparalleled power over customizing the game above and beyond what limited options the program hands to you), and they'll tell you to learn Ruby - the programming language that RPG Maker VX Ace is coded in. It's not that this isn't good advice, but a little primer on how the RPG Maker program actually works would be a lot more immediately useful - especially to those of us who have some programming experience, but simply don't know this particular language (yet).

Well, after a year of searching in vain (and, yes, I have finally made the decision to learn Ruby properly), I did recently come across a brief introductory tutorial to coding specifically for RPG Maker VX Ace, and, even with its limited scope, it has had an enormous impact on my understanding of at least some of the basics of what's going on in the code, but most importantly, on my confidence in being able to learn how to manipulate code, and the promise of what kind of things I'll have control over once I do. It's been the most useful external RPG Maker resource I've read since that eventing guide that enlightened me to the fact that I was doing "cutscenes" all wrong.

Graphic Equipment

In any programming environment, there is often more than one solution to every problem. Some solutions are simpler and more elegant than others, though those generally require some amount of experience and insight to discover. Sometimes the difference between one or another solution is simply a matter of approach, and your specific requirements will lead you to decide which ones are more or less desirable, and which ones may not be usable at all. For at least the last year or so, I've been looking for a way to implement optional alternate outfits, or, more crucially, equipment-dependent character graphics, in my game. It's one of those superficial features that doesn't impact the gameplay too terribly much, but is the sort of thing that makes the game a little more interactive and, I think, makes it a little bit more fun to play.

I toyed with the idea of using "Equip Events" (a handy script courtesy of Hime Works), which allows you to run versatile Common Events whenever the player equips or un-equips ("dequips") a character with a certain piece of equipment (weapons or armor). The Database in RPG Maker lets you run Common Events when items are used, but not when weapons and armor are equipped - this script fixes that discrepancy. With Equip Events, I can assign a unique Common Event to each piece of equipment, that will change the "actor" (RPG Maker terminology for playable character)'s character and face graphic to whatever I wish.

But, as you might be thinking, this could become rather cumbersome if I have a lot of pieces of equipment associated with custom graphic changes (that would turn out to be a lot of Common Events!). Moreover, this would work fine if each piece of equipment could only be used by one character (and thus is assigned a unique graphic change), but if I want a particular piece of equipment to change different graphics depending on who is equipping it, I'm out of luck, since I have no way (through this script or in the default program, that I know of) to know which character is the one being equipped!

So instead of using Equip Events for this specialized purpose, I found something better - a different script especially designed to change character graphics on equip - Jeneeus Guruman's Graphic Equip Ace. With this script I can simply add a little note in the corner (in the "notetag" area) of each piece of equipment's stats page in the Database, and the script automatically changes the actor graphic without having to do it through a Common Event. Better yet, I can assign different graphic changes to different characters for a single piece of equipment! And I can also assign a default graphic to each character for when they're not equipped with anything! As far as I can tell, this script works just as I need it to.

Variable Graphic Scripts

But there remains a little snag, which results from giving the player control over the actors' graphical appearances. There are two times at which I, as the developer, need to know what image an actor is being represented by: 1) when I display a message window accompanied by the actor's face, and 2) when I create temporary duplicates of actors to manipulate during cutscenes. Theoretically, this would simply be an issue of accessing data (which images are associated with which actors) that I know the program has a hold of. But the default program doesn't give you a command with which to access this data, and so this is an example of one of those situations where scripting can give you a simple solution that is not possible through eventing.

Now, presumably, you could get over this hurdle by assigning values to variables that correspond to actors' graphical appearances, that are updated every time those graphics are changed. And indeed, this is how I thought I was going to have to do it for a long time. But then I'd have to use the more cumbersome Equip Event solution above, rather than the more streamlined Graphic Equip Ace solution, since the latter isn't designed to update variables, but the former utilizes Common Events within which I can update variables. But then we come across the problem of having way too many Common Events, when I know there's a much simpler solution - if I could only access the data I know is hiding in the code somewhere.

(You might recall that I had this same problem with accessing the random encounter values, and it resulted in a similarly elegant solution.)

But first, a very small detour (only because this is the order in which I figured these things out). One thing that I discovered during my work on Ascension, that wasn't immediately apparent to me, was the difference between player and actor graphics. Actor graphics are stored in the program and correspond to specific actors (again, when I say "actor" I'm referring to playable characters). The "player" is the actual sprite you move around on screen, which is usually displayed in the form of the graphic of whichever actor is at the head of your party (and which will change if you change the order of your party). But here's the interesting thing - you can change the player graphic (which is, in a sense, more "temporary" than the actor graphics), without changing the graphic associated with any actor.

(I exploited this in Ascension by creating special graphics that denote which difficulty level you're playing on, that are viewable on the load/save game screen, but that don't affect the look of the character you control in the actual game.)

Character Graphics

Now consider that you're trying to design a cutscene where the player changes appearance (use your imagination - let's say the player is transformed into a toad), but by the end of the cutscene, the player must be returned to its usual appearance. You could change the actor graphic associated with the actor at the head of the player's party (which always changes the player graphic accordingly), and then change it back at the end of the cutscene. But if you let the player change the order of his team around, how will you know which actor graphic to change? Well, you can figure that out using event commands, by storing the numerical ID of the party leader in a variable, but then you'll need to use a conditional branch to determine the value of that variable, or else change everybody's graphic every single time.

If you know precisely which graphic you're going to use during the cutscene (if, say, it doesn't depend on who the character is), you can change the player graphic without mucking about with the actor graphics, but you're still going to need to use a variable and run a conditional branch to figure out which actor to turn the player back into at the end of the cutscene (depending on which actor is at the head of the party). And if there are different possibilities for graphical appearance for each of the actors, then you'll have to run even more conditional branches on the variables you've (hopefully!) been updating every time somebody changes their appearance. Or, you could just run this little script, right there in your event (look for the Script button on the third page of Event Commands), at the beginning of the cutscene:
$game_variables[x] = 
$game_player.character_name
$game_variables[y] = 
$game_player.character_index
to store the graphic associated with the player (whatever it is) in two variables x and y (replace with numbers, and make sure you use variables that aren't being used for something else - you'll probably also want to label them in the event window like you do all your other variables). Note that "character_name" refers to the filename of the image file (not including the extension) and "character_index" refers to the index of the image set within that file (if you've done any work on sprites and graphics in RPG Maker, you've undoubtedly noticed that image files usually contain eight different sprite sets, indexed from 0-7). Then, at the end of the cutscene, run this script:
$game_player.set_graphic(
$game_variables[x], $game_variables[y])
with the same variables from before, and it will automatically restore the player graphic to what it was before the cutscene! It's like you took a snapshot of the player, and then reverted it to the snapshot after changing it in the body of the event!

Alternatively, if you want to set the player graphic to that of a specific actor, but you don't know which graphic that actor is going to be using, and you don't want to keep a running tally every time the actor changes its appearance (resulting in a cascade of conditional branches), then just type this into a script box within your event:
$game_player.set_graphic(
$game_actors[x].character_name, 
$game_actors[x].character_index)
where x is the number of the actor as it appears in the Database. Additionally, if you want to set an event's graphic to that of an actor, rather than the player (useful if you're designing a cutscene where multiple actors in addition to the player are present), run this script:
$game_map.events[x].set_graphic(
$game_actors[y].character_name, 
$game_actors[y].character_index)
This time y is the number of the actor as it appears in the Database, and x refers to the ID of an event on the current map, whether it's the event calling the script, or another one entirely (make sure your ID refers to an event that actually exists on the map, though). Are you getting the hang of it yet? The next script will turn an event into a clone of the player, no matter what the player looks like!
$game_map.events[x].set_graphic(
$game_player.character_name, 
$game_player.character_index)
Go ahead, try it in your project! Note, however, that if you're trying to make an exact copy, you'll have to run a separate command to make the event face whichever direction you want it to face. You can, however, do this simply with a Set Move Route event command (try "Turn toward Player"), without having to use scripts at all.

Face Graphics

The other problem is the one involving the face graphic, which is used in message windows, and is unfortunately a little bit trickier. Now, you can use the same principles with the face graphic that we used above on the character graphic, just replacing every instance of "character" with "face". But remember that neither the player nor events have a face - only the actors do - and that face graphics are only used in message windows (and on the menu screen, but we're not concerned with that here).

Where it gets messy is using the script version of the Show Text event command. The script version gives us a little bit more power, in that we can assign a face graphic using a variable, like so:
$game_message.face_name = 
$game_actors[x].face_name
$game_message.face_index = 
$game_actors[x].face_index
$game_message.background = 0
$game_message.position = 2
$game_message.add("Text")
"Background" and "position" refer to the correlating options in the Show Text event command, each one indexed from 0-2 (Normal, Dim, Transparent; and Top, Middle, Bottom). "Text" is the actual text that will show up in the message window.

Presumably, we could use this solution just fine (on the other hand, there may be further difficulties, I haven't used it very much), but we no longer get the nice GUI accompanying the corresponding event command, which allows us to preview how the text will look (and thus fit it neatly into the text boxes). I'm looking into a more complicated script that digs into the code and adds a bunch of new features to the message windows that can be used right there in the event command - Yanfly's Ace Message System. It seems to do exactly what I want it to do, but as with most of these gourmet scripts, it also includes a whole lot of extra features that I don't really need. I might try to see if I can pare it down a bit to just the essentials that I want. The important thing is that it looks like what I want to do is not only doable, but I'm actually doing it!

Friday, November 21, 2014

Adjusting Encounter Rate

On every map in an RPG Maker VX Ace project, you can specify the average number of steps between random enemy encounters (on regions designated for random encounters), in the Map Properties window (below where you assign troops to each region). This gives you some level of control over how often a player will run into random encounters, but the formula the program uses to calculate the number of steps between any two given encounters leaves much to be desired. This formula can be found in the script editor on line 195 of Game_Player, and is as follows:
@encounter_count = rand(n) + rand(n) + 1
where "@encounter_count" is the number of steps until the next encounter, and "n" corresponds to the average number of steps between encounters that you specify in the Map Properties window on any given map. This formula calculates a random number from 1 to twice the average steps (plus 1) you've given the map. That means that on a map that you've chosen the average steps between encounters to be 20, for example, you could go anywhere from just a single step to as many as 41 steps before your next encounter. Quite frankly, I think that's too much variance, and especially on the low side, only being able to get a few steps between encounters is pretty frustrating.

The good news is, changing the program's behavior is as simple as modifying the above formula. Feel free to let your imagination run wild. A simple alternative that I'm using for the time being is as follows:
@encounter_count = rand(n) + n / 2
Here, the lowest possible number of steps before the next encounter will be: not 1, but half whatever the average steps between encounters is, and the maximum will be 50% more than the average. So, if you set the average to be 20 on a map, the steps calculated between encounters will always be between 10 (half the average) and 30 (three halves of the average). There's still a lot of variance there, but this formula cuts out the really short and really long travels between encounters to make it all a bit more consistent. As I said, you can fool with the formula as much as you like.

And if you don't want to change the default code (which I wouldn't recommend), just paste this code into the Materials section (with whichever updated formula you want to use) and it will overwrite the default:
class Game_Player < Game_Character
  def make_encounter_count
    n = $game_map.encounter_step
    @encounter_count = rand(n) + n / 2
  end
end
I recommend you give it a title ("encounter adjustment", perhaps?) so you know what it does at a glance in the future. This is a nondestructive way of messing around with the scripts so that if for whatever reason you want to revert to the default, you can just delete the added code in the Materials section!

Click here for another mini-script related to random encounters.

Friday, November 7, 2014

Building a Canoe

Vehicles in RPG Maker VX Ace (without scripts) behave in a certain way. This post is concerned primarily with the "boat", which is not to be confused with the "ship". The ship is the typical RPG ship vehicle, which moves at double speed over ocean tiles (shallow or deep). Unlike in Final Fantasy (the first one), though, ships can dock anywhere on land - not just at ports - and it can also sail up rivers, basically making the boat obsolete once you get the ship.

The boat, on the other hand, instead of just paddling up rivers, can also traverse shallow ocean tiles. This can be an advantage or a disadvantage depending on what your game requires. But also depending on your RPG experience, it can be a little counter-intuitive (I'm finding that RPG Maker VX Ace is a bit of an amalgam of different RPG conventions from various sources, which is good in that it's not just a duplicate of one particular game, but can be frustrating if you're trying to model your own game after certain conventions you're used to from a particular title).

Anyway, I was wondering if I could build a canoe that works like the one in Final Fantasy, which doesn't act like a vehicle in that it sits on the map in one place and you board it, move around, and then disembark. The Final Fantasy canoe is more like an item you carry in your inventory: once you have it, previously impassable rivers are now passable. You don't need to find your canoe and board it first - you already have it with you. You just step onto the river, and your player graphic changes to the canoe, and once you step off, it changes back to your character.

Well, the RMVXAce "boat" doesn't work that way - it's a full-on vehicle, like the ship. But, as an exercise to demonstrate how to manipulate certain aspects of the game (in this case, without using scripts), let me describe a workaround I've come up with. To start with, the default settings ensure that the player can not simply walk over river tiles. This is easy enough to change, by navigating to the tileset tab of the Database, and changing the passage setting of the river tile on the "Field" tileset (second row, first column) from an X to an O.

Presumably, though, there'll be a point in your game before your character acquires the canoe. So, what you can do is copy the Field tileset and paste it onto another line (you may have to increase the maximum). On one of them, the river tile should be set to impassable, and on the other one (you should name it differently so you can tell the difference), it should be set to passable. Then, all you need to do is use the "Change Tileset" Event Command once your player acquires the canoe, on any maps with rivers, to change it from the default Field tileset to the new one with the rivers set to passable!

But, there's something you still need to account for. When you change a map's tileset via the Change Tileset Event Command, it resets whenever you leave that map. Furthermore, I don't think you can change the tileset of any other map than the one you're on when the Event triggers - which wouldn't work if you acquire the canoe in a town, and the rivers are all on the world map.

Well, here's what you can do: on any maps that have rivers, create an autorun event. It should trigger only once the player has acquired the canoe (you can check this with a switch, or else by whether the player has the canoe item, if you want to treat it that way). It should change the tileset of the map as discussed above and then erase itself (Erase Event). That way it will fix the map every time you enter it after acquiring the canoe, so that you will be able to walk over the rivers.

Now, then, you're going to need another event on the same map - a Parallel Process that runs only when the player has the canoe. This event is going to check the player's map position (by storing them in variables), and then determine the terrain tag (by storing it in another variable) of the tile the player is currently standing on (with the "Get Location" command). Of course, you'll have to go back into the Database and give the river tile (on the passable version of the Field tileset) a terrain tag (and make sure it doesn't conflict with any other terrain tags you might be using on the same map).

In the Parallel Process event, you'll want to run a conditional branch that checks whether the terrain tag of the tile the player is standing on (which you stored in a variable) matches the one you gave the river tile in the Database. If it does, use a Set Move Route command and change the player's graphic to the boat graphic, and then turn a self-switch on. Now you're in river mode.

Create a new page in the same event (also triggered by parallel process), with the conditional being the self-switch you just turned on. Now, you're going to do the same thing as before (get the player's position, store the terrain tag in a variable, then check that variable), but this time you want the conditional to run only when the terrain tag is NOT equal to the one you gave the river tile in the Database. When that happens, simply change the player's graphic back to what it was using another Set Move Route command, and then turn off the self-switch. You're back in land mode!

You can do all sorts of things now, like disable the save function when the player is on a river tile, by adding the appropriate commands to the event in the same place where you changed the player's graphic. You also may need to run a conditional branch when changing the player's graphic back, to determine which party member is at the head of the party. In fact, you'll probably want to disable Formation Access while the player is in the canoe as well, so the player doesn't switch out the canoe graphic for a different character. And, graphically, this canoe feature doesn't work well if you're using "Player Followers" (which I don't like anyway).

Those are the basics. It seems to work pretty well for me so far - I've even managed to get a waterfall cave (map transfer from river tile to dungeon, and back again) working. You can even dock the ship at a river mouth, too! Just like in the first Final Fantasy. I rigged up a nice little tutorial (like I've seen users do on the RPG Maker forums) that demonstrates how my FF canoe works - you can download it here and play it like any other RPG Maker game. Also, it's unencrypted, so you can open the project file up in RPG Maker and see just how all the events work. It's a lot like my Prefab Smithy, but taken just one more step further!

Friday, March 28, 2014

Building a Ship (Map)

The on-ship cutscene is a staple of classic RPGs. Although in the first Final Fantasy, there was no separate map to indicate being on board the ship (or airship), I seem to recall one in Final Fantasy IV (probably just before the entire gang got attacked by Leviathan), and there were certainly scenes of that nature in Final Fantasy VI - even more so if you include the airship.

Well, in my work on the harbor town I'm designing, and the nearby sea shrine, it came to me that I'm going to need to have a scene on board the ship that your group eventually acquires the reins to. Trouble is, RPG Maker VX Ace does not include a tileset to be used for designing ship maps. I found a couple custom tilesets designed by fans, but they leave a lot to be desired.

It turns out that a previous version of RPG Maker - RPG Maker XP - did have a ship tileset. And I realized in another light bulb sorta moment that, just like you can download the RTP for RMVXAce, you can do so (on the very same webpage) for both previous versions of the program RMVX and RMXP! And then, you'll have access (in your Common Files) to all the default tilesets, graphics, music, etc. from those versions of the program!

Well, I thought, hey, this might be a way to grab some extra materials to develop with. Like, for example, the battler graphics (graphics for monsters you fight in encounters), are good enough, but the variety is too limited. I'd be happy with more in the same style, so they all look consistent, but there's just not enough included with the program. Well, it turns out that VX's graphics are very similar to VXAce, only a bit more primitive, and barely anything new that VXAce doesn't already cover.

XP is further removed from the VX series, so you'd think it might have more options, but the drop in quality is considerable. Plus, as far as the battler graphics are concerned, there is way too much emphasis on humanoid enemies (as opposed to more animal-based enemies like my game requires). Also, XP used a graphical standard where the characters were two tiles tall (I think I've seen people refer to it as "mack", but I don't know what that means), instead of the "chibi" one tile square standard that VX/Ace uses.

Personally, I prefer the one tile standard, even if it distorts the character more, because it more accurately reflects the graphical style of the classic Final Fantasy RPGs I'm drawing most of my inspiration from, and that was one of the compelling reasons that led me to get my hands on VX Ace when I had passed on many of its RPG Maker forebears. Anyhow, the fact that XP uses two tile tall characters means a lot of the graphic proportions are unsuitable for a game designed with VX/Ace. :-/

However, for the ship tileset, I'm willing to make an exception, because there really aren't any satisfactory alternatives that I've come across. But, it's not a pretty compromise. I had to modify the actual dimensions of the tileset file so it works in VX Ace. And, as far as I can surmise, RMXP used a system that involved many more layers of graphical superposition so you can, for example, lay the mast down over top of the ship's deck. This is harder to do in VXAce, without carefully manipulating which tiles go on which layer, but it can be fudged by using events (for which you can select a graphical tile, and place over top of the actual map).

But that's not all. It's a bit hard to figure out where all the ship tiles are supposed to go, and how they're supposed to be used. I unfortunately don't have access to any kind of sample map from XP, like I do in VX Ace, to see how the designer was intended to use the ship tiles. You'd think it'd be a simple enough matter to figure out via trial and error, and it more or less is, but one thing that confounds me is that the back of the ship doesn't fit together with the front. For the life of me, I don't know what's going on there, and I wish I knew how XP built a ship, because to me it looks like it can't be done with the tiles included.

Anyway, I actually went in and graphically modified the relative positions of some of the tiles, so that the back and the front of the ship match, and did my best to build a decent ship map - inside and out. It's not very shiny, but I think it's good enough to use. Go ahead and take a peek at it:



I'm going to give you a link to the ship tileset files I used, adapted from RMXP to work in RMVXAce, with the back of the ship adjusted to fit the front. Note that I used a lot of events, especially for the mast, but also for the overhang on the front of the ship, to get it looking the way it does in my map. All you have to do is import the files into your tileset folder, and then add them to a tileset in the Database. I recommend making a new one just for ships. You'll probably want the ocean tiles, and I also put the wooden plank floor tiles in files for the A layer (so you can place other stuff on top of them) - I'll give you those, too. Make sure you set the passability settings in the Database so the program knows where to let the player walk and where not to.

Ship_A1 - ocean tiles
(place this in the A1 slot since they're autotiles)

Ship_A5 - floor tiles
(place this in the A5 slot since they're not autotiles)

Ship_Bfix - first half of the ship tileset, with modified back of ship
(place this in the B, C, D, or E slot - these tiles go on top of A tiles)

Ship_C - second half of the ship tileset, mostly interiors
(place this in the B, C, D, or E slot - these tiles go on top of A tiles)

Disclaimer: I can't seem to figure out how to get the translucency to work. The transparency should work fine, but if the shadows under some of these tiles seem a little blunt, that's why.

Note: You can place any other tilesets in the remaining B, C, D, and E slots (whichever two you didn't use for the ship tilesets). For example, I put Inside_B and Inside_C (standard Interior tilesets that come with the RTP) in the D and E slots for some basic interior stuff (beds, shelves, etc.). It's up to you.

Good luck! And if you find a more elegant solution to the lack of a ship tileset in RMVXAce, please let me know what it is...

Wednesday, March 12, 2014

Steps to Next Encounter (and my very first script!)

Even before I started building my game in RPG Maker VX Ace, I had in my mind an idea for an optional alternative to the usual random enemy encounter system. Now, as far as that standard system goes, I have mixed feelings about it, because, like everyone else, I understand and recognize that random encounters can be annoying, to say the least, and do definitely have a discouraging effect on the player's exploration of your maps. On the other hand, they do serve a purpose, increasing the feeling of "danger" in unsafe areas, giving the player something to do on a map, introducing the need to weigh the risk of searching for treasure against the cost of fighting more battles; and they're intricately integrated into the basic gameplay style of your classic RPG. Not to say that there aren't alternatives, or that there haven't been any RPGs that have explored other possibilities (some with great success), but I am very reluctant to throw it out altogether.

Therefore, I'm open to nonstandard alternatives. The most popular alternative is probably on-screen encounters, which is something that Chrono Trigger (the best non-Final Fantasy RPG ever made), and also the much-maligned Final Fantasy Mystic Quest used (in part). And while this is a nice option, I don't feel it's suited to every RPG style, and, unfortunately, RMVXAce's included sprite graphics are very limited in the monster category (even more so than their in-battle "battler" graphics), making that option pretty undesirable without seeking external graphical support.

Well, the idea I had in mind for my game was the possibility for the character - being affiliated with the Hunters Guild, whose goal is to eradicate monsters in the wild - to choose the option of, instead of waiting around and letting the monsters come to you, taking a more proactive stance and initiating a series of continuous encounters, after which the map the player is on will be entirely cleared of encounters. This way, you can actually separate the adventure and battle portions of the game play, and not have the one constantly interrupting the other. I think that that could potentially be preferable, as once you're in battle mode, you're probably less resistant to the idea of continuing to fight, whereas when you're in the middle of exploring, the last thing you want is a battle popping up out of nowhere to distract your focus.

Final Fantasy Mystic Quest actually had something like this, outside of the dungeon maps (which used on-screen encounters), in the form of "battlegrounds" (or whatever they might have been called), where you'd have to fight ten (I think) battles in a row in order to vanquish it and move to the next spot on the map. It's very similar to what I have in mind, although I would integrate it more into the rest of the game, rather than standing apart from the dungeons, and be an optional alternative to the classic random style of encounters. The only thing is, I haven't yet worked out all the kinks of how I want it to function, and that's hampering my progress on actually developing it in my game. Like, do I want vanquished maps to stay vanquished, or reset once you've left them? Do I want the players who choose random encounters to still have the option of "vanquishing" after a certain number of those random encounters, or not? And if so, can I actually do that with the program available to me?

So I've been exploring how the random encounters actually work in this program, for a better understanding of what options are open to me. It turns out that the game's random number generator is a bit less-than-ideal: for example, if you set a map's average steps between encounters to, say, 15, you will be just as likely to get one step between two encounters as you will 29. But that appears to be easy enough to modify just by changing the equation. One other very interesting thing I've learned is that after every battle, the game calculates a random number of steps (within the set bounds) until the next encounter, so it knows exactly when your next encounter is going to trigger (as opposed to, say, flipping a coin with every step).

With that knowledge came speculation about random encounter "gauges", as I've heard some other games have done, which use some kind of visual cue for the player (overlaying a picture onto the screen would be a simple matter in RMVXAce), to warn them of an impending encounter - like a symbol that changes color or flashes red when the encounter is near. I'm not sure if it's something I actually want in my game - although I can see how, without changing how the encounters actually work, it might be less jarring to the player if they can anticipate a battle that's coming up rather than being completely surprised - but I was possessed with an uncanny desire to code one myself, just to see if I could do it.

Honestly, it seemed easy enough. I was even able to pry into the scripts behind the engine, and locate some of the terminology being used to determine this hidden value that dictates the number of steps between one encounter and the next. But for the life of me, I couldn't figure out how to access that value (or the variable that presumably holds it) in an event for manipulation, even with the simple script calls I was trying out. I knew the value was there in the code somewhere, and I even thought I knew where, yet it remained - frustratingly - out of reach. I got so annoyed with it, that I actually started learning some of the basics of coding in "Ruby", in the hope that it would help me understand the code - or read somebody else's script that did what I wanted to do.

It was a frustrating effort, but I learned enough to figure that if I couldn't access the value directly, I could modify the code and add in a line that assigned the value I was looking for to a game variable that I DID know how to access. And voila, it worked like a charm. I even went so far as to learn how to write "aliases", so I could add in a new script that modifies what the game does, without changing the code on the original page - that way if there are problems in the future, I can easily revert to the default. It's almost crazy to think it, but I actually wrote a custom script of my very own! Granted, it's extremely basic, and doesn't change the actual functionality of the program, just assigns a couple of values to a couple of easily-accessed variables, but still!

By the way, if you're working on a game like me, and you'd like to access said values - namely, the number of steps the game chooses before initiating the next encounter, as well as the running count of decreasing steps left until that encounter - feel free to use this script. Because it doesn't muck around with functionality, there really shouldn't be any compatibility problems (but then again, what do I know?), but you do have to make sure the variables in this script aren't being otherwise used in your game (by yourself, or by other scripts). I chose variables number 50 and 51 just because they were empty, and I wasn't using them. You can change those two numbers to whatever you want, to correspond to two different game variables you aren't using. Then, you can access their values just like any other variable you're using in your game! You can use them to make a countdown or gauge that measures steps until the next encounter in a way that either you, the developer, can make use of, or the player can see! (I imagine it would be a simple matter of using a parallel process event that changes a picture overlaid on the screen).

Here it is. All you have to do is copy this text into an empty page in the "Materials" section of your Script Editor, and give it an appropriate name (I called mine "encounter variables"):
class Game_Player < Game_Character
  #mods Game_Player line 193-6
  #stores total number of steps until next encounter in game variable 50
  #change 50 to whatever variable number you want to use for this value
  alias :zharth_make_encounter_count :make_encounter_count
  def make_encounter_count
      zharth_make_encounter_count
      $game_variables[50] = @encounter_count
    end
    
  #mods Game_Player line 378-84
  #stores number of remaining steps until next encounter in game variable 51
  #change 51 to whatever variable number you want to use for this value
  alias :zharth_update_encounter :update_encounter
  def update_encounter
    zharth_update_encounter
    $game_variables[51] = @encounter_count
  end
end
Just a couple notes, though. First, the countdown value, that decreases with every step, and initiates an encounter when it hits zero, doesn't update until the player's taken their first step after the last encounter. So, be careful if you have something happening when the counter is at zero, it'll likely trigger after the battle instead of just before it. Also, the way the game works, certain tiles are designated as "bush" tiles - usually forests on the world map, and grass on other maps (these can be changed in the Database on the Tilesets tab) - and these tiles actually decrease the "steps until next encounter" count by 2 steps, not just one. As a result, sometimes the counter will drop to -1. Also, since the counter could jump from 2 to 0 in one step, you want to make sure that any indicator that occurs just before an encounter doesn't happen too late for the player to see it. Also, the steps counter decreases by only 0.5 for every step when the player is driving the ship vehicle. (These settings can be modified via scripts if you need).

The other thing worthy of noting is that the steps counter remains active even when the player is standing on tiles that are not designated for random enemy encounters. If, for example, you have a road that serves as a safe space, with no enemy encounters, the counter will still decrease as the player walks along the road. If they step off the road, they will still trigger an encounter when the counter reaches zero. If they remain on the road when the counter reaches zero, it will merely reset without initiating an encounter. I can see how this behavior could be abused by a player - especially if they are being given a visual cue as to when the next encounter will occur - in the form of stepping on the road as soon as the encounter is supposed to trigger, allowing the counter to reset, then venturing back out into the dangerous area. This wouldn't be an issue, however, on maps with no or very minimal safe tiles. But maps that do have such areas might invite confusion for the player if the visual gauge is flashing red while the player stands in a safe area, and no encounter initiates. You might be able to get around this by turning any such visual cues off on those tiles, but that could become tedious, or not look very smooth or elegant. I leave consideration of such issues up to you.

Sunday, March 9, 2014

Tile IDs and Terrain-Dependent Battle Backgrounds

On most maps created in RPG Maker VX Ace, a "battle background" must be specified for enemy encounters (whether random or by call from an event), otherwise a less-than-satisfactory swirled composite snapshot of the current map is used. However, "world map" or "overworld" maps (designated by using the "Field" tileset) utilize a different behavior, in which the battle background chosen for an encounter if not otherwise specified depends on certain presets that correlate to the type of terrain the player is standing on when the encounter is initiated (e.g., grass, desert, snowfield). When the player is driving a vehicle (excepting the airship, which is not susceptible to normal random encounters) the ship background is used.

A variety of battle backgrounds

This is a pretty handy default, although it may not be sufficient if you'd rather have a more fine-tuned system (for example, I don't think it looks right to have an open seas background when you're paddling down the river). Normally, for dungeon maps, you'd only really need to set a single background for more or less all of the encounters, and this can be done in the map properties. But because the world map often involves multiple varied terrains, a single determined background just isn't going to cut it.

Now, you can, I believe, use region ID codes (which can be freely placed on maps, and are usually used to designate regions containing a specific set of encounters) to trigger different battle backgrounds, although I feel that may introduce some confusion for the developer, as it splits the use of region IDs across two separate purposes. Terrain tags may also be used, which are linked to the actual tile graphics themselves, although you can only denote 10 such tags (as opposed to the 64 region IDs), so they are much less useful in this case. I ended up utilizing the tile IDs instead, which are ideal - since you can designate the battle background through event (without mucking up the way anything works on other maps) - but a little tricky because you have to figure out what the tile IDs are for the tiles you're using in the first place.

I ultimately decided that I would have to use my own terrain-specific background system while I was working on an airship random encounter, inspired by the Doom Gaze enemy from Final Fantasy VI. For developers' reference, action button and touch events don't trigger while you're on the airship (but they do on the boat or ship). Otherwise, you'd find yourself entering towns in your airship just by flying over them, and that would be...awkward, to say the least. But, autorun and parallel process events will still run when you're in the airship, and so I used the latter to rig my airship random encounter.

Doom Gaze attacks sporadically when you're flying around in the airship in FFVI

It worked swimmingly, except that the system-designated battle background was, like the other vehicles, the ship background. The ship floor looked fine enough, but having the ocean, instead of the sky, in the background, was all wrong. So I manually set the background for that encounter to the one I wanted. Problem was, after I got off the airship, and ran into an encounter on a snowfield, the background was still specified as the ship+clouds background I had set for the airship encounter. And though I could respecify the background after getting off the airship, I couldn't revert it to its default unspecified state, thus triggering the automatic terrain-dependent backgrounds the system falls back on (trying to set the background to "none", by the way, just causes it to use a black screen as the background).

So I figured, if I want this to work right, I'm just going to have to knuckle down and create a system of my own that selects the backgrounds I want. The good news is that it's doable just by using a single parallel process event (per overworld map, if you have more than one) that recurringly checks the player's x and y coordinates. The bad news is that figuring out the tile IDs that the event checks the coordinates against was a bit of a pain in the ass. You'd think this was one of those things listed in the owner's manual under "specs" or something (and maybe it is - but I couldn't find it). At any rate, it is possible to brute force it, enough to get the pattern down and fill in the blanks.

First, though, you have to have a basic understanding of how autotiles work (which most of the overworld terrain tiles are). My first thought was that I could look at the tilesheet, and just count the tiles 0, 1, 2, 3, from top left to bottom right, but the way the autotile system works is that every autotile on the sheet corresponds to some 47 different tiles (depending on how its borders are oriented). Not only that, but the first tile begins at ID number 2048, and not 1 or even 0. This tutorial by Nick Palmer is an excellent discussion of how those autotiles work, but it stops short on listing the actual tile IDs, or even identifying which tiles in the pattern are the first and last (which would facilitate identifying the number at which each terrain type gives way to the next one).

So I just figured it out myself. And I'm gonna tell you what they are, so that if you find yourself in my position, you won't have to repeat all the grunt work I've just done. First, I played around with the shallow sea tiles (because that's the first terrain on the tilesheet), and rigged up an event that displays the tile ID of the tile the player is standing on when he presses the shift (dash) button, so I could jot them down. As it turns out, the tile with the lowest numerical ID within any autotile set is the one with no borders (the "center" tile), and the one with the highest numerical ID is the one with borders on all sides (the "lone" tile). After figuring that out, it was simple enough to just find out the lowest and highest IDs for each of the subsequent terrains. For what it's worth, though, here's a graphical representation of each of the 47 tiles in the autotile set, in order, from lowest numerical ID to highest. I assume the other terrains work similarly, and at least, the lowest and highest tiles have born that theory out.


The ID range for the rest of the terrains in the A layer Field tileset ("World_A") are as follows:

White numbers denote layer 1 IDs, green numbers denote layer 2 IDs.

Note that the tile ID actually has three layers, which correspond to the graphical layers on which the tiles are laid down. Layer 3 corresponds to the B, C, D, and E layers, so, in the case of the Field tileset, that would be towns and castles and things like that. The A layer, which is the one we're dealing with, includes both layers 1 and 2 of the tile IDs. The trees and mountains and things in the lower right corner of the tilesheet go on top of the ground, so they are all designated with layer 2 IDs. You'll notice, also, that the deep sea tiles are marked by layer 2 IDs. This is because they are actually placed on top of the shallow sea terrain. This is also why the sea add-ons, like the rock shoal and the icebergs, when placed on deep sea tiles, change that tile to shallow sea, instead of going on top of the deep sea. Some of these terrains have IDs that do not span the full 47 values; this is because they are not autotiles (they don't have variable borders). Incidentally, if you wanted to find the layer 3 tile IDs for the B, C, D, and E layers, you'd probably have a much easier time, as they don't include autotiles, and you can probably just count them off from the tilesheet (but I haven't actually tried it out).

Layer 2 (or 3) tiles placed on top of layer 1 (or 2) tiles (like trees on grass, or deep sea over shallow sea) will retain the lower layer ID of the ground tile, in addition to the upper layer ID of the add-on. This is something you'll have to account for in your conditional branches if you're designating different behavior for different combinations of layers. For example, shallow sea and deep sea tiles will both have layer 1 IDs in the range of 2048-2094, but the shallow sea tiles will all have layer 2 IDs of 0, whereas the deep sea tiles will have layer 2 IDs in the range of 2096-2142. As another example, pine tree forests will always have a layer 2 ID in the range of 3056-3102, but their layer 1 ID will be determined by the type of terrain the trees are sitting on. Tiles like the swamp tree, lava bubbles, waterfall, cloud, pond rock, and whirlpool, despite appearing to be add-on tiles, are actually stand-alones, and are designated by their own unique layer 1 IDs. It is also worth noting that for the 16 types of terrain in the bottom left corner of the tilesheet, each tile with a layer 2 ID is automatically placed upon (and therefore carries the layer 1 ID of) the terrain to its immediate left (exactly like the deep sea goes on top of the shallow sea).

tl;dr - If you ignore everything else, the real meat of this post is that last image above. I hope it proves useful for somebody somewhere someday.

Friday, March 7, 2014

A Prefab Smithy

So here's what I accomplished today - a prefab smithy. It's pretty simple. You go in, and the swordsmith will craft a sword for you. I intend to integrate this into my game at some point, but for right now I took it as a challenge and just wanted to see if I could put it together and get it to work. Getting some of the animations to work right was a little tricky (fine tune controlling of those step animations is a bitch), but I think I got it running pretty smoothly. I copied it to a blank project so I could upload it and let you guys try it out for yourself. Everything except the smithy and the basic sword weapon is the default the program starts with. It's not encrypted, so if you have RPG Maker VX Ace, you can open it up and see how it works. If you want to use it or modify it for your own game, be my guest.

Download: Smithy (1.47MB)