Party Follow Tutorial
IntroductionWhen I originally created this tutorial, it was for RPG2kNet way back when. Since then, I've made some revisions and minor tweaks to the script and it's at a point where the events are litterally plug-and-play. Even so, the tutorial itself is a bit complex and you'll probably be lost without a good working knowledge of variables and events. If you feel you're ready... please come. It won't hurt... much. BasicsMaybe I should explain the party follow system. It's also known as the caterpillar effect - where your entire party is on the map, following the lead character around like a caterpillar. I recall a guy named Drakul creating a tutorial, but sadly, the page is down. (Don't worry, I'm not stealing his stuff. This is the net result of my hard work, and I ask that you not steal it, either.) I noticed that there's a general idea that a party follow system tends to lag the system... this was even mentioned by Jovian, an NPC in Destiny's Call Complete. True, when the events are not scripted properly, it can HORRIBLY lag the system. But then, a system with minimal lag can still be devised. This is what I tried to work towards. There's also the problem of multiple characters. You may not always have the same party - in fact, in most games the party is constantly changing, constantly evolving. I addressed this too. The biggest problem, however, is the number of events that must be copy-pasted from one map to another. You must have patience, for on every map you want your party to follow you, you must copy the events to. I tried to make this as painless as possible. So in the end, we've got a party following us with low lag, changing to adapt to the party, and as easy initialization as possible, right? I've also added in features where your party will gather at one point, and can re-initialize itself if things get too hairy. Let's get to work. ConventionsHere's the standard conventions I'll use in this tutorial.
Variable / Switch setupLike I said before, you need a good working knowledge of variables. The system I have ended up using two switches and 15 variables. I'll go ahead and list those here now. Switches:[99]: Reset party [100]: Gather party Variables:V[41]: Player current X V[42]: Player current Y V[43]: Player old X V[44]: Player old Y V[45]: Event ID 2 V[46]: Event ID 3 V[47]: Event ID 4 V[48]: Player ID 2 V[49]: Player ID 3 V[50]: Player ID 4 V[51]: Player step 4 V[52]: Player step 3 V[53]: Player step 2 V[54]: Player step 1 V[55]: Call event page Go ahead and set those up. If you have to change the actual switches and variables, feel free - just remember what replaces what, because I'm referring to everything as I use it here. The primary eventThere's one event on every map that essentially controls the party follow system. If it's not there, the party will not follow, no matter what. So we have to script that first. Create a new event with no graphic, event start "Push key", position "Below hero". I'll spit out the script - with explanations of each line, of course. <> Change var: Var[43:Player old X] (Set) Hero's X Pos. <> Change var: Var[44:Player old Y] (Set) Hero's Y Pos. These two lines save the player's position into variables so the party can start out under the player like it should. They're also used for tracking the player, which I'll explain later. <> Move Event: This event - StartSlipThrough This line simply allows the hero to "step over" the party. This way, you won't get stuck in a corner by your party, get frustrated and simply blow up your computer. That would be a bad thing, yes? <> Get Event ID: Event at (0, 0) to V[55: Temporary] This is where the event script gets tricky. To properly move the events, we have to place their event IDs into variables, and the easiest way is to place the events in a specific place on the map and load their IDs on event start. However, we can't overwrite the old IDs in the case of teleporting to the same map - this fucks things up seriously. To circumvent this we see if there's an event at (0, 0) (which is where this event SHOULD be placed) and if that event ID is nonzero then we can assume the events haven't been initialized yet. We load the other event IDs like so: <> If Var[55] Does Not Equal 0 <> Get Event ID: Event at (0, 0) to V[45: Event ID 2] <> Get Event ID: Event at (1, 0) to V[46: Event ID 3] <> Get Event ID: Event at (2, 0) to V[47: Event ID 4] <> End If <> Set event place: This event - (V[43], V[44]) At the end of all that we move the event under the hero. <> Change var: Var[0055:Call event page] (Set) 1 <> Call event: V[46]P[V[55]] (Map event - Variable: Event V[46], Page V[55]) <> Call event: V[47]P[V[55]] These lines use the values we set earlier and initializes the OTHER events we have to use for the system. I'll give you the script for those events after we're done here, okay? <> Change var: [0051 to 0054] (Set) 0 (Variable range: From V[51] to V[54]) This initializes the variables we use to track the direction the player steps in. Clear them so the following events don't wander all over the map crazily. Okay, that finishes the first page. Let's script the second now. Make a new page with the start condition set to "Parallel Process" and position set to "Same level as hero". Check the "Allow event overlap" box. I suppose I should explain that last bit. "Allow event overlap" is a bit of a mistranslation - rather, its full name is "Disallow (Prevent) event overlap". By checking it, the hero can walk over it, but not other events. The only exception is when an event is TOLD to walk over it via the Move Event command. Remember, it's on the same height as the hero but it's set to let stuff (mainly the hero) slip through it. The final part is the graphic and condition. I recommend you order your party using the same numbers you gave your heroes in the Database. Easier accounting. Give your event the same graphic as the lowest-numbered hero that can be in the party (usually 1, but I don't know your game). Then check the box by "Event conditions: Variable" and use the variable "Variable V[8]: Player ID 2". Set the number in the "Above" box to the same number you used earlier (once again, probably 1). It's a but tricky, I know. At least we only have to code the event once. Speaking of which, give the event this script: <> Call event: This event Pg(1) Run all the initialization code we scripted earlier. <> Loop Yup, this script takes place in an infinite loop =P <> Change var: Var[0041:Player current X] (Set) Hero's X Pos. <> Change var: Var[42:Player current Y] (Set) Hero's Y Pos. Get the player's CURRENT position. Remember what I said earlier about tracking the hero's position? This is where we do it. We check the player's current position against the old one, and set a variable according to which direction the player stepped. The script checks the directions in order of down, left, right, then up. <> Fork: Var[42:Player current Y] V[44] (Bigger) (Add else case) <> Change var: Var[54: Player step 1] (Set) 1 <> Else case <> Fork: Var[41:Player current X] V[43] (Smaller) (Add else case) <> Change var: Var[54: Player step 1] (Set) 2 <> Else case <> Fork: Var[41:Player current X] V[43] (Bigger) (Add else case) <> Change var: Var[54: Player step 1] (Set) 3 <> Else case <> Fork: Var[42:Player current Y] V[44] (Smaller) (Add else case) <> Change var: Var[54: Player step 1] (Set) 4 <> Else case <> Change var: Var[54: Player step 1] (Set) 0 <> End case <> End case <> End case <> End case Ugly, but still doable. But there's still the matter of gathering the party - they're not going to move one step if the player doesn't first. We have to have an override. <> Fork: Switch[100: Gather party] On <> Change var: Var[54: Player step 1] (Set) 5 <> End case There you have it. A value of 5 means nothing to the movement code, so the events won't step when they see it - they'll walk up to greet the player, then stop moving. We still need it though, because the code that tells all the events to step won't run unless the player HAS moved. When the variable we check is set to 0, the code assumes the player hasn't moved. It sees the 5 and thinks "oh, the player moved." <> Change var: Var[0043:Player old X] (Set) Var[41] <> Change var: Var[44:Player old Y] (Set) Var[42] Save the new player position, which becomes the old position the next time the script is run. <> Fork: Var[54: Player step 1] 0 (Others) Now we have to check which direction the event should move. First, we check if the player moved (or if we're gathering the party). If not, then we have no need to run the code here. <> Fork: Var[53: Player step 2] 1 (Same) <> Move event: This event - Step down <> End case ...so, why are we checking this instead of what the player just stepped? If we move the event too early, it tends to mess up when it's moving around - that is, not follow the player correctly. I've had it happen. It's ugly. Trust me. <> Fork: Var[53: Player step 2] 2 (Same) <> Move event: This event - Step left <> End case <> Fork: Var[53: Player step 2] 3 (Same) <> Move event: This event - Step right <> End case <> Fork: Var[53: Player step 2] 4 (Same) <> Move event: This event - Step up <> End caseOf course, we need one fork condition for each direction we need to test. So they can follow in all directions and not just one. <> Change var: Var[55:Call event page] (Set) 2 <> Call event: V[46]P[V[55]] <> Call event: V[47]P[V[55]] Call the movement code for the OTHER following party members on the map. <> Change var: Var[51: Player step 4] (Set) Var[52] <> Change var: Var[52: Player step 3] (Set) Var[53] <> Change var: Var[53: Player step 2] (Set) Var[54] "Step down" the directions to move. The other events read variables 52 and 51 to coordinate their steps. In essence, the player steps, then the first follower, then the second, then the third. So we have to give them the old directions so they, too, can follow the player accurately. <> End case Finally, we're out of the movement code! <> Wait: 0.0sec The lag-killing line. While it may seem useless for a wait to run for 0 seconds, it actually helps A LOT. Without this line, RM2k will die from the lag, making it unplayable. Remove it if you don't believe me, but don't come crying back when you find out what I said is true. <> Fork: Switch [100: Gather party] On <> Move All <> Fork: Var[51: Player step 4] 5 (Same) <> Change switch: [100: Gather Party] Off <> Change switch: [99: Reset Party] On <> End case <> End case When you gather the party, this checks if you're done. First, move everything (the party tends not to gather correctly if you don't), then check the last step taken. If it's 5 (remember what I said earlier?), we've done and should reset the party's position... just to make sure they're in the right place. <> Fork: Switch [99: Reset party] On <> Change switch: [99: Reset party] Off <> Break cycle <> End case When we reset the party, we have to break out of the loop and run the initialization commands again. So, all we need to do is "Break cycle" to get out of the loop. The script will run again on its own. <> End loop Yup! That's it. Last line of code... on this page. (groans can be heard from the back of the room) Hey! No groaning while I'm talking. At least the code for all the other pages is simple. (more groans can be heard from the back of the room) It's not that bad, really... just one page for every possible party character. Make a new page (you DO have more than one character, right?) and change the graphic to the next character that can be in your party. Change the number in the box by "Above" to whatever that hero's ID is. Here's the entire script for that page, and every page after: <> Call event: This event Pg(2) That's all it needs. I think you can safely set up the rest of your pages in this event now. Just make sure that the IDs go in ascending order from page to page. To clarify: make sure that you don't have page 3 using an ID of 10 while page 4 uses an ID of 3. And remember: Parallel process, same level as hero, allow event overlap. The second and third followersLet's make this easy on ourselves... go ahead and copy the lead event and paste it at (1, 0). Delete the script for every page (but not the pages themselves) and change the event start condition on each page to "Push key." Here's the entire script for page 1: <> Move Event: This event - StartSlipThrough <> Set event place: This event - (V[43], V[44]) That's it. All we need to do is set the event under the player and make sure it can be passed through. Page 2 isn't hard either: here's page 2's script. <> Fork: Var[52: Player step 3] 1 (Same) <> Move event: This event - Step down <> End case <> Fork: Var[52: Player step 3] 2 (Same) <> Move event: This event - Step left <> End case <> Fork: Var[52: Player step 3] 3 (Same) <> Move event: This event - Step right <> End case <> Fork: Var[52: Player step 3] 4 (Same) <> Move event: This event - Step up <> End case There's one final edit we need to make to this event: on each page, change the variable in the conditions to "49: Player ID 3". Now copy and paste THAT event. Change all the "Var[52]"s to "Var[51]"s and the Var[49]s to Var[50]s. Hope I didn't confuse you on that last bit. That's it. Your party will now follow you around on this map. Try it if you want. Party managementWhat, it didn't work? Oops - that's right, we haven't set the variables the system uses to track which characters are in the party. There's minimal maintenince when it comes to adding characters - at the most, three lines of code whenever you add a character to your party. I normally use V[1] for temporary numbers, but once again, change at will. <> Change var: Var[1: Temoprary] (Set) Party size <> Change var: Var[1: Temporary] (Add) 46 <> Change var: Var[Var[1]] (Set) (ID of just-added hero) Why do we add 46? The ID of the second hero is stored in V[48]. Since V[1] is set to the size of the party, it'll be equal to 2 if we just added in the second character. 46 + 2 = 48. Removing characters is another matter entirely - we not only have to remove the character from the party, we also have to have the other characters take up the slack. Otherwise, hilarious non-following antics can and do ensue. Let's say the second character in the party is leaving. We have to set the variables up like so... <> Change var: Var[48: Player ID 2] (Set) Var[49] <> Change var: Var[49: Player ID 3] (Set) Var[50] <> Change var: Var[50: Player ID 4] (Set) 0 ... moving the empty slot to the end of the party. This is just the basics of adding and removing characters. Party management can get ugly in cutscenes, and for those I recommend you have them take place on a seperate map without the party follow system to deal with. Fleshing outNow that the system is essentially complete, there's just one final thing that needs to be done: copying the events to every map that you want your party to follow on. The system was scripted with one thought in mind: that the events DON'T have to have specific IDs to work correctly. The only catch is making sure the events for the follow system are in the same place on every map: the control event at (0, 0), and the following events placed immediately next to it (follower 1 at (1, 0); follower 2 at (2, 0)). That's it - no further editing of code necessary. Known bugsHere's something interesting I found out while I was scripting the system: if you teleport from one location to another on the same map, the events won't reset themselves. This includes the party follow events. That's the purpose of the Reset switch when you created the events. After you have a Teleport command that moves you to another location on the same map (usually with interior maps), also have that event turn on the Reset switch. If you don't, your party will no longer follow you around, leaving you asking "Where did I go wrong?" The final wordI put a lot of hard work into this system, and hope to see it put to good use. If you want to use it, that's fine (why else would I write a tutorial detailing how to make it?) but at least have the decency to credit me for my hard work. All I ask is a mention in the credits... maybe an email saying "thanks." I get lonely, y'know. Feel free to ask questions about the script... but only if they're intelligent. No questions along the lines of "i saw your tutorial i dont understand it help me". I won't even acknowledge you. I warned you aead of time that even with the explanations, this is an extremely advanced script! I do not kid around with stuff like that. Finally, feel free to tweak the script. If you see an area where you think it can be improved, do it. I wrote the script to be as open-ended as possible. So go. Make me proud. LegalThis document is ©2002 Dan Sandstrom. RPG Tsukuru 2000 / RPG Maker 2000 is ©2000 ASCII / Yoji Ojima. Ask if you wish to use this tutorial on your site, I may update it in the future. Violators will be prosecuted to the fullest extent of my foot. | |
The WhoopA Network - Design and content ©2001-2006 Dan Sandstrom |