How to Make an RPG

In this tutorial, you’ll learn how to use pre-built frameworks to create your own reusable RPG engine. By the time you’re done, you’ll have the groundwork to create the RPG of your dreams! By .

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Quest-Making Power

What's an RPG without questing? Since you have the groundwork for your game and interaction, the last phase is to build out an API with which your Lua characters can interact.

This way, you can make your NPCs say or do different things based on the stage of the quest the hero is on.

To build quests, you need to be able to keep track of quest progress. For this simple game, NSUserDefaults is a quick and easy way to do this. If you like, you can implement something more advanced with Core Data, sqlite or some network-backed storage system.

Think for a moment about what kind of data you'll need to store. Say, for example, that you have a quest where the player is tasked to deliver a letter from “Kid” to “Old Man.”

Well, when the player speaks to the Old Man without having first received the quest from the Kid, the Old Man might respond with, "Nice weather we’re having." He will know that the player doesn't have a letter for him by checking a specific key in the NSUserDefaults (or database).

The Kid will give the player a quest by setting a value for a specific key. Then, when the player revisits the Old Man, the Old Man will see that value, clear it out and reward the player (perhaps by updating the value of a money key).

When you start to think about the game from this perspective, the possibilities are limited only by your ability to come up with stories! Let's see how to implement such methods for storage that will aid you in your quest for quest-making power.

Add the following two methods to GameLayer.m:

- (void) setMeta:(NSString *)value forKey:(NSString *)key
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:value forKey:key];
    [defaults synchronize];
}

- (NSString *) getMetaValueForKey:(NSString *)key
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    return [defaults objectForKey:key];
}

These are just some helper methods to get and store some meta information. Think of it as a global dictionary for information shared across your LUA objects.

That's it! You now have a basic storage mechanism for your game. These two methods provide you with a simple wrapper around NSUserDefaults. setMeta:forKey: stores a key/value pair and getMetaValueForKey: retrieves the value.

In theory, you could save the entire game state using only these two methods.

Now to make the player’s interaction with the soldier more interesting using these methods. Open up room-soldier.lua and replace the interact method with the following code:

function soldier:interact()
    if self.game:getMetaValueForKey("room_soldier_greeting") == "true" then
        self.game:npc_say("soldier","Please return her home safely.")
    else
        self.game:npc_say("soldier", "You must save the princess! She has been taken!")
        self.game:setMeta_forKey("true","room_soldier_greeting")
    end
end

The first time the player interacts with the soldier, the "room_soldier_greeting" key won't be set and he will respond with "You must save the princess! She has been taken!" The key will then be set to "true" so that the game knows that the player has received the quest.

When the player interacts with the soldier after that, the soldier will recognize the key and respond with, "Please return her home safely." If you wanted to, you could set another flag indicating that the quest is active, and so on.

What's great about this method is that any NPC can access any key/value pair, even ones set by other NPCs. That's how NPCs interact with each other “behind the scenes,” and that's how you can set up your quests between multiple NPCs.

At this point, your creative juices should be flowing as you start to imagine all of the possibilities this brings!

Where To Go From Here?

And with that, you have the basic components for a full-fledged RPG. You can download the final project here.

If you would like to build up your API a bit more and add additional layers of interactivity, here are some suggestions:

  1. Dialog: Update the chat box to take parameters from which the the player can choose. When the player makes a choice, send that value back to the NPC. Once you’ve done this, you can begin to form entirely new systems – stores, monster battles, forks in stories, and so on!
  2. Move NPC: Perhaps an NPC blocks your character's path and the only way to proceed is to move him out of the way. Create an API call that allows an NPC to move themselves based on some criteria.
  3. Animating NPCs: Build up your system even more to allow the NPCs to walk around. You could do this by exposing the animation methods for a given sprite sheet.
  4. Queue for NPC behaviors: Perhaps there is an epic dialog between characters. As of right now, you would have to fake it inside of a single NPC file, but it would be cool if there were a global event queue to which NPCs could add, so that all of the NPCs could queue events for themselves as well as for others.

Here are still more enhancements you could make to the overall game:

  1. An actual story with more characters: Your game is a little boring with only one talking soldier!
  2. Music: Perhaps use Cocos2D's built in audio engines to dynamically load music based on the tile map. That way, when the player switches rooms, the music will switch, too.
  3. Random enemy encounters: If you implement #1 from the list above, this becomes pretty easy. Perhaps use the green meta tile to overlay areas where enemies could lurk. Then add some keys to the tile set that relate to the types of enemies that lurk there. Once the player moves over the highlighted area, do a random roll to see if an enemy is encountered, and if so, treat the enemy like an NPC and use the get/set meta methods to simulate health.
  4. Stats: Use the game state to keep track of a player's inventory, equipment, health and other stats.

As you can see, building an RPG from scratch isn't for the faint of heart. Luckily, you have incredible tools like Cocos2D, Lua and Tiled to assist you in your quest. You could easily reuse the engine you built in this tutorial to make countless games by swapping out the tile sets and Lua files.

If you have any questions or comments, feel free to reach out to me on Twitter or leave them in the forum for this post. Happy Coding!