Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

How to Build a JRPG: A Primer for Game Developers

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

This article is a high-level overview for creating a JRPG (Japanese Role-Playing Game) such as the early Final Fantasy games. We'll look at the architecture and systems that make up the skeleton of a JRPG, how to manage game modes, how to use tilemaps to display the world, and how to code an RPG combat system.

Note: This article is written using a Java-like pseudo code language, but the concepts are applicable to any game development environment.


Contents



The Unlikely Birthplace of JRPGs

On of Dragon Warrior iconic enemies - the slime

The slime - one of Dragon Warrior's iconic enemies.

In 1983, Yuji Horii, Koichi Nakamura and Yukinobu Chida flew to America and attended AppleFest '83, a gathering of developers showing off their latest creations for the Apple II. They were blown away by the latest version of an RPG called Wizardry.

On returning to Japan, they decided to create Dragon Warrior, an RPG that was similar but streamlined for the NES. It was a massive hit, defining the JRPG genre. Dragon Warrior didn't fare as well in America, but a few years later another game did.

In 1987, the original Final Fantasy was released, spawning one of the best selling video game franchises on Earth which became, at least in the West, the iconic JRPG.



The Genre Talk

Game genres are never precisely defined - they're more a fuzzy collection of conventions. RPGs tend to have a leveling system, one or several player characters with skills and statistics, weapons and armor, combat and exploration modes, and strong narratives; game progress is often achieved by advancing across a map.

Japanese RPGs are RPGs created in the mold of Dragon Warrior; they're more linear, combat is often turn-based and there are usually two types of map: a world map and a local map. Archetypal JRPGs include Dragon Warrior, Final Fantasy, Wild Arms, Phantasy Star and Chrono Trigger. The type of JRPG we're going to talk about in this article is one similar to an early Final Fantasy.

jrpg-snes-jrpgs


Five Reasons You Should Make a JRPG

1. They've Stood the Test of Time

Games like Final Fantasy VI and Chrono Trigger are still very enjoyable to play. If you make a JRPG you're learning a timeless game format that modern players are still very receptive to. They make for a great framework to add your own twist and experiment - be that in the narrative, presentation or mechanics. It's a great thing if you can make a game that's still played and enjoyed decades after it's first release!

2. The Game Mechanics Are Widely Applicable

Call of Duty, one of the world's most popular FPS games, uses RPG elements; the social game boom surrounding FarmVille was basically a clone of the SNES RPG Harvest Moon; and even racing games like Gran Turismo have levels and experience.

3. Constraints Foster Creativity

Much as a writer might be intimidated by a blank sheet of paper, a game developer may find themselves paralyzed by the large number of possible choices when designing a new game. With a JRPG a lot of the choices have been decided for you, so you don't have that choice paralysis, you're free to follow the conventions for most decisions and deviate from convention at the points that matter to you.

4. It's Doable as a Solo Project

Final Fantasy was almost entirely coded by a single programmer, Nasir Gebelli, and he was doing it in assembly! With modern tools and languages it's far easier to create this type of game. The largest part of most RPGs isn't the programming it's the content - but this doesn't have to be the case for your game. If you dial it back a little on the content and focus on quality over quantity then a JRPG is a great solo project.

Having a team can help with any game, and you might want to outsource the art and music, or use some of the excellent creative commons assets from places such as opengameart.org. (Editor's note: Our sister site GraphicRiver also sells sprite sheets.)

5. For Profit!

JRPGs have a dedicated following and a number of indie JRPGs (such as the ones pictured below) have done well commercially and are available on platforms like Steam.

jrpg-indies


Architecture


JRPGs share so many conventions and mechanics that it's possible to break a typical JRPG down into a number of systems:

jrpg-architecture

In software development one pattern is seen over and over again: layering. This refers to how the systems of a program build on top of each other, with broadly applicable layers at the bottom and layers more intimately dealing with problem at hand near the top. JRPGs are no different and can be viewed as a number of layers - lower layers deal with basic graphic functions and upper layers deal with quests and character stats.

Tip: When developing a new system it's best to start by creating the bottom layers first and then moving layer by layer to the top. Using middleware helps you skip several of the lower layers common to many games. On the architecture diagram above, all the layers below the dotted line are handled by a 2D game engine.

As you can see from the architecture diagram above, there are a lot of systems the make up a JRPG but most systems can be grouped together as separate modes of the game. JRPGs have very distinct game modes; they have a world map, local map, combat mode and several menu modes. These modes are almost entirely separate, self-contained pieces of code, making each one simple to develop.

Modes are important but they would be useless without game content. An RPG contains many map files, monster definitions, lines of dialog, scripts to run cutscenes and gameplay code to control how the player progresses. Covering how to build a JRPG in detail would fill an entire book, so we're going to concentrate on some of the most important parts. Handling the game modes cleanly is critical to producing a manageable JRPG, so that's the first system we'll explore.



Managing Game State


The image below shows the game loop pumping away, calling an update function every frame. This is the heartbeat of the game and nearly all games are structured this way.

jrp-gameloop

Have you ever started a project but stalled because you found it too hard to add new features or were plagued by mysterious bugs? Maybe you tried to cram all of your code into the update function with little structure and found the code became a cryptic mess. An excellent solution to these types of problem is to separate the code out into different game states, giving a much clearer view of what's happening.

A common gamedev tool is the state machine; it's used all over the place, for handling animations, menus, game flow, AI... it's an essential tool to have in our kit. For the JRPG we can use a state machine to handle the different game modes. We'll take a look at a normal state machine and then we'll mix it up a little, to make it more suitable for the JRPG. But first let's take a little time to consider the general game flow pictured below.

jrpg-states-and-transistions

In a typical JRPG you'll probably start off in the local map game mode, free to wander around a town and interact with its inhabitants. From the town you can leave - here you'll enter a different game mode and see the world map.

The world map acts very much like the local map but at a larger scale; you can see mountains and towns, instead of trees and fences. While on the world map if you walk back into the town the mode will revert to the local map.

In either the world map or local map you can bring up a menu to check out your characters, and sometimes on the world map you'll be thrown into combat. The diagram above describes these game modes and transitions; this is the basic flow of JRPG gameplay and is what we'll create our game states from.

Handling Complexity With a State Machine

A state machine, for our purposes, is a piece of code that holds all the various modes of our games, that allows us to move from one mode to another, and that updates and renders whatever the current mode is.

Depending on the implementation language a state machine usually consists of a StateMachine class and an interface, IState, that all states implement.

Tip: An interface is just a class with member function definitions but no implementation. Classes that inherit from an interface are required to implement its member functions. This means an interface has no code, it just specifies that other classes provide certain functionality. This allows different classes to be used in the same way because we know they have a group of member functions defined by a common interface.

A state machine is best described by sketching out a basic system in pseudocode:

class StateMachine
{
    Map<String, IState> mStates = new Map<String, IState>();
    IState mCurrentState = EmptyState;

    public void Update(float elapsedTime)
    {
        mCurrentState.Update(elapsedTime);
    }

    public void Render()
    {
        mCurrentState.Render();
    }

    public void Change(String stateName, optional var params)
    {
        mCurrentState.OnExit();
        mCurrentState = mStates[stateName];
        mCurrentState.OnEnter(params);
    }

    public void Add(String name, IState state)
    {
        mStates[name] = state;
    }
}

This code above shows a simple state machine with no error checking.

Let's look at how the above state machine code is used in a game. At the start of the game a StateMachine will be created, all the different states of the game added and the initial state set. Each state is uniquely identified by a String name which is used when calling the change state function. There is only ever one current state, mCurrentState, and it's rendered and updated each game loop.

The code might look like this:

StateMachine gGameMode = new StateMachine();

// A state for each game mode
gGameMode.Add("mainmenu",   new MainMenuState(gGameMode));
gGameMode.Add("localmap",   new LocalMapState(gGameMode));
gGameMode.Add("worldmap",   new WorldMapState(gGameMode));
gGameMode.Add("battle",     new BattleState(gGameMode));
gGameMode.Add("ingamemenu", new InGameMenuState(gGameMode));

gGameMode.Change("mainmenu");

// Main Game Update Loop
public void Update()
{
    float elapsedTime = GetElapsedFrameTime();
    gGameMode.Update(elapsedTime);
    gGameMode.Render();
}

In the example, we create all the states required, add them to the StateMachine and set the starting state to the main menu. If we ran this code the MainMenuState would be rendered and updated first. This represents the menu you see in most games when you first boot up, with options like Start Game and Load Game.

When a user selects Start Game, the MainMenuState calls something like gGameMode.Change("localmap", "map_001") and the LocalMapState becomes the new current state. This state would then update and render the map, allowing the player to start exploring the game.

The diagram below shows a visualization of a state machine moving between the WorldMapState and BattleState. In a game this would be equivalent to a player wandering around the world, being attacked by monsters, going into combat mode, and then returning to the map.

jrpg-state-machine

Let's have a quick look at the state interface and an EmptyState class that implements it:

public interface IState
{
    public virtual void Update(float elapsedTime);
    public virtual void Render();
    public virtual void OnEnter();
    public virtual void OnExit();
}

public EmptyState : IState
{
    public void Update(float elapsedTime)
    {
        // Nothing to update in the empty state.
    }

    public void Render()
    {
        // Nothing to render in the empty state
    }

    public void OnEnter()
    {
        // No action to take when the state is entered
    }

    public void OnExit()
    {
        // No action to take when the state is exited
    }
}

The interface IState requires each state to have four methods before it can be used as a state in the state machine: Update(), Render(), OnEnter() and OnExit().

Update() and Render() are called each frame for the currently active state; OnEnter() and OnExit() are called when changing state. Apart from that it's all pretty straightforward. Now you know this you can create all kinds of states for all the different parts of your game.

That's the basic state machine. It's useful for many situations but when dealing with game modes we can improve upon it! With the current system, changing state can have a lot of overhead - sometimes when changing to a BattleState we'll want to leave the WorldState, run the battle, and then return to the WorldState in the exact setup it was before the battle. This kind of operation can be clumsy using the standard state machine we've described. A better solution would be to use a stack of states.

Making Game Logic Easier With a State Stack

We can switch up the standard state machine into a stack of states, as shown the diagram below. For example, the MainMenuState is pushed on the stack first, at the start of the game. When we start a new game, the LocalMapState is pushed on top of that. At this point the MainMenuState is no longer rendered or updated but is waiting around, ready for us to return to.

Next, if we start a battle, the BattleState is pushed on the top; when the battle ends, it's popped off the stack and we can resume on the map exactly where we left off. If we die in the game then LocalMapState is popped off and we return to MainMenuState.

The diagram below gives a visualization of a state stack, showing the InGameMenuState being pushed on the stack and then popped off.

jrpg-state-stack

Now we have an idea how the stack works, let's look at some code to implement it:

public class StateStack
{
    Map<String, IState> mStates = new Map<String, IState>();
    List<IState> mStack = List<IState>();

    public void Update(float elapsedTime)
    {
        IState top = mStack.Top()
        top.Update(elapsedTime)
    }

    public void Render()
    {
        IState top = mStack.Top()
        top.Render()
    }

    public void Push(String name)
    {
        IState state = mStates[name];
        mStack.Push(state);
    }

    public IState Pop()
    {
        return mStack.Pop();
    }
}

This above state stack code has no error checking and is quite straightforward. States can be pushed onto the stack using the Push() call and popped off with a Pop() call, and the state on the very top of the stack is the one that's updated and rendered.

Using a stack-based approach is good for menus, and with a little modification it can also be used for dialog boxes and notifications. If you're feeling adventurous then you can combine both and have a state machine that also supports stacks.

Using StateMachine, StateStack, or some combination of the two creates an excellent structure to build your RPG upon.

Next Actions:

  1. Implement the state machine code in your favorite programming language.
  2. Create a MenuMenuState and GameState inheriting from IState.
  3. Set the the main menu state as the initial state.
  4. Have both states render different images.
  5. On pressing a button, have the state change from the main menu to the game state.


Maps


Maps describe the world; deserts, spaceships, and jungles can all be represented using a tilemap. A tilemap is a way of using a limited number of small images to build up a bigger one. The diagram below shows you how it works:

jrpg-tiles-to-tilemap

The above diagram has three parts: the tile palette, a visualization of how the tilemap is constructed, and the final map rendered to the screen.

The tile palette is a collection of all the tiles used to create a map. Each tile in the palette is uniquely identified by an integer. For example, tile number 1 is grass; notice the places where it's used on the tilemap visualization.

A tilemap is just an array of numbers, each number relating to a tile in the palette. If we wanted to make a map full of grass we could just have a big array filled with the number 1, and when we rendered those tiles we'd see a map of grass made up from many small grass tiles. The tile palette is usually loaded as one big texture containing many smaller tiles but each entry in the palette could just as easily be its own graphic file.

Tip: Why not use an array of arrays to represent the tilemap? The first array could represent by an array of rows of tiles.

The reason we don't do this is just for simplicity and efficiency. If you have an array of integerss, that's one continuous block of memory. If you have an array of arrays then that's one block of memory for the first array which contains pointers, with each pointer pointing to a row of tiles. This indirection can slow things down - and since we're drawing the map each frame, the faster the better!

Let's look at some code for describing a tile map:

//
// Takes a texture map of multiple tiles and breaks it up into
// individual images of 32 x 32.
// The final array will look like:
//     gTilePalette[1] = Image    // Our first grass tile
//     gTilePalette[2] = Image    // Second grass tile variant
//     ..
//     gTilePalette[15] = Image   // Rock and grass tile
//
Array gTilePalette = SliceTexture("grass_tiles.png", 32, 32)

gMap1Width = 10
gMap1Height = 10
Array gMap1Layer1 = new Array()
[
    2,  2,  7,  3,  11, 11, 11, 12, 2,  2,
    1,  1,  10, 11, 11, 4,  11, 12, 2,  2,
    2,  1,  13, 5,  11, 11, 11, 4,  8,  2,
    1,  2,  1,  10, 11, 11, 11, 11, 11, 9,
    10, 11, 12, 13, 5,  11, 11, 11, 11, 4,
    13, 14, 15, 1,  10, 11, 11, 11, 11, 6,
    2,  2,  2,  2,  13, 14, 11, 11, 11, 11,
    2,  2,  2,  2,  2,  2,  11, 11, 11, 11,
    2,  2,  2,  2,  2,  2,  5,  11, 11, 11,
    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
];

Compare the above code with the diagram and it's quite clear how a tilemap is built up from a small series of tiles. Once a map is described like this then we can write a simple render function to draw it on the screen. The exact details of the function will change depending on the viewport setup and drawing functions. Our render function is shown below.

static int TilePixelSize = 32;

// Draws a tilemap from the top left, at pixel position x, y
// x, y - the pixel position the map will be rendered from
// map - the map to render
// width - the width of the map in tiles
public void RenderMap(int x, int y, Array map, int mapWidth)
{
    // Start by indexing the top left most tile
    int tileColumn = 1;
    int tileRow = 1;

    for(int i = 1; map.Count(); i++)
    {
        // Minus 1 so that the first tile draws at 0, 0
        int pixelPosX = x + (tileColumn - 1) * TilePixelSize;
        int pixelPosY = y + (tileRow - 1) * TilePixelSize;

        RenderImage(x, y, gTilePalette[gMap1Layer1[i]]);

        // Advance to the next tile
        tileColumn += 1;
        if(tileColumn > mapWidth)
        {
            tileColumn = 1;
            tileRow += 1;
        }
    }
}

-- How it's used in the main update loop
public void Update()
{
    // Actually draw a map on screen
    RenderMap(0, 0, gMap1Layer1, gMap1Width)
}

The map we've used so far is quite basic; most JRPGs will use multiple layers of tilemaps to create more interesting scenes. The diagram below shows our first map, with three more layers added it to, resulting in a far more pleasing map.

jrpg-using-tilemap-layers

As we saw previously, each tilemap is just an array of numbers and therefore a full layered map can be made from an array of those arrays. Of course, rendering the tilemap is really just the first step in adding exploration to your game; maps also need to have information about collision, support for moving entities around, and basic interactivity using triggers.

A trigger is a piece of code that's only fired when the player "triggers" it by performing some action. There are lots of actions that a trigger may recognize. For instance, moving the player character on to a tile may trigger an action - this commonly happens when moving onto a doorway, teleporter or the edge tile of map. Triggers may be placed on these tiles to teleport the character to an indoor map, world map or related local map.

Another trigger might depend on the "use" button being pressed. For instance, if the player goes up to a sign and presses "use" then a trigger is fired and a dialog box is displayed showing the text of the sign. Triggers are used all over the place to help stitch maps together and provide interactivity.

JRPGs often have a lot of quite detailed and complicated maps, so I recommend that you don't try and make them by hand, it's a much better idea to use a tilemap editor. You can use one of the excellent free existing solutions or roll your own. If you want to try an existing tool then I definitely recommend checking out Tiled which is the tool I used to create these example maps.

Next Actions:

  1. Get Tiled.
  2. Get some tiles from opengameart.org.
  3. Create a map and load it into your game.
  4. Add a player character.
  5. Move the character from tile to tile.
  6. Make the character smoothly move from tile to tile.
  7. Add collision detection (you can use a new layer to store collision information).
  8. Add a simple trigger to swap maps.
  9. Add a trigger to read signs - consider using the state stack we talked about earlier to display the dialog box.
  10. Make a main menu state with a "Start Game" option and a local map state and link them together.
  11. Design some maps, add some NPCs, try a simple fetch quest - let your imagination run free!


Combat

Finally, on to the fighting! What good is a JRPG without combat? Combat is where a lot of games choose to innovate, introducing new skill systems, new combat structure, or different spell systems - there's quite a lot of variation.

Most combat systems use a turn-based structure with only one combatant permitted to take an action at a time. The very first turn-based battle systems were simple, with every entity getting a turn in order: player's turn, enemy's turn, player's turn, enemy's turn, and so on. This quickly gave way to more intricate systems offering more leeway for tactics and strategy.

We're going to have a close look at Active-Time based combat systems, where combatants don't all necessarily get an equal number of turns. Faster entities may get more turns and the type of action taken also affects how long a turn takes. For instance, a warrior slashing with a dagger may take 20 seconds but a wizard summoning a monster may take two minutes.

jrpg-combat-screen

The above screenshot shows the combat mode in a typical JRPG. Player-controlled characters are on the right, enemy-characters on the left, and a textbox at the bottom shows information about the combatants.

At the start of combat, the monster and player sprites are added to the scene and then there's a decision about which order the entities take their turns. This decision may partially depend on how the combat was launched: if the player was ambushed then the monsters will all get to attack first, otherwise it's usually based on one of the entity stats such as speed.

Everything the player or monsters do is an action: attacking is an action, using magic is an action, even deciding what action to take next is an action! The order of actions is best tracked using a queue. The action at the top is the action that will take place next, unless no faster action preempts it. Each action will have a countdown that decreases as each frame passes.

The combat flow is controlled using a state machine with two states; one state to tick the actions and another state to execute the top action when the time comes. As always, the best way to understand something is to look at the code. The following example implements a basic combat state with an action queue:

class BattleState : IState
{
    List<IAction> mActions = List<IAction>();
    List<Entity> mEntities = List<Entity>();

    StateMachine mBattleStates = new StateMachine();

    public static bool SortByTime(Action a, Action b)
    {
        return a.TimeRemaining() > b.TimeRemaining()
    }

    public BattleState()
    {
        mBattleStates.Add("tick", new BattleTick(mBattleStates, mActions));
        mBattleStates.Add("execute", new BattleExecute(mBattleStates, mActions));
    }

    public void OnEnter(var params)
    {
        mBattleStates.Change("tick");

        //
        // Get a decision action for every entity in the action queue
        // The sort it so the quickest actions are the top
        //

        mEntities = params.entities;

        foreach(Entity e in mEntities)
        {
            if(e.playerControlled)
            {
                PlayerDecide action = new PlayerDecide(e, e.Speed());
                mActions.Add(action);
            }
            else
            {
                AIDecide action = new AIDecide(e, e.Speed());
                mActions.Add(action);
            }
        }

        Sort(mActions, BattleState::SortByTime);
    }

    public void Update(float elapsedTime)
    {
        mBattleStates.Update(elapsedTime);
    }

    public void Render()
    {
        // Draw the scene, gui, characters, animations etc

        mBattleState.Render();
    }

    public void OnExit()
    {

    }
}

The code above demonstrates the control of the battle mode flow using a simple state machine and a queue of actions. To begin with, all the entities involved in the battle have a decide-action added to the queue.

A decide-action for the player will bring up a menu with the RPG stable options Attack, Magic, and Item; once the player decides on an action then the decide-action is removed from the queue and the newly chosen action is added.

A decide-action for the AI will inspect the scene and decide what to do next (using something like a behavior tree, decision tree or similar technique) and then it too will remove its decide-action and add its new action to the queue.

The BattleTick class controls the updating of the actions, as shown below:

class BattleTick : IState
{
    StateMachine mStateMachine;
    List<IAction> mActions;

    public BattleTick(StateMachine stateMachine, List<IAction> actions)
        : mStateMachine(stateMachine), mActions(action)
    {
    }

    // Things may happen in these functions but nothing we're interested in.
    public void OnEnter() {}
    public void OnExit() {}
    public void Render() {}

    public void Update(float elapsedTime)
    {
        foreach(Action a in mActions)
        {
            a.Update(elapsedTime);
        }

        if(mActions.Top().IsReady())
        {
            Action top = mActions.Pop();
            mStateMachine:Change("execute", top);
        }
    }
}

BattleTick is a sub state of the BattleMode state and it just ticks until the top action's countdown is zero. It then pops the top action out of the queue and changes to the execute state.

jrpg-action-queue

The diagram above shows an action queue at the start of a battle. No one has yet taken an action and everyone is ordered by their time to make a decision.

The Giant Plant has a countdown of 0, so on the next tick it executes its AIDecide action. In this case the AIDecide action results in the monster deciding to attack. The attack action is almost immediate and gets added back into the queue as the second action.

On the next iteration of BattleTick, the player will get to choose which action his dwarf "Mark" should take, which will change the queue again. The next iteration of BattleTick after that, the Plant will attack one of the dwarves. The attack action will be removed from the queue and passed over to the BattleExecute state, and it will animate the plant attacking as well as doing all the necessary combat calculations.

Once the monster's attack is finished another AIDecide action will be added to the queue for the monster. The BattleState will continue this way until the end of the combat.

If any entity dies during the combat all its actions need to be removed from the queue - we don't want dead monsters suddenly reanimating and attacking during the game (unless we're purposely making zombies or some kind of undead!).

The action queue and simple state machine are the heart of the combat system and you should now have a good feel for how it fits together. It's not complete enough to be a standalone solution but it can be used as a template to build something more fully functioning and intricate. Actions and states are good abstraction that help manage the complexity of combat and make it easier to expand and develop.

Next Actions:

  1. Write the BattleExecute state.
  2. Perhaps add more states, such as BattleMenuState and AnimationState.
  3. Render backgrounds and enemies with basic health stats.
  4. Write a simple attack action and run a simple battle of trading attacks.
  5. Give entities special skills or magic.
  6. Make an enemy that will heal itself if below 25% health.
  7. Create a world map to launch the battle state from.
  8. Create a BattleOver state that shows loot and XP gain.


Review

We've had a high level look at how to make a JRPG, diving into some of the more interesting details. We've covered how to structure code using a state machine or stack, how to use tilemaps and layers to display our world, and how to control the flow of combat using an action queue and state machine. The features we have covered make a good base to build on and develop from.

But there's also a lot that hasn't been covered at all. Making a full JRPG includes XP and leveling systems, saving and loading of the game, lots of GUI code for the menus, basic animations and special effects, states for handling cutscenes, combat mechanics (such as sleep, posion, elemental bonuses and resistances), to name just a few things!

You don't need all these things for a game, though; To The Moon basically had only map exploration and dialog. You can incrementally add new features as you make your game.

Where to Go From Here

The hardest part of making any game is finishing it, so start small, think of a mini-rpg; escape a dungeon, a single fetch quest, and then build up. If you find you're getting stuck then reduce the scope of the game, make it simpler and finish it. You might find as you develop you get lots of new and exciting ideas, which is good, write them down but resist the urge to increase the scope of your game, or even worse start a new one.

Making a JRPG is hard; there are a lot of systems, and without a good map it can be difficult to know which to tackle first. A thorough step-by-step guide to building a JRPG would fill a book! Fortunately, I'm writing that book, so if you want a more detailed guide to making a JRPG then please check it out.



Resources Used

A number of resources and creative commons assets were used to to help put together this article:

Advertisement