Pikmin Fanon will close on September 1st (see here for details and discussion).
A full-history page and file archive is available for download here (mirror).
Wayback Machine archive can be found here. Partial Wikia archive here.

Difference between revisions of "Pikifen/Object script"

From Pikmin Fanon
Jump to: navigation, search
(Noted which events trigger every frame a condition is true.)
Line 252: Line 252:
! style="text-align: left" | '''<code>arachnorb_plan_logic</code>'''
! style="text-align: left" | '''<code>arachnorb_plan_logic</code>'''
| Special logic for {{c|arachnorb}}-type enemies. This is used to internally plan what sort of movements the arachnorb's feet will need to do for the next sequence of steps, so that it can achieve the specified goal. This only works on the object that represents the arachnorb's head, which must be a [[Pikifen/Misc. features#Parent/Child objects|parent object]] with feet children objects. In order for the engine to know where to position the feet, the following script variables should be declared: <code>max_step_distance</code> specifies the maximum distance a foot can move per step; <code>max_turn_angle</code> specifies the maximum amount of degrees the arachnorb can turn per step; <code>min_turn_angle</code> specifies the minimum amount of degrees the arachnorb can turn per step; <code>feet_normal_distance</code> specifies the usual distance the feet are from the center of the head.
| Special logic for {{c|arachnorb}}-type enemies. This is used to internally plan what sort of movements the arachnorb's feet will need to do for the next sequence of steps, so that it can achieve the specified goal. This only works on the object that represents the arachnorb's head, which must be a [[Pikifen/Creating object types#Parent/Child objects|parent object]] with feet children objects. In order for the engine to know where to position the feet, the following script variables should be declared: <code>max_step_distance</code> specifies the maximum distance a foot can move per step; <code>max_turn_angle</code> specifies the maximum amount of degrees the arachnorb can turn per step; <code>min_turn_angle</code> specifies the minimum amount of degrees the arachnorb can turn per step; <code>feet_normal_distance</code> specifies the usual distance the feet are from the center of the head.
<code>'''arachnorb_plan_logic''' home</code>
<code>'''arachnorb_plan_logic''' home</code>
:Sets up the internal logic for the arachnorb to head home. This will automatically decide how to turn or how to walk forward to get there.
:Sets up the internal logic for the arachnorb to head home. This will automatically decide how to turn or how to walk forward to get there.

Revision as of 14:43, 8 February 2020

This page will guide you on how to write a script for enemy objects in Pikifen. Although it is recommended to follow this guide from start to finish, you may jump straight to a section that explains a specific problem you may be having. To note is that you can also copy and paste an existing enemy's scripts and properties and adjust them to your liking, instead of creating everything from scratch.


The script is basically that: a script, like in a movie or theater. Something like: "When the bad guy says 'I'll get you', you say 'never!'. When the bad guy throws the punch, you dodge to the side." Except we'll be instructing the enemies to do what they need to do. "When a Pikmin shows up, you move to it. When the Pikmin is close, you lunge in for a bite."

For this, you'll need to understand some concepts: an action is an instruction we'll tell the enemy to do, like moving somewhere, focusing its sights on an object, changing its animation to the sleeping one, etc. An event is the same as the "when"s on the previous example. An event can be something like when a Pikmin approaches, when it reaches its intended destination, when its current animation finishes, etc. So, in essence, when an event happens, the object will perform some actions. That's the basics of it.

There is one more concept: a state. To make it easier, you can think of a state like a state of mind in a human: sleeping, hungry, disturbed, thinking about what to cook, etc. Except states for enemies can be anything you want. For an enemy like a Red Bulborb, the states would be sleeping, chasing prey, chewing, shaking, going back home, etc. States are important, because depending on the state, we may want the same event to trigger different actions. For instance, suppose a Pikmin comes near. What is the Red Bulborb to do? Well, it depends on its state: if it's sleeping, it must wake up, but if it is awake, it should lunge in for a chomp.

One final note: "mob" (short for "mobile object") is an alternate name for "object".

Red Bulborb guide

Creating the script

If you haven't already, follow the object type tutorial to create your own enemy. We'll be writing the script on a file called Script.txt, on the same folder. Create the file if it is not there already.

On this text file, add a script block. Inside of this, we'll be adding our enemy script. For the rest of this tutorial, we'll be creating a very basic (and varied) Red Bulborb.

Creating a state

We'll need to start the script with a state. Let's think of the most "normal" state for a Bulborb, to serve as a starting point. That would probably be the sleeping state, right? Most Bulborbs we see in the games are asleep when first met, so it makes sense to start here. You can name a state whatever you want (so long as you don't use spaces), but for the sake of clarity, let's call it sleeping. Ok, now we're going to have to specify what events and actions can take place while in this state. In order for the engine to understand what events/actions belong to this state, we'll need to a block for this state, create a sleeping { line, and the matching } line.

Your script should be looking like this:

script {
    sleeping {

Looking out for an event

Let's see, in this state, there's not much the Bulborb can do except wake up. Let's make it so that it wakes up when a Pikmin or leader touches it. For clarity, let's call Pikmin and leaders "opponents", since they are the sort of object the Red Bulborbs want to take down. We have to write the name of the event, which in this case, is on_touch_opponent. All events start with on_ (as in: "on the event that this happens, do that"), and in this case, this event triggers every time the Red Bulborb is near an opponent. What now? Well, we need to specify what actions to take. To recap: on the state of sleeping, when an opponent touches it, the Bulborb will perform some actions that we will specify later (waking up).

Because the engine needs to know what actions to perform on this event, we need to open up the event as a block with curly braces.

Performing an action

Let's assume that you already have animations for the Bulborb – these include waking up, walking, biting, going back to sleep, etc.

What we want now is for the Bulborb to wake up. Visually, we want its animation to change from the one where it is sleeping to the one where it wakes up and gets on its feet. For that, we can type set_animation waking_up. That set_animation word at the start tells the engine that the enemy needs to change animations, while the other word specifies what the animation is. Here, it is assumed that the animation for waking up is in fact called waking_up, but you can name it whatever you want.

So, when the Bulborb is in the sleeping state, the engine will look out for the event in which an opponent touches it. When that happens, the Bulborb will perform an action in which it changes its animation to waking up. Makes sense, right? Except there isn't much else that will happen. A Pikmin touches it, the Bulborb visually changes to an animation where it wakes up, but then what? Well, right after it begins its waking up animation, the engine will realize that an opponent is touching it (yet still). And because the Bulborb is still in the "sleeping" state, which is a state that is looking out for the "opponent is touching" event...it will just trigger the event again and again, which will keep restarting the animation. And it will keep doing this until the Pikmin walks away. The logical solution would be to change its state right after setting its animation, so that it may wake up in peace, without being interrupted by the constant "opponent is touching" events.

Add the line set_state waking_up after the line with the animation change action. This action will make its state change. Well, now that we've said that, we should also create this new "waking_up" state, then. Create it below the "sleeping" state's block. If you want, you can add an empty line between the two states to make it easier to read. The script should be looking like this, so far:

script {
    sleeping {
        on_near_opponent {
            set_animation waking_up
            set_state waking_up
    waking_up {

On enter

Although it is not the case, imagine that we wanted to make a grumble sound play, and an "exclamation mark" particle effect whenever the Bulborb wakes up. That's fine, we would just add more actions to the event. But now imagine that there were more ways for the Bulborb to wake up. Like we wanted it to wake up if an internal alarm set off (a creature can't stay asleep forever, right?), or even when a bomb rock explosion happens nearby. No problem, we would just add the events for those to the "sleeping" state, and make those events do the same. Except...it is a bit of a pain having to copy and paste the exact same set of animation+sound+particle+state actions for every one of those events. Well, there is an alternative way, which is much more organized.

Let's think about this: the animation, sound, and particle effect all happen when? When the Bulborb wakes up. When do we know exactly that the Bulborb woke up? When it enters the "waking_up" state. Regardless of how it got there (opponent touch, biological alarm, etc.), we know that if it got to this state, it means that it must perform the wake-up routine that involves all of those things. Luckily, we can specify what should happen when an object enters a state. Go to the "waking_up" state and add an event called on_enter. In here, place the usual actions. Oh, but because the sound and particle only belong to that a hypothetical scenario, the only action you should put here is the animation change we wrote earlier. Remember to remove the animation action from the sleeping state's on_touch_opponent event.

So, to recap, while sleeping, whenever an opponent touches it, it will change state to waking up. When it enters this "waking up" state, it will perform its animation to wake up. Makes a bit more sense this way, and it's also more organized. Keep this in mind when you want to switch to a state using multiple ways.

On animation end

Ok, now that the Red Bulborb can enter the "waking up" animation, what should it do while in it? Well, it shouldn't really be willing to fight, should it? It is still getting up, so it's not ready for that. In fact, it cannot do anything while in this state except finish getting up. As soon as it finishes though, it should probably look around for whatever woke it up. Ok, so on the event that it finishes getting up, it shall begin examining its surroundings. But how do we know that it finished getting up? Considering that games are simpler than real life, we know how long the Bulborb takes to wake up, since its animation is always the same. We could then wait for that amount of time, but we don't need anything that complex. There is an event that will trigger every time the current animation finishes. So, the best way to go about this is: "on the event that its waking up animation finishes". The event that checks this is called on_animation_end. As for what actions to perform, it would make sense to enter a state where it analyzes its surroundings and acts according to what it decides at the time (going back to sleep, chasing prey, etc.).

Your script should look like so:

script {
    sleeping {
        on_near_opponent {
            set_state waking_up
    waking_up {
        on_enter {
            set_animation waking_up
        on_animation_end {
            set_state examining
    examining {


Let's speed up the tutorial a bit. On the "examining" state, we can set its animation to the animation where it looks around left and right in search of something to do. If it was asleep and woke up because of a nearby Pikmin, it will perform the waking up animation, enter the examining state, spot the Pikmin, and go for it. Makes sense. If it can't find anything to do by the point it finishes looking around, it should head back home (the spawn point) and fall asleep. Let's handle that scenario. On the "examining" state (where its animation is set to looking around when the state is entered), on the event that it finishes its animation, it should change to a state where it's focused on returning home. You might find it weird why the Bulborb would try to go home right after waking up, but remember that we can use the "examining" state elsewhere too, like after it finished eating all Pikmin, or has wandered too far.

On this "returning home" state, we must tell the Bulborb to walk home. The action that does this is simple enough: move_to_target home. It would make sense to make this action run whenever the "returning_home" state is entered, of course. Now, on this same state, we want to make it so that on the event that it reaches its home, it proceeds to fall asleep. The event that checks if an object has reached its destination is on_reach_destination. Here, we can set it to a state where it falls asleep.


What about moving towards a Pikmin? On the examining state, in the event that it spots a Pikmin, it should move towards it to try to eat it, right? But let's think about what it means to "spot a Pikmin". Enemies can only spot Pikmin if they are close enough – if they're within vision reach. And once the enemy gets close to the Pikmin, it will only lunge for the kill if the Pikmin is within biting reach. All of these reaches are things you have to define yourself.

When in a state, an enemy can consider something to be "near" it if it is within a certain reach. It can also consider the object it is focused on to be "out of reach". Since in the examining state, a "near" Pikmin is any Pikmin that is within eyesight reach, and in the chasing state, it's any Pikmin that's fairly close, you have to change what "near" means. So, add the line set_near_reach wake_up to the on_enter event of the sleeping state. This will set the "near" reach to a reach we'll call "wake_up". We can name reaches whatever we want; let's worry only about the names for now, since we'll actually declare their values later. For the examining state, set the "near" reach to "search". This way, a Pikmin will only be considered "in reach" if it's within "waking up" reach when sleeping, and if it's within "searching" reach when examining.

Now that the reach is set, we can be on the lookout for the on_opponent_in_reach event on the examining state. When this event happens, well, we want the Bulborb to start chasing after the Pikmin. In order for the engine to keep track of what object our enemy is going to go towards, we need to say that the Bulborb will take focus on the Pikmin. On the on_opponent_in_reach event, we can perform the action focus trigger. This will make the Bulborb focus on whatever object triggered the event. This "focus" mechanic is also useful when losing track of the focused object: imagine that the Bulborb focuses on a Red Pikmin, and is going to chase it, but eventually, said Pikmin drowns. You would want the Bulborb to do something because it lost track of its prey, right?

Now that we've got that Pikmin focused, we want to move to it. Let's create a state for when the Bulborb is chasing. You may have guessed it, but the action that makes the Bulborb move to our focused Pikmin mob is move_to_target focused_mob. In addition, let's add an on_focus_off_reach event. This will trigger when the Pikmin is out of reach, which should happen when the Pikmin is so far away that the Bulborb can't see it any more. But just like before, this is another "reach". So, when entering the chasing state, use set_far_reach chase, so that the on_focus_off_reach event triggers whenever the focused Pikmin is off of this "chase" reach. You don't need to worry about the Pikmin dying or disappearing – that will also trigger the on_focus_off_reach event. Now that you're handling this event, you can make the Bulborb go back to the examining state, if the Pikmin it was chasing got out of reach.


In the "chasing" state, our Bulborb is in pursuit. It's got its sights locked on to the Pikmin, and is always moving in its direction. On the event that it gets near (remember to update the "reach"!), it should take a bite. The general way biting works in the Pikmin games is that an enemy clamps its jaws in front of it, and any Pikmin that get hit will be caught in its mouth. In reality, there is a limit: if you have a massive group of Pikmin bundled together, and a Red Bulborb chomps through the group, it will only be able to catch 3 in Pikmin, or 5 in Pikmin 2. This behavior can be replicated on the engine as well.

In order for the whole "catching" part to work, we need to keep in mind something about animations; read the animation tutorial if you need a reminder. Each object has a set of body parts, and they are named. Enemies like a Red Bulborb should have a "mouth" body part, because this is the body part that will be keeping hold of any captured Pikmin.

When the Bulborb begins lunging, its mouth is no longer a passive body part sitting around doing whatever. The creature will open its mouth and will use it to capture Pikmin. So, on the beginning of its lunging procedure (likely when the Bulborb enters the "lunging" state), we should let the engine know that its "mouth" body part is now a Pikmin-eating body part. To do so, use the action start_chomping 5 mouth. The start_chomping action makes some body parts start trapping Pikmin. The "5" there is the maximum number of Pikmin that can be caught at once. Finally, the "mouth" part is the name of the body part that will be made to trap Pikmin. From here on out, any Pikmin that touch the "mouth" body part will squeal and become trapped in its mouth.

When the lunge animation is over, you should set the "mouth" body part back to normal, so Pikmin don't accidentally get caught later when the enemy is, for instance, walking. To do this, write stop_chomping. Then, we'll (likely) want to change to a chewing state, where the Bulborb is chewing, and after it is done, kill off any caught Pikmin. This is controlled by the swallow and swallow_all actions, which will make it swallow some (randomly picked) or all captured Pikmin. On the flip-side, if you use release, the enemy will safely release all captured Pikmin.


The Red Bulborb lunges. But did it capture any Pikmin? We need to know this in order to decide if the creature should start chomping, or if it should flop to the ground. We can ask the engine this question and it will be able to give us an answer. Once the lunge animation is over, add the action get_info pim chomped_pikmin. This is what we use to get info of all sorts; in this case, we want to know the amount of chomped Pikmin currently in its mouth. But what do we do with this information?

We'll save it somewhere known as a variable. This is some space in memory dedicated to saving a value, and we can change it or retrieve it at any point. In our case, the variable will hold the amount of chomped Pikmin. And what about its name? In the previous paragraph, we called it pim (short for "Pikmin in mouth"), but you can call any variable whatever you like. From here on out, whenever you need to refer to the number of Pikmin in its mouth, you can access the value in this "pim" variable by writing $pim. When the script is run, it will replace $pim with 0, or 1, or whatever else "pim" is worth at the time.

It's generally good practice to declare a starting value for your variables. For this, you can create an init block outside of the script block, and in it, add set_var pim 0. This will set the value of the "pim" variable to 0. Any actions inside this block will be run when the object is created, so you always know what the starting value of every variable is.


Now to actually decide what to do after the lunge. The creature's behavior splits into two here: if it caught something, it should change to a chomping state, else, it should flop to the ground. This conditional logic can be written in the script.

After pointing down how many Pikmin got bit, let's run an if action. Write it down as such: if $pim > 0. This action, when run, will check the number of Pikmin in its mouth, via our "pim" variable. Naturally, in this case, we want to check if more than zero Pikmin got caught. Then this action will change the flow of the script: if the Bulborb caught Pikmin, the script continues on to the next actions. So after this if action, add the action to enter a chewing state.

But what if it didn't capture anything? Well, write an else action after the action that sets to the chewing state. And after that, write the logic to change to a flopping state. With all of this logic, the engine will enter that if action, and if it realizes the condition is false, it will jump to the actions after the "else". To wrap up the conditional part of this event, after the action that changes to the flopping state, you will need to add an end_if action. With this, the engine knows that what comes after is no longer a part of the conditional logic, and its flow works like normal.

Note that you don't always need to add an "else" part to your condition. Also, you may want to indent (add another tab at the start) lines inside the "if" and "else" parts. This example is simple, but more complex conditions and flows will be much easier to read if you can easily tell what belongs to what part of the condition just from the way the text is laid out.


The enemy can die at (almost) any moment. When that happens, the engine automatically jumps the script into a different state, so you don't need to worry about listening to the death event on every single state. To specify what state it should jump into, go out of the script block, and write a line with death_state = dying. This way, the engine knows that when the enemy's HP reaches 0, it must enter the "dying" state.

There are two parts to an enemy's death. The start, and the end. When an enemy's HP reaches 0, you likely want to make them perform a fainting animation, as well as call a special action that will run some extra code related to an enemy beginning to die (this code will, amongst other things, create the sparkling particles). This is done with the action start_dying. When it's time to register the enemy as completely dead (like when the fainting animation ends), you need to call the action finish_dying. This will make the object carriable, release a spirit, etc.


Remember earlier when the idea of having the Bulborb wake up due to a biological timer came up? Let's implement that. Let's say that every time the Bulborb falls asleep, its biological clock sets an alarm for 20 seconds, at which point, it will wake up on its own, look around, and if there's nothing going on, fall asleep again. When the Bulborb falls asleep, so when the "sleeping" state is entered, use the following action: set_timer 20. This will start an internal timer for the object that will tick in 20 seconds.

On the sleeping state, look out for the on_timer event. This will be triggered when the timer reaches 0. This would be the time to change the state to the "waking_up" state. When a timer reaches 0, it deactivates, so if you have a timer that you want to tick every X seconds, you need to set the timer again at that point. Other than that, there is one important question: what if the Red Bulborb's sleep is interrupted by a leader or Pikmin walking near? The timer would keep going, which is something we likely don't want. You can kill the timer by simply typing set_timer 0.

Script-related attributes

In order for the engine to get a grip on this script, we'll need to specify a few more things. First of all, on the Script.txt file, which you should still be on, add the following attribute outside the script block: first_state = sleeping.

This is so that the engine may know how the Bulborb begins its life. We did decide that the starting point of a Red Bulborb should be the sleeping state, so that is what we'll tell the engine. In addition, along this tutorial, there have been times where "being near" and "within sight distance" have been mentioned, but what are these distances? And surely they must vary by enemy. Well, they're just more attributes, and are as normal as weight or rotation speed. The following attributes exist, and you should try to declare them all. Go back to the Data.txt file to add them:

  • itch_damage: If an enemy has taken this much damage, it will be considered "itchy". With this, you can listen to the on_itch event, and when it triggers, make the enemy shake the Pikmin off. Handling this event automatically resets the amount of damage, making it possible for the enemy to be itchy again, next time it takes this amount of damage. Setting this to something like 10% or 20% of the max health is usually the way to go.
  • itch_time: In order for the enemy to not shake over and over, if you keep damaging it, you can also specify a minimum time requirement between itches, in seconds.
  • territory_radius: How far away from the spawn point must the enemy be before being considered "far from home". For reference, a Red Bulborb has this set to 500.

What about the "reaches" from before? This is where you'll define what a "waking up" reach is, what a "chasing" reach is, etc. Create a block called reaches. Inside, one per line, you declare the reaches, in the format <name> = <distance 1> <angle 1> <distance 2> <angle 2>. What does this mean? Well, let's fill in the "wake_up" reach. Type down wake_up = 10 360. What this means is that any Pikmin within 10 units of the Red Bulborb will be considered "in reach". The 360 is because we want this to happen regardless of where the Pikmin is in relation to where the Bulborb is facing, so it's a 360 degree range.

Now, add search = 250 180 30 360 for the next range. What about this? Well, this range actually has two parts. The first part means that Pikmin within 180 degrees of the Bulborb's front, and within 250 units, will be considered "in reach". This makes sense: any Pikmin that's within a fair distance in front of the Bulborb should be enough for the enemy to spot it. The second part means that any Pikmin within 30 units, at any angle, will also be considered "in reach". This extra part is useful for when the Pikmin is, for instance, hitting the Bulborb's back. Since the Pikmin is completely behind the Bulborb, it wouldn't be caught by the 250-180 description, since that only finds Pikmin in front. This way, any Pikmin close enough will also be considered "seen" by the Bulborb. The reason why we don't set the within-250-unit reach to 360 degrees is because that would unrealistically make the Bulborb see Pikmin far away that are behind it.

You'll need to tinker with these values until you find some balance you like. The other reaches will be something like attack = 40 30 (Pikmin within this reach are ready to be chomped), and chase = 250 360 (focused Pikmin outside of this reach will be considered lost).

Other than that, there's the script file's death_state attribute we filled earlier, and there is also a states_ignoring_death attribute, in which you can list states that are meant to ignore the death event (separated by semicolon). If you find that a death even is being sent on states you don't want, add the state's name here. Similarly, there's a states_ignoring_spray attribute.

This ends the tutorial. From here on out, you would continue the script whichever way you wanted. Know that you can check the scripts of enemies that come packaged with the engine to learn more.

List of events

Event Description
on_enter Triggered when the current state is entered.
on_leave Triggered when the current state is left.
on_animation end Triggered when the current animation finishes. Technically, this is triggered when the current animation begins looping.
on_damage Triggered when the object takes any sort of damage.
on_far_from_home Triggered every frame the object is far enough away from its home (as per the territory_radius attribute).
on_focus_off_reach Triggered every frame the focused object is beyond the current "far reach", or is dead. Also triggered when the focused object is deleted. Useful for making enemies lose track of focused Pikmin that are too far away.
on_frame_signal Triggered when one of the frames of the current animation has launched a signal. The number of the signal can be obtained with the get_info action.
on_held Triggered when the object is picked up by another one. Particularly useful for tool objects.
on_hitbox_touch_eat Triggered when one of the object's normal hitboxes touches an opponent's "eat" hitbox. Particularly useful for tool objects.
on_hitbox_touch_a_n Triggered when one of the object's attack hitboxes touches an opponent's normal hitbox. The opposite doesn't exist since it's reserved by the engine for controlling attack damage.
on_itch Triggered when the object takes a certain amount of damage after the last itch, as defined by the itch_damage attribute. It will also only trigger if it's been a certain amount of time since the last itch, as per itch_time. If the current state cannot handle this event, it will continue being sent until an event shows up that can handle it.
on_land Triggered every frame the object is touching the floor.
on_object_in_reach Triggered when an object has entered within its "near reach". Will trigger every frame for the same object, too.
on_opponent_in_reach Same as on_object_in_reach, but for opponents only.
on_pikmin_land Triggered when a thrown Pikmin lands on it. Might not work on objects that are too short.
on_reach_destination Triggered every frame that the object is in its destination, by moving there with any of the "move" actions.
on_receive_message Triggered when another object sent it a message. The contents of the message can be obtained with the get_info action.
on_released Triggered when the object was being held by another, but has now been released. Particularly useful for tool objects.
on_touch_hazard Triggered when it touches a hazard, whether from a hitbox, or from a sector.
on_touch_object Triggered every frame it is touches an object, for every object it's touching.
on_touch_opponent Same as on_touch_object, but for opponents only.
on_tick Triggered every single game frame. Because a frame can last for any amount of time, this is not an appropriate way to make things change over time. It is more useful for when you want to constantly update something, like make the object constantly turn to its focused object's position.
on_timer Triggered when the internal timer reaches 0.
on_touch_wall Triggered every frame it is touching a wall.
on_weight_added Triggered when an object starts standing atop this one, thus adding weight.
on_weight_removed Triggered when an object that was standing atop this one leaves, thus removing weight.

List of actions

Action Description
add_health add_health <amount>
Add <amount> health to the object's health. You can also remove some health by specifying a negative number.
arachnorb_plan_logic Special logic for arachnorb-type enemies. This is used to internally plan what sort of movements the arachnorb's feet will need to do for the next sequence of steps, so that it can achieve the specified goal. This only works on the object that represents the arachnorb's head, which must be a parent object with feet children objects. In order for the engine to know where to position the feet, the following script variables should be declared: max_step_distance specifies the maximum distance a foot can move per step; max_turn_angle specifies the maximum amount of degrees the arachnorb can turn per step; min_turn_angle specifies the minimum amount of degrees the arachnorb can turn per step; feet_normal_distance specifies the usual distance the feet are from the center of the head.

arachnorb_plan_logic home

Sets up the internal logic for the arachnorb to head home. This will automatically decide how to turn or how to walk forward to get there.

arachnorb_plan_logic forward

Sets up the internal logic for the arachnorb to move forward.

arachnorb_plan_logic cw_turn

Sets up the internal logic for the arachnorb to rotate clockwise. When this is called manually, the arachnorb turns a random angle between the minimum and maximum turn amounts.

arachnorb_plan_logic ccw_turn

Same as the cw_turn goal, but for a counter-clockwise turn.
calculate calculate <variable> <left> <operator> <right>
Calculates the mathematical operation between the operands and sets the variable to the result. It makes sense to use a variable in at least one of the operands, otherwise you're just punching in a fixed number calculation that any household calculator could tell you about. The operator can be + (add), - (subtract), * (multiply), / (divide), or % (modulo). For instance, calculate jumps $jumps + 1 would increment the number of jumps. Be careful not to get your $ signs confused – the <variable> field shouldn't use it!
delete Delete this object.
drain_liquid Makes the liquid in the sector it is on start draining. After a few seconds, it will be completely liquid-free. This will affect the sector it is on as well as all neighboring sectors that have liquid.
else If the corresponding if action's check ends up being false, the script will run the actions after this else, until it reaches the matching end_if.
end_if Closes a condition started by an if action.
finish_dying Runs the procedure related to the end of the object's death sequence. Amongst other things, this makes enemies unleash a spirit.
focus focus trigger
Focuses on the object that triggered the event.

focus link

Focuses on the first linked object, if any.

focus parent

Focuses on the parent object, if any.
get_chomped Makes the object get chomped as if it were a Pikmin. This is only applicable if run inside the on_hitbox_touch_eat event.
get_focus_var get_focus_var <destination_variable> <variable_from_focus>
Sets the variable <destination_variable> of this mob to the same value as the variable <variable_from_focus> of the focused mob, if any.
get_info get_info <destination_variable> <information>
Sets the variable <destination_variable> to some special information. The possible data are:
  • body_part: For events that deal with hitboxes, this is the name of this mob's body part that's responsible.
  • chomped_pikmin: How many Pikmin it currently has chomped.
  • day_minutes: What time of the in-game day it is, in minutes.
  • field_pikmin: How many Pikmin are currently on the field.
  • frame_signal: What the signal was that triggered an on_frame_signal event.
  • health: The object's current health.
  • latched_pikmin: How many Pikmin are currently latched on to it.
  • latched_pikmin_weight: Total weight of the Pikmin that are currently latched on to it.
  • message: What the message was that got sent when the on_message_received event got triggered.
  • message_sender: Name of the type of object that sent the message, when an on_message_received event gets triggered.
  • mob_category: Category of the mob that triggered the event. This is the same name as the corresponding folder in Game_data/Types. Only available for certain events.
  • mob_type: Type of the mob that triggered the event. This is the name defined in the name attribute of the object type's Data.txt file. Only available for certain events.
  • other_body_part: For events that deal with hitboxes, this is the name of the other mob's body part that's responsible.
  • weight: Current weight on top of it.
get_random_decimal get_random_decimal <variable> <minimum_value> <maximum_value>
Places a random value between <minimum_value> and <maximum_value> (including) into the variable <variable>. This number is a real number, so it can have decimal places.
get_random_int get_random_int <variable> <minimum_value> <maximum_value>
Places a random value between <minimum_value> and <maximum_value> (including) into the variable <variable>. This number is an integer number, so it will not have decimal places.
goto goto <label_name>
Orders the script to jump to where the label named <label_name> is. The label must be in the same event block as this goto. You can use this to loop actions multiple times in a row by returning to the top of the loop.
if Only executes the next actions, until an else or end_if action, if the condition you specify is true. If not, it jumps to the matching else or end_if action.

if <left> <operator> <right>

<left> and <right> are two values, and <operator> is how you want to compare them. As such, it makes sense to replace at least one of the values with a variable. Note that due to scripting limitations, only <right> may have spaces, if it is a string. The possible operators are:
  • =: True if <left> matches <right>. It works with text too.
  • !=: True if they don't match; also works with text.
  • <: True if the number in <left> is less than the number in <right>.
  • >: Greater than.
  • <=: Less than or equal.
  • >=: Greater than or equal.
label label <label_name>
Labels this point of the script as <label_name>. You can then use the goto to force the script to go to this point at will. Each label is only accessible to the event block it belongs to.
move_to_absolute move_to_absolute <x> <y>
Tells the object to begin moving to the specified area coordinates.
move_to_relative move_to_absolute <x> <y>
Tells the object to begin moving to the specified relative coordinates. See here for more info.
move_to_target move_to_target <target>
Tells the object to begin moving towards a special target. Possible values:
  • arachnorb_foot_logic: Used by arachnorb feet objects to move according to the internal plan. See the arachnorb_plan_logic action for more information.
  • away_from_focused_mob: Move away from the focused object, thus going in the direct opposite direction.
  • focused_mob: Move towards the focused object, following it as it moves.
  • focused_mob_position: Move towards the position of the focused object at this exact moment. In other words, don't follow it as it moves.
  • home: Move towards home (spawn point).
  • linked_mob_average: Move towards the average position of its linked objects. Useful for keeping an arachnorb's head in the center position of its feet objects, for instance.
order_release Orders the Pikmin that is holding on to this object to release it.
print print <text>

Prints some text to the top of the screen. Only useful for debugging the script, so you know how much a variable is worth, where the script passes, etc.

receive_status receive_status <status name>
Applies the specified status effect.
release All captured Pikmin are safely freed.
remove_status remove_status <status name>
Removes the specified status effect, if the object is currently afflicted by it.
send_message_to_focus send_message_to_focus <message>
Send a text message to the currently focused mob. Objects that receive a message will be thrown the on_receive_message event.
send_message_to_links send_message_to_focus <message>
Same as send_message_to_focus, but it sends it to all linked objects.
send_message_to_nearby send_message_to_focus <distance> <message>
Same as send_message_to_focus, but it sends it to all objects that are within the specified distance.
set_animation set_animation <animation>
Changes to and begins the animation <animation>.

set_animation <animation> no_restart

Same as above, but doesn't set the frame number to 0, meaning that animation will continue from whatever frame number the previous one left off.
set_far_reach set_far_reach <reach_name>
Makes it use the specified reach as the "far reach", from here on out.
set_gravity set_gravity <multiplier>
Sets how gravity affects this object. 1 is normal, 0 is no gravity, 0.5 is half gravity, -1 is upwards gravity, etc.
set_health set_health <amount>
Sets the object's health to the specified number.
set_height set_height <height>
Sets the object's height. Objects atop this one will rise or lower accordingly.
set_hiding set_hiding <true/false>
Sets whether or not the engine should hide this object's shadow and health from here on out. This is useful, for instance, when a Sheargrub digs underground.
set_holdable set_holdable
Makes it so that nothing can hold this object.

set_holdable <rules>

Makes it so that the specified kinds of objects can hold this object. You can write more than one, by writing one in each word. The valid values are pikmin for Pikmin, and enemies for enemies.
set_huntable set_huntable <true/false>
Sets whether or not this object can currently be hunted by other objects. This does not affect whether or not other objects can hurt it.
set_limb_animation set_limb_animation <animation>
Same as set_animation, but for the limb connecting it to its parent mob.
set_near_reach set_near_reach <reach_name>
Makes it use the specified reach as the "near reach", from here on out.
set_sector_scroll set_sector_scroll <x_speed> <y_speed>
Makes the sector this object is on begin scrolling, with the specified speed in the X axis (units per second) and the specified speed in the Y axis. Its floor texture will scroll along, and any objects on this sector will be dragged too. Setting both values to 0 will make it stop scrolling, naturally.
set_state set_state <state>
Instantly changes to the specified state. If it was meant to run any actions after this one, they will not be run.
set_tangible set_tangible <true/false>
Sets whether or not this mob can be touched by others. This only affects whether or not the mob can push or be pushed.
set_team set_team <team_name>
Sets the object's current team. Objects in the same team will not hunt or harm each other. Valid values are:
  • none: Does not belong to a team.
  • player_X: Belongs to player 1, 2, 3, or 4's team (replace the X with a number). Usually used for leaders and Pikmin.
  • enemy_X: Belongs to the enemy team 1, 2, 3, or 4 (replace the X with a number).
  • obstacle: Obstacle team.
  • other: Team for whatever else.
set_timer set_timer <amount>
Starts the mob's timer with the specified time period. Writing 0 makes the current timer stop, without triggering any on_timer events.
set_var set_var <variable> <value>
Sets the value of the specified variable.
show_message_from_var show_message_from_var <variable>
Shows a message on-screen using the text inside the specific variable. Any \n in that text represents a line break.
spawn spawn <spawn data>
Instantly creates a new object, with the information in the supplied spawn data block. See here for more information.
stabilize_z stabilize_z <reference> <offset>
Changes the object's Z coordinate to match the Z coordinate of its highest (if the reference is highest) or lowest (if the reference is lowest) linked object. After changing it, it also moves it up by the specified offset.
start_chomping Sets what body parts will be used to trap Pikmin from here on out.

start_chomping <victim_max> <body_parts>

<victim_max> is the maximum number of Pikmin that can be caught. <body_parts> is the name of the body part(s) that will be used for trapping, one per word.
start_dying Runs the procedure related to the start of the object's death sequence. Amongst other things, this makes enemies unleash a cloud of sparkle particles.
start_height_effect Records the object's current Z and, from here on out, scales the object larger the higher it is from that pivot Z. This creates a perspective effect that reflects how high the object is. This feature cannot scale any smaller than normal size. Use stop_height_effect to return to normal.
start_particles start_particles <generator_name> [<x offset>] [<y offset>] [<z offset>]
Begin emitting particles using the specified particle generator. If specified, the x, y, and z coordinates are the offset from the object's center coordinates and Z coordinate, based on the object's angle. See here for more info. If the particle generator specified has no interval (i.e. it only launches particles once and then it's over), then the particle generator is automatically removed from the object after it emits its particles. An object can only have one script-given particle generator attached at a time.
stop Makes the object stop moving laterally, and makes it stop rotating.
stop_vertically Kills the object's vertical momentum.
stop_chomping Makes it so no body parts will be used for chomping any more, from here on out.
stop_height_effect Stops the height effect started with start_height_effect. This also gets called every time the object touches the floor.
stop_particles Removes any currently attached particle generator.
swallow swallow <number>
Makes the object swallow <number> amount out of the captured Pikmin, picked at random. This kills the Pikmin.
swallow_all Makes the object swallow all captured Pikmin. This kills the Pikmin.
teleport_to_absolute teleport_to_absolute <x> <y> <z>
Instantly teleports the object to the specified area coordinates.
teleport_to_relative teleport_to_relative <x> <y> <z>
Instantly teleports the object to the specified coordinates relative to its position and angle. See here for more info.
turn_to_absolute turn_to_absolute <angle>
Turn towards the specified angle. 0 is east, 90 is south, etc.
turn_to_relative turn_to_relative <angle>
Turn <angle> degrees anti-clockwise.
turn_to_target turn_to_target <target>
Turns towards a special target. Possible values are:
  • arachnorb_head_logic: Used by arachnorb head objects to turn according to where their feet objects are located. See the arachnorb_plan_logic action for more information.
  • focused_mob: Constantly turn towards the focused mob. You can make it stop with the stop action.
  • home: Turn towards home (spawn point).

Relative coordinates

Some mob actions allow you to specify some coordinates relative to the object. While the absolute coordinates 50,100 are in the location of the map at X=50, Y=100, the relative coordinates mean that this is at the object's position, plus 50 to the right, and 100 down. This is assuming the object is facing the right.

If it isn't, the coordinates rotate around the object, such that a positive X is always in front of the mob. So for coordinates 50,100, this would mean 50 units in front of the mob, and 100 units to its right, regardless of where it's facing.

The same also applies to relative and absolute angles: a relative angle of 0 means the same angle that the mob is facing.


  • When you want to change states, make sure that the action that switches the state is the last one that will be run on the event's code. This is because when a state change action happens, it skips over all other actions that were written after it.
  • When changing a state, make sure that the new state's on_enter event doesn't change to another state in a way that could create an infinite loop. For instance, if changing to state A causes it to change to state B, which causes it to change to state C, which causes it to change to state A again, the engine will crash.