RPG tutorial

From Platinum Arts Sandbox Free 3D Game Maker
Revision as of 22:00, 5 October 2011 by Hirato (Talk | contribs) (Part 5)

Jump to: navigation, search

The following tutorials are only meant to cover the basics of developing for the RPG. Each of the tutorials build upon the work from the previous exercises and are therefor best done in order.

Part 1

This part covers making the initial skeleton of our game.


By default the RPG detects the available games by searching data/rpg/games for cfg files, these files form the basis of what the main menu will list as the available games. In selecting a game from the menu, it will then attempt to load the definitions from an equivalently named directory.

We now know the first step to making our own tutorial game, we need a corresponding cfg and directory inside data/rpg/games'

Luckily sandbox comes with a base that can be derived to quickly get things up and running, so first up, let's make a copy of the base directory and call the copy "tutorial" and then move a file named base.cfg inside data/rpg/games/tutorial into data/rpg/games and rename it to tutorial.cfg.

We can essentially open up our game in sandbox now, but we still have a few things to do, so for now, open up tutorial.cfg in your favourite text editor. The contents should be pretty self explanatory but we do need to make a few specific changes.

Firstly, we want to set the default map and associate it with mapscript 0, for this excercise we'll name our map tutorial1.

Secondly, we want to set the version number and the compatibility number to 1.

Finally, we will want to specify a HUD to use for our game. Sandbox currently only ships one, so we will execute it here.

The final version of tutorial.cfg should look similar to this

 r_reparemap tutorial1 0
 
 firstmap tutorial1
 
 gameversion 1
 compatversion 1
 
 exec data/rpg/games/hud_standard.cfg

Save it and we have one more step to go, we need to make a map named tutorial1, so fire up sandbox and save a newmap under that name.

Congratulations! you have successfully set up the basics required to make your RPG with sandbox

Addendum

game.cfg has two explicit purposes. Firstly it identifies the existence of a game and secondly, it defines many of the important attributes of the game.

things that can and should be defined in game.cfg include

  • the script and flags to use on a maps
  • internal properties, such as the game version
  • global game properties, such as friendly fire
  • rule properties (currently not available)
  • the initial/default HUD

Part 2

This section of the tutorial involves spawning a neutral NPC and assigning him some dialogue


We can go about this in a few ways, but we'll start by first defining the NPC's script, the NPC, and then creating a place for him in the world.

First off, go to your definitions directory (probably data/rpg/games/tutorial) and then enter the script subdirectory. You will not want to create a new configuration file and place it at the very end of the others (eg, if the last is named 7.cfg, name yours 8.cfg). In this file, we define how any entities using it will react and interact with the surrounding world. Since we don't want to bother with that, we will simply include the default NPC script.

Afterwards we can start defining the dialogue. When you're done the final script should look something like this. Feel free to experiment by writing more dialogue and fleshing out your character

 include scripts/1 //includes the default NPC script
 
 r_script_say "Hello, how are you doing" [ // 0 - it's good practice to number your entries
   r_response "I'm well, yourself?" 1 //goes to dialogue #1
   r_response "Goodbye" -1 //closes the dialogue
 ]
 
 r_script_say "I'm glad to hear it" [ // 1
   r_response "Goodbye" -1
 ]

With that taken care of, we will now define a critter to use the script. All critter configuration options are prefixed with r_char and most contain a variant with a _get suffix for retrieving the value. Now create a new cfg file in the critter sub directory, following the same steps as you did for the script to define it's name. This will probably be 0.cfg.

Consult the configuration reference for a full list of available configuration options, for now, copy the following into critters/0.cfg

 r_char_name "Bob"
 r_char_mdl "ogre"
 r_char_script 8 //make sure this corresponds with the above script

Finally, we need to spawn Bob, so start your game and create a critter entity that spawn a critter of type 0. Remember that F1 toggles editmode in the RPG!

 newent critter 0

You're done, to test it simply exit editmode and press E while hovering the crosshair over him.


Addendum

Default Scripts

The various definition types of the RPG each default to their own individual specialized script. They correspond as follows

  • 0 - null/empty/nothing
  • 1 - Default critter script; primarily initiates dialogue, will in the future control AI logic and stealth abilities
  • 2 - Default item script; mainly implements pickup
  • 3 - Default obstacle script; does nothing
  • 4 - Default container script; will eventually allow you to pick the lock and loot items
  • 5 - Default platform script; does nothing
  • 6 - Default trigger script; toggles triggered state (eg, switches door between open and close)

Note that the player defaults to script 0, and has its script explicitly set to 7. Script 7 contains some basic player logic, mainly it lets you know when you level up.

Definition numbering

The numbers allows the game to easily and quickly identify and order definitions, unfortunately this is inconvenient to the users since it makes identifying which definition corresponds to an item you're looking for a bit of a chore. The only thing you need to remember, is that each definition must be assigned number from 0 and up and that there cannot be any empty gaps. Duplicate numbers (eg hex or octal) and non-number names will throw a warning.

$ ls
1.cfg  2.cfg  3.cfg  4.cfg  5.cfg
# the game will abort with these files


$ ls
0.cfg  1.cfg  2.cfg  3.cfg  4.cfg
# the game will start

Multiple dialogue entry points

The entry point is defined by the talk signal, by default this simply opens the dialogue at position 0 should it exist. If you'd like to change the entry point you will have to redefine the talk signal for your entity. For example...

 r_script_signal talk [
   if $cond [
     r_chat self 0
   ]
     r_chat self 2
   ]
 ]

You can add more more conditions and variables and you are allowed the full range of cubescript commands.

Dialogue standards

There are no fixed standards, but we recommend the following conventions when writing dialogue for your characters.

 r_script_say "Things the creatures say are simply typed like this, no surrounding quotes" []
 r_script_say "If you wish to put *emphasis* on a word, place *'s on both sides]" []
 r_script_say "[between these brackets, write what your character sees and experiences]" [
   r_response "[Likewise, place any actions your character takes here]"
 ]

Part 3

This section of the tutorial covers basic item definitions, trigger basics and crafting.

For this exercise we will craft papyrus sheets, we will write on these to produce our weapon in the next part. This process demands the use of a knife, a hammer and something heavy to compress it while drying. The important part is the materials that are used in the process and those that enable the process, we recommend ignoring the process itself.

So first up, let's define the ingredients, the tools we're going to use and the product we're going to make. If you've followed the tutorial thus far, you should still have 0 item definitions, otherwise follow the previously defined rules. Save the following in the items subdirectory. The commands and their effect should be self-explanatory

0.cfg

r_item_name "Papyrus reed"
r_item_description "Freshly harvested from the Papyrus plant, the stem of these reeds have been used for centuries to create a durable writing surface."
r_item_mdl "tentus/moneybag"

1.cfg

r_item_name "Old Knife"
r_item_description "The blade has seen a lot of use and is missing a few chips, but remains deadly sharp."
r_item_mdl "tentus/moneybag"

2.cfg

r_item_name "Old Mallet"
r_item_description "The mallet appears to have seen a lot of use, but remains effective for beating things."
r_item_mdl "tentus/moneybag"

3.cfg

r_item_name "Papyrus"
r_item_description "Papyrus reeds have been converted into a durable surface suitable for writing on."
r_item_mdl "tentus/moneybag"

Next, we will define the recipe. A recipe has 3 lists of items, the ingredients, the catalysts and the products. Ingredients are items that are consumed in full to produce the products and catalysts are items that enable the process to happen.

For now, copy the following to recipes/0.cfg

r_recipe_flags $RECIPE_KNOWN //we know the recipe at the start

r_recipe_add_ingredient 0 10 // 10 x papyrus reeds

r_recipe_add_catalyst 1 1 // 1 x knife
r_recipe_add_catalyst 2 1 // 1 x hammer

r_recipe_add_product 3 1 // 1 x papyrus

We now have everything we need to create the final item, we simply need to spawn them into the world. If you are in a hurry to test it out, use the following commands to spawn them in the world.

newent item 0 10 //skip this if you aren't in a hurry
newent item 1 1 //knife
newent item 2 1 //hammer

If you're still here, we're now going to make actual harvestable papyrus plants using triggers, since we lack a suitable model we will improvise using one for reeds. First we will define a suitable script. Our trigger's script will add a random amount between 1-4 reeds to the player's inventory and then destroy itself. If we wanted, we could toggle a variable and change the model so it looks as though it was harvested and perhaps even respawn it after a few while of game time, but that's a more advanced topic for another time. So for now, copy the following into scripts/9.cfg.

 //papyrus reeds
 
 r_script_signal interact [
   // adds between 1-4 units of papyrus to whoever harvests it
   r_additem actor 0 (rnd 5 1) 
   // removes itself from the stack
   r_destroy self
 ]

As for the trigger itself, copy the following into triggers/0.cfg.

r_trigger_name "Papyrus plant"
r_trigger_mdl "dcp/reed"
r_trigger_script 9

Congratulations, just spawn a few of those near a body of water somewhere, and you've finish this section of the tutorial. The command is of course as follows

newent trigger 0

Addendum

Splitting the process

The general recommendation is to try and contain the whole process in a single recipe. Rather than splitting it out into many small pieces. As a rule, try to avoid making the player learn and execute the process and let taht be handled via the character's knowledge. For example, if we wanted to create stew in a more contemporary setting, the recommended recipe would be something like this.

Ingredients

  • 3 x Potatoes
  • 1 x Unions
  • 5 x Carrots
  • 1 x Butane canister

Catalysts

  • 1 x Knife
  • 1 x Cutting board
  • 1 x Pot
  • 1 x Portable gas cooker

Products

  • 5 x Stew

Likewise, the strongly not recommended series of recipes may look something like this

Ingredients

  • 1 x Potato

Catalysts

  • 1 x Knife
  • 1 x Cutting board

Products

  • 5 x Sliced potato


Ingredients

  • 1 x Union

Catalysts

  • 1 x Knife
  • 1 x Cutting board

Products

  • 5 x Sliced union


Ingredients

  • 1 x Sliced union

Catalysts

  • 1 x Knife
  • 1 x Cutting board

Products

  • 5 x Diced union


Ingredients

  • 1 x Carrot

Catalysts

  • 1 x Knife
  • 1 x Cutting board

Products

  • 5 x Sliced carrot


Ingredients

  • 15 x Sliced Potatoes
  • 25 x Diced Unions
  • 25 x Sliced Carrots
  • 1 x Pot

Products

  • 1 x Uncooked Stew


Ingredients

  • 1 x Uncooked Stew
  • 1 x Butane canister

Catalysts

  • 1 x Portable gas cooker

Products

  • 1 x Pot
  • 5 x Stew


Skilled Craftsmen

If you want to add a recipe that depends on skills to be used, you can use the r_recipe_reqs family of variables to set them. You're allowed to utilise the full family of stats and skills to define skill requirements for a recipe.

Part 4

This part covers covers particle effect definitions, status effect definitions and item usage definitions with the example of a weapon. The player will be able to craft it with the materials from the previous part.

Let's dive right into it. We're going to create 2 items and an additional recipe. For the first item, we need some means of writing on the papyrus we created in the previous session. The second item will be the weapon we will produce, for now we will just create a small skeleton for it. We should currently have 4 items defined, if not adjust numbers accordingly.

4.cfg

r_item_name "Ink Well"
r_item_description "It is a phial of ink. Paired with a quill these are still very popular writing instruments."
r_item_mdl "tentus/moneybag"

5.cfg

r_item_name "Magic Arrow"
r_item_description "Upon this scroll of papyrus rest incantations for a magical spell."
r_item_mdl "tentus/moneybag"

Next we will define the recipe to produce the weapon, we should currently only have a single recipe, adjust accordingly if this isn't the case.

1.cfg

r_recipe_flags $RECIPE_KNOWN

r_recipe_add_ingredient 3 1 // 1 x papyrus
r_recipe_add_ingredient 4 1 // 1 x ink

r_recipe_add_product 5 1 // magic arrow scroll

We now have to deal with the most important part to make any weapons, swords, spells or otherwise. We need a status group to do something. Zero of more status effects comprise each group, and this design decision mainly exists to accommodate spells like polymorph and their respective dispelling. The statuses sub directory should already contain a dummy group, once again, adjust the numbers as required for our own.

1.cfg

//heavy damage
r_status_friendly 0 //this is decidedly hostile
r_status_addgeneric $STATUS_HEALTH -100 0 // instantly remove 100 HP

We currently have everything we need to define our weapon/spell, but we unfortunately won't be able to see the projectile at present due to having no particle effects defined. Projectiles can have up to 3 effects, that is the projectile itself, its trail and the explosion at the end. -1 can be substituted in any of the effect slots to disable emissions for that part. We will define the following 2 effects in the effects subdirectory.

0.cfg

// flying arrow
r_effect_mdl "hirato/arrow"
r_effect_flags 0

1.cfg

// purple magic sparkles
r_effect_flags 0
r_effect_particle $PART_STEAM
r_effect_colour 0x3F003F
r_effect_size  0.5

We now have everything we need to define our weapon fully as well as be able to see any of its attacks. To make the weapon usable, we need to define a use case in which it is a weapon. We have 3 possible use cases, use (eg, read, drink), armour and weapon, the last two are implemented and fully functional while the first isn't. Naturally we want the weapon use case.

So to define our weapon fully, open up items/5.cfg and add the following at the end. Generally speaking you don't need to define quite as many properties, most of these are here just to be sure things work as expected.

r_item_use_new_weapon // 0 - it's good practice to number these entries

//these slots are available in consume and armour use cases as well
r_item_use_name "Magic Arrow"
r_item_use_description "An arrow is conjoured from the caster's finger tip and flung at its target with sheer mental will."
r_item_use_cooldown 1500
//increases the strength of the spell with player skill or charging
r_item_use_chargeflags $CHARGE_MAG
// adds our status effect at 30% efficiency - with the above charge flag that means 30 damge 
r_item_use_new_status 1 $ATTACK_MAGIC 0.3

//these slots are available with armour use cases as well
r_item_use_slots $SLOT_LHAND
r_item_use_skill $SKILL_MAGIC

//these slots are exclusive to weapons
r_item_use_pflags $P_TIME
r_item_use_angle 0
r_item_use_lifetime 1000
r_item_use_gravity 0
r_item_use_projeffect 0 //substitute with your arrow's effect
r_item_use_traileffect 1 //substitute with your trail's effect
r_item_use_deatheffect -1 //replace with a suitable EoL effect
r_item_use_ammo -1 //use mana
r_item_use_cost 15 //uses 15 units of mana
r_item_use_kickback 10
r_item_use_recoil 10
r_item_use_target $T_SINGLE
r_item_use_speed 1.1 // in 100's of cubes a second

Congratulations! Just spawn the ink well somewhere and craft your weapon, and have some fun. In the next part we will make several mobs for you to use it against.

Addendum

Reserved ammo types

Specifying ammo 0 and above for a use case means you're going to use items from the respective ammo group. In addition there are also 3 additional ammo types that occupy numbers -1, -2 and -3. they are as follows.

  • -1 - Mana
  • -2 - Health
  • -3 - Experience

$STATUS_HEALTH, $RECIPE_KNOWN, what is all this stuff!?

These are hard coded RPG constants that are reproduced inside data/rpg/game.cfg and are usually kept in sync. We strongly recommend that you use these constants/variables as opposed to using the numbers directly, this helps ensure future compatibility and makes it easier to understand the intended effect of the definitions if updates are required.

The file contains all of the various flags and numbers that are available in the RPG, so being familiar with them will be a great boon to you if you choose to use sandbox.

Part 5

This section of the tutorial covers debug settings, waypoints, and basic AI by making a hostile mob for the player to defeat. Before we even consider adding any AI or monsters, we need to canvas our map with waypoints for the AI to follow and get to the player.

But before we get to the waypoints, there is a more critical item to consider, we need to shelter the beast first, so that it doesn't attack the player immediately, specifically so that the player has a chance to build his weapon before taking on the beast. I'd suggest erecting a wall behind Bob's house, see the screenshot on the right for a recommended layout.

Our second order of business is to then enable the AI debug channel so that we can see the waypoints we're dropping and then to canvas the area. Considering the terrain will be mostly flat, you may wish to turn on the experimental waypointing method as well.

debug 32 //ai debug channel
dropwaypoints 1 //required to drop waypoints
experimentalwaypoint 1 //method that links to all nearby nodes, as opposed to tracing a path
savewaypoints // saves them when you're done DO NOT FORGET TO DO THIS!!!

REST OF TUTORIAL HERE

Addendum

The debug variable is a set of flags, you can toggle most of them from the options menu under the game tab, but here they are, reproduced in full.

  • 1 - World - draws misc information on the HUD and prints some information on the map stack
  • 2 - Entity - draws entity pointers above head and prints when more are spawned and destroyed as well as their deaths and a few other things
  • 4 - Configuration - prints what various properties were set to when loading definitions
  • 8 - Projectiles - prints hit testing details and renders a pointer string over the projectile
  • 16 - Script - informs you of most executed commands and any sent and received signals (when verbose)
  • 32 - AI - draws waypoints and pritns any received commands
  • 64 - I/O mainly lets you know what is being read from savegames
  • 128 - Camera, draws cutscene information on the HUD
  • 256 - Verbose, makes the rest spammier

Part 6

This section of the tutorial involves creating a fetch quest, mapflags and teleports

Part 7

This part of the tutorial involves the creation of a basic puzzle to open a door as well as overriding the HUD