Gw Temp

Menu

Tutorial - 'RM2K Pointer Tutorial' by Rast

An item about RPGMaker 2000 posted on

Blurb

Learn how to use pointers in Rm2K. A powerful advanced feature for RPGMaker 2000. If you don't know what it is, now is a time to look!

Body

RM2K POINTER TUTORIAL
---------------------

This tutorial explains how to use pointers, or variables that point to other variables. This is a powerful advanced feature of RM2K that I don't see people use much, but makes creating large and complex systems much easier with a bit of planning and some know-how.

This is an ADVANCED TUTORIAL. This means that if you don't already know the ins and outs of RM2K's event system you're going to get lost fast. But, if you've already made a game or two and are trying to figure out how to put together a good custom system, you're in the right place, and I hope you find my document useful.

This tutorial wil not give you step by step instructions on how to make any specific type of custom system. The examples I present are only examples and if you actually want to make the kind of system decribed in the examples you'll have to flesh them out yourself. Rather, it is intended to explain how to use pointers to create a foundation for your own custom systems.

What is a pointer?
------------------

A pointer is a variable that contains the ID number of an other variable, a map event, or a switch. You can access the data or event the variable is pointing at by using the "variable no" pointer reference (for either the target variable or source variable), the variable switch option, or the variable option for the Call Event event.

By doing this, you can refer to the switches, variables, or events indirectly. This allows for your events to access arbitrary data or multiple identical events in a common manner (i.e, just change one variable (the pointer), and do your stuff and it's doing it to a different thing). We'll go over some examples of how this is useful later, after we do a more in-depth look at each type of pointer use.

Use #1 - Variable pointing to variable
--------------------------------------

So, you're asking, "Why do I need to have one variable refer to another instead of just using the variable the normal way?". Well, the reason you would want to set up this kind of a system is because this is the easiest way to set up data structures in RM2K.

Envision, for a moment, a CBS system that supports up to 10 enemies. Now say, for each enemy, you have 4 stats, the ID number of the enemy, his HP, his attack power, and defense power. For a system that supports up to 10 enemies, that means you're using 40 variables for your system.

Now, there's really only two ways you can get info in and out of your 40 variable system we just set up - you can either do it the long way with a huge common event, or you can use a data structure.

To set up this kind of a data structure, just take 40 varaibles (make sure they're all in one long block, it's important), and set them aside for this system. You must set them all up identically, for example:

761) Monster #0 ID No (Stat #0)
762) Monster #0 HP (Stat #1)
763) Monster #0 ATP (Stat #2)
764) Monster #0 DFP (Stat #3)
765) Monster #1 ID No (Stat #0)
766) Monster #1 HP (Stat #1)
767) Monster #1 ATP (Stat #2)
768) Monster #1 DFP (Stat #3)
...
800) Monster #9 DFP (Stat #3)

We start numbering the data structures at zero because it makes it easier to calculate the offset, which we're getting to shortly.

Now, we have to set up a common event to get data in and out of data structure. This event takes 3 variable and one switch parameter.

So, say for example, we set it up like this:

Variable 801) Monster Number
Variable 802) Stat Number
Variable 803) New Value or Return Value
...
Switch 1225) Write Flag

So, say you want to know the HP information on monster six. You'd set variable 801 to 6 (the monster's number), variable 802 to 1 (the stat number), you wouldn't do anything to variable 803 since the event will return the monster's HP there, and you'd set switch 1225 to OFF since you're reading the variable and not writing to it.

Now you'd call your common event, which would do the following:

1) It would generate a pointer as follows:
a) Since each individual data item in the structure is four variables long, it would multiply your monster number (in variable 801) by four.
b) It would add the stat number to that value to get the final offset from the beginning of the data structure.
c) It would add 761 (which is the top of the data structure in our example) to that value to get the final pointer. This number refers to the variable that is actually holding the data you're interested in.
2) It would check switch 1225 (the write flag in our example), and if it's ON, it would take the value in variable 803 (the new value or return value in our example), and write it into the variable that our pointer is pointing at (again, using the "Variable No" variable instruction). If it's OFF, it'll take the value in the variable that our pointer is pointing at and place it in variable 803.
3) The event would terminate and return to the calling event.

So how is this any more useful than the old method where you just refer to everything manually?

Well, let's take our example a step further. Say we need to scan in our CBS to see if any enemies have been defeated (at 0 or less HP). We can do it the old and do 10 forks and check them all, or we can do it like this:

Set variable 801 to 0 (the first monster ID)
Set variable 802 to 1 (the stat number for HP in our example)
Set switch 1225 (the write flag) to OFF to read it
Cycle
Call Event (our data structure event we just talked about)
If variable 803 is 0 or less do whatever we need to do when this enemy is defeated
Set variable 801 +1 (increment one to the next enemy)
If varible 801 is 10 Break Cycle (since 9 is the highest enemy number in this example)
End Cycle

This type of cycle allows you to set things up once and then just cycle through it and do it to all your enemies. You could do just about everything with your enemies in this example with this type of a cycle, and in reality, if you wanted to make a real CBS, trying to manage your enemies (and party members too!) any other way would quickly turn into a huge mess of event code. I'm sure you can think up other uses, data structures are useful anywhere you have multiple identically set up custom anythings.

Use #2 - Variable pointing to switch
------------------------------------

In this use, you can use a variable to refer to switch to set it on or off. You can only set switches in this manner, not read them, which significantly reduces this use's usefulness. Still, there are some uses, such as when you need to set a switch in response to variable input (such is in some sort of dial puzzle or whatever you can come up with). If you really need to reference switches that you can read and write, I suggest you simulate a switch by using a variable (just have 0 be off and any non-zero value be on)

Use #3 - Variable Pointing to Map Event
---------------------------------------

In this use, you take your variable and you use it to refer to a map event. Actually, for this type of a system, you'd need two variables, one to refer to the map event and another to the event page. You can use these variables via the "Call Event" event to call an event without directly referencing it.

This is most useful for when you have a number of identical events in different places on your map. For example, say you have a puzzle that the player must assemble. The puzzle is 5x5 grid of puzzle pieces with one piece missing to make a hole that allows the player to slide the pieces around.

To set this type of puzzle up, I would set up one "master" event that would take the player's input via an Enter Password event, and 24 (25 minus the hole) events that all have an identical page 1 that controls their sliding motion (it would check to see if the hole was next to them in the direction the player just indicated he wanted the puzzle shifted, and if it is, it would slide the event into the hole). These events would all also have a page 2 that, when called, would check to see if the puzzle piece was in the correct position to solve the puzzle, and if it is, it would increment a variable (the same variable for all pieces). These events must have a solid block of ID numbers, say, 2-25 for this example.

So, the player activates the puzzle. The master event reads the player's input via an Enter Password event, and when it detects directional input, it cycles through all the Page 1s of the puzzle events to slide the puzzle around (the cycle is the reason why the events' ID numbers should be in a solid block. If they're not, you'll have to call all the events manually), and then it sets the Page 2 variable to zero and cycles through all the events again and calls Page 2 (the solve page) this time. If the page 2 event is equal to 24 when the cycle terminates, you know all 24 pieces are in the correct positions and the puzzle is solved.

Now for another example, this one using pointers to events and data structures together.

Say you have 20 arbitrary (player-defined) NPC's that can be anywhere on a map. You have to take these 20 NPCs and put them in the right places on the map when the player first walks into it or the map otherwise resets. I can envision this kind of a system being used in some sort of a party switch system, and I did something similar to this in the stable wing of the monster arena in Dragon Destiny.

So, you set up your data structure as above. We have 20 data structure entries as follows:

Stat 0) NPC ID Number (so the NPC will know what it is)
Stat 1) NPC X Coordinate on the map
Stat 2) NPC Y Coordinate on the map

And we throw in an extra variable so the events will know which data entry is them:

- Current Data Structure Entry
- This Event ID Number (one for each of the 20 events, so each event will know what it is after it's set up)
- This Event ID Number (And one more for a common event)

Now we set up our 20 NPC events. Like above, these need to have a solid block of ID numbers, say, 1-20. There also needs to be a 'master' event that will auto-start and run once whenever the room is reset to set everything up again.

The NPC events all need to be totally identical, since each of the 20 events can represent any of the NPCs, depending on how the player set it up. You'll need to set them up as follows:

Page 1
------
This page has no starting conditions, and is activated by Push Key, so it will always be the one running except when a different page is manually called. This page is what the player will see and actually walk up to and interact with (if the event is in an accessable location on the map). It should have a blank look (Future 1-4 is good for this) since it's actual appearance will be set up by Page 2. For it's actions, it should check it's own ID number (which is set up by Page 2) and set the common event's This Event ID Number variable, and call the common event, which will take it's action (we'll talk about this in a moment)

Page 2
------
This event sets it up. Current Data Structure Entry will have already been set by the calling (master) event, so all this event needs to do is get it's ID number, X coordiante, and Y coordinate out of the data structure. It should record the returned ID number in this event's This Event ID Number variable, and then run it through a series of forks, and change it's appearance using the Move Event event command to set this event to however the player has set it up previously, and then use the Set Event Place event command to place itself at it's X and Y coordinates.

The master controller event should auto-start and run once and only once whenever the map resets. You can do this easily by setting the event up to auto-start and having it's last action be a "Clear Timer" event command, which will clear the event until the next time the room resets.

This event should be set up as follows:

Set Current Data Structure Entry to 0
Set the event pointer to 1 (the first dynamically set up event)
Set the page pointer to 2 (the set-up page for our dynamically set-up events)
Cycle
Call Event (event pointer) Page (page pointer)
Current Data Structure Entry +1
If Current Data Structure Entry is 21 Break Cycle (since 20 is the last dynamically set up event)
End Cycle
Clear Timer

And the common event will be called whenever the player tries to interact with one of our dynamically set up events. The event will set the Common Event's This Event ID Number to the map event's This Event ID Number and call the common event. The common event should fork through every possible value of the event's ID Number and take the appropriate action (such as displaying a bit of dialog).

So now you're scratching your head and wondering how this would all actually work. So, here's the end result of this example, if it were used in a party switch system.

Say the player doesn't have Joe or Shane in his party. These two would be dynamically set up events wandering about in the party switch place (such as an airship). Now say he walks up to Joe and hits the action button. The event that had been dynamically set up to be Joe would pass it's ID number ot the common event, thus telling the common event that it was supposed to be Joe at the moment, so it would fork through until it found Joe's dialog and display it.

Now say the player decides he needs Joe so he takes Joe and leaves Amy in his place. The data structure would be updated to remove Joe and add Amy in his place, and the game would reset the room. The room would reset and Amy would appear in the appropriate spot, which may or may not be where Joe was depending on how the data structure is set up.

And In Conclusion
-----------------

I've shown you just a few examples of how you can use pointers in your game. I'm sure you can think up more, especially if you use this to create a few custom systems and see how much easier this really makes it.