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/Creating object types"

From Pikmin Fanon
Jump to: navigation, search
(Added some notes for when you expect a mob to be attacked, but it's not.)
(Moved parent/child info from Pikifen/Misc. features to this page.)
Line 149: Line 149:
  
 
=== Parent/Child objects ===
 
=== Parent/Child objects ===
If your object is meant to be a '''[[Pikifen/Misc. features#Parent/Child objects|parent]]''', composed of several different '''child''' objects, then you need to specify the children data. In <code>Data.txt</code>, add a block called <code>children</code>. Inside, you will include a series of blocks, each one with a unique name that represents the child, e.g. "left_foot". Now, when your object is spawned, it will spawn these children along with it.
+
Your object can be a '''parent''' object, meaning it is actually composed of several different '''child''' objects. This feature is especially useful when you need several independently-moving parts. For instance, in a {{c|Beady Long Legs}}, the head is the parent object, meaning it is the enemy proper, and each leg is a child object.
  
Each of these blocks needs to have the following attributes:
+
A parent will spawn its children at the same time that it itself is spawned. Because every child is meant to be its own individual thing but also serve as components of the parent object, there are several ways for you to specify what it should do when it interacts with the world. This means specifying what happens when it receives damage, receives a script event, or receives a status effect: it can either ignore what it received or not, and it can either relay it to the parent object or not.
 +
 
 +
Children objects can also be connected to a specific body part in the parent. Because children objects are commonly used as appendages of the creature, it is possible to draw a "limb" connecting a parent object to a child object. This limb is a rectangular shaped sprite that stretches and rotates accordingly.
 +
 
 +
To make your object type a parent, go to <code>Data.txt</code>, and add a block called <code>children</code>. Inside, you will include a series of blocks, each one with a unique name that represents the child, e.g. "left_foot". Now, when your object is spawned, it will spawn these children along with it. Each of these children blocks needs to have the following attributes:
 
* '''<code>spawn</code>''': Name of the [[#Spawning other objects|spawn data]] to use.
 
* '''<code>spawn</code>''': Name of the [[#Spawning other objects|spawn data]] to use.
  
Line 160: Line 164:
 
* '''<code>hold_offset_angle</code>''': If the parent holds this child, this is the angle from the body part/object's default position that the child is located at.
 
* '''<code>hold_offset_angle</code>''': If the parent holds this child, this is the angle from the body part/object's default position that the child is located at.
 
* '''<code>hold_rotation_method</code>''': Indicates how the child can rotate. <code>never</code> means it never rotates (besides the starting angle). <code>face_parent</code> means it always rotates to face the center of the parent object. <code>copy_parent</code> means it's always the same angle as the parent object. Defaults to never.
 
* '''<code>hold_rotation_method</code>''': Indicates how the child can rotate. <code>never</code> means it never rotates (besides the starting angle). <code>face_parent</code> means it always rotates to face the center of the parent object. <code>copy_parent</code> means it's always the same angle as the parent object. Defaults to never.
* '''<code>handle_damage</code>''': If <code>true</code>, the child object suffers any damage that it receives.
+
* '''<code>handle_damage</code>''': If <code>true</code>, the child object loses health when it receives damage. If <code>false</code>, it ignores the damage.
* '''<code>relay_damage</code>''': If <code>true</code>, the child object relays any damage suffered to the parent object.
+
* '''<code>relay_damage</code>''': If <code>true</code>, the child object relays any damage to the parent object, so ''it'' can handle it.
* '''<code>handle_events</code>''': If <code>true</code>, the child object handles any event that it receives.
+
* '''<code>handle_events</code>''': If <code>true</code>, the child object handles any script event that it receives. If <code>false</code>, it ignores the event.
* '''<code>relay_events</code>''': If <code>true</code>, the child object relays any events received to the parent object.
+
* '''<code>relay_events</code>''': If <code>true</code>, the child object relays any events received to the parent object, so ''it'' can handle them.
* '''<code>handle_statuses</code>''': If <code>true</code>, the child object handles any status effect that it receives.
+
* '''<code>handle_statuses</code>''': If <code>true</code>, the child object handles any status effect that it receives. If <code>false</code>, it ignores the status.
* '''<code>relay_statuses</code>''': If <code>true</code>, the child object relays any status effects received to the parent object.
+
* '''<code>relay_statuses</code>''': If <code>true</code>, the child object relays any status effects received to the parent object, so ''it'' can handle them.
 
* '''<code>limb_animation</code>''': If there is meant to be a "limb" drawn between the child and parent, specify the name of its [[Pikifen/Creating animations|animation]] here. This animation must be included in the parent object's animation set.
 
* '''<code>limb_animation</code>''': If there is meant to be a "limb" drawn between the child and parent, specify the name of its [[Pikifen/Creating animations|animation]] here. This animation must be included in the parent object's animation set.
 
* '''<code>limb_thickness</code>''': If there is a limb, this specifies how thick it is.
 
* '''<code>limb_thickness</code>''': If there is a limb, this specifies how thick it is.

Revision as of 14:43, 8 February 2020

This page will instruct you on how to create new object types in Pikifen. This includes a new type of enemy, new type of Pikmin, etc.

General idea

In order for the engine to detect a type of object, it will check the "Game_data/Types" folder. Inside are several folders, one for each category of object (enemies, gates, etc.). Inside each category are folders for the different types of objects (the different types of enemies, different types of leaders, etc.). Finally, inside those are some text files with data about how the object works, its animations, or its script.

Creating a new object type

To create a new object type, make a folder for it in the right category, and create an empty text files inside called "Data.txt". Inside, you will write all of the object's attributes, like the name, its movement speed, etc. These take on the form of attribute = value, and there is one attribute per line. So for instance, to name Louie's object type, you'd have the line name = Louie in the file.

Some attributes are mandatory, some are optional, some apply to all object types, and some only apply to certain categories of object type. You can get a list of attributes that apply to all object types in the following sub-sections of this page, and then check what attributes exist for that category by visiting the category's article from the list. After you're done setting the attributes, you must create the animations for the object type; use the animation tutorial for this. Finally, some object types will also need a script to run. To figure out if your object will need a script or not, check the list of categories and if it does, read the object script tutorial to learn what you need to do.

After you have done that, you can boot up the engine, go to the area editor, place your new object in an area, hit play, and watch it in action!

Naturally, instead of creating your own files from scratch, you may copy and paste an existing object's files and simply edit those.

Mandatory attributes

The following attributes must exist, regardless of category.

  • name: Name of the object type. e.g. "Olimar", "Red Pikmin", "Cloaking Burrow-nit".

Recommended attributes

The following are attributes that you really should have, but the engine can run without them.

  • can_hunt: This object will only want to hunt down objects of this target type. i.e. it will only consider those an "opponent" (provided they're also in an opposing team). See target_type below for more information.
  • can_hurt: This object can only cause damage to objects of this target type (provided they're also in an opposing team). See target_type below for more information.
  • height: Object's height. This doesn't need to be very specific. For reference, leaders are usually 32, Pikmin are usually 24.
  • max_health: The object's top health. For reference, leaders have 2000, and something like a Red Bulborb has 750.
  • move_speed: Standard movement speed (in pixels per second). For reference, leaders move at 130.
  • pushable: true if this object can be pushed out of the way by other objects. false otherwise.
  • pushes: true if this object can push "pushable" objects out of the way. false otherwise.
  • radius: The object's size, represented by the circle's radius (in pixels). Leaders are 32 pixels wide, so their radius is 16. Pikmin have a radius of 10.
  • rotation_speed: How fast the object turns when moving, in degrees per second. For reference, leaders use around 360, Pikmin use around 630, and a Red Bulborb uses around 114.
  • target_type: What type of "target" the object is. This determines which objects will hunt it, and which objects can attack it. Possible values are as follows, along with what each type is meant to represent:
    • none: Cannot be damaged or hunted down.
    • player: Leaders, Pikmin, and anything belonging to the "heroes" of the player's side.
    • enemy: Enemies.
    • weak_plain_obstacle: Weaker objects that should be damaged by many things, like leaders, Pikmin, or explosions. e.g. egg.
    • strong_plain_obstacle: Stronger objects that should be damaged by beefy hits, like Pikmin or explosions. e.g. gas pipe.
    • pikmin_obstacle: An object only Pikmin should harm. e.g. electric gate.
    • explodable: An object that should only be hurt by an explosion. e.g. reinforced wall.
    • explodable_pikmin_obstacle: An object that should be hurt by Pikmin or explosives only. e.g. Burgeoning Spiderwort.
    • fragile: A fragile object that should be harmed by even the gentlest smack. e.g. bomb rock.

Optional attributes

For all categories of object type, you may set these attributes, but they will still work if you don't.

  • blocks_carrier_pikmin: If set to true, the object being alive in the way of carrier Pikmin will block their carrying, like a gate or an unbuilt bridge.
  • can_free_move: If true, this object can move in any direction freely, without having to first turn there. It will also not face towards the direction it is going.
  • casts_shadow: If set to false, the object won't cast a shadow on the ground. Default is true.
  • default_vulnerability: For every source of damage not specified in the vulnerabilities, the damage the object receives is multiplied by this amount.
  • health_regen: Passive health regeneration rate, in HP per second. Default is 0.
  • is_obstacle: If set to true, the object will be considered an obstacle. This only impacts whether enemies and such can harm it or not.
  • 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.
  • main_color: A color to represent the object by. The format is R G B (values range from 0 to 255). Default is black.
  • max_carriers: Maximum number of Pikmin that can carry this object, when it is made carriable.
  • pushes_with_hitboxes: If true, this object pushes with its (normal or attack) hitboxes, instead of pushing using its object's center and radius.
  • rectangular_dimensions: If this object is meant to have rectangular collision, specify the rectangle's dimensions here, in the format <width> <height>. This is useful for objects like gates, but shouldn't be used by objects that can move (among other things, the engine is not ready to handle rectangular object vs rectangular object collisions).
  • show_health: If set to false, the object's health wheel will not appear on top of it. Default is true.
  • spike_damage: If this object is meant to cause spike damage, specify the spike damage type's name here.
  • spike_damage_vulnerabilities: Normally, objects hit by a spike damage attack will receive the damage specified. If you want this mob type to take more or less damage (or even heal!), you can specify it here. This is a block, where every attribute inside has the spike damage type's name as a name, and the percentage as a value. Example: poison = 50 will make this enemy take half the intended damage when ingesting a White Pikmin.
  • 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.
  • walkable: If true, this object can be walked on top of by other objects. Other objects will be able to mount it if they fall on it from above, or if they are on a floor that's within 50 units of height from the top of this object (much like how climbing up stairs work).
  • weight: How much Pikmin strength does it take to carry the object.

List of object categories

The following is a list of all categories that exist in the engine, with links to pages detailing more information about them.

Category Brief description Examples Script?
Pikmin A type of Pikmin. Red Pikmin, Yellow Pikmin No
Leader A leader. Yes, you can have multiple "Olimars" in an area! Olimar, Louie No
Enemy An enemy, either prey or predator. Red Bulborb, Cloaking Burrow-nit Yes
Onion An Onion. Each can only handle one Pikmin type. Red Onion, Yellow Onion No
Ship Anything that the Pikmin can return treasures to. S.S. Dolphin, Hocotate ship No
Pellet A pellet. Red 1 pellet, Blue 5 pellet No
Treasure A main collectible, like a ship part, treasure, fruit, etc. Main Engine, Courage Reactor No
Bridge Anything that once opened, creates a bridge. Wood bridge, Red ceramic bridge No
Group task Something that requires Pikmin to pose together in order to open, move, etc. Cardboard box, electrode Yes
Scale Measures how much weight is on top of it, and does things depending on the amount. Seesaw block, crushable paper bag Yes
Track Transports an object from point to point. Climbing stick, slide No
Bouncer Bounces an object to some other location. Bouncy Mushroom, geyser No
Converter Anything that converts a thrown Pikmin to another type. Crimson Candypop Bud, Queen Candypop Bud No
Decoration Any decorative plant or object. Clover, Margaret No
Drop A droplet that can be drunk. Nectar, Ultra-bitter nectar No
Pile Any sort of pile of resources. Bitter Burgeoning Spiderwort, Ceramic pile red No
Resource Anything that can be harvested from a pile and brought somewhere. Bitter berry, Ceramic fragment red No
Tool Anything that can be held by a Pikmin and activated when the Pikmin's thrown. Bomb rock, Mine Yes
Interactable Anything that the current leader can interact with to cause some action. Sign Yes
Custom Any object with no specific behavior. Egg, Fire geyser, anything really Yes

If there's a type of object you know is popular in the Pikmin series, but you can't find the category for it, then either an appropriate category does not yet exist in the engine, or it can be created as a custom object.

Extra features

Spawning other objects

If you want your object to spawn other objects, you need to specify their spawn data. In Data.txt, include a block titled spawns. Inside, you will write a series of blocks, each one with a unique name that will identify that spawn data. Later, when you want to spawn an object using the script, you need to refer to this name.

These spawn data blocks must have the following attributes inside:

  • object: Name of the type of object to be spawned. This is the formal name, i.e. the name provided in the name attribute in the mob type's Data.txt file.

It can also optionally have these attributes:

  • relative: Are the specified spawn coordinates absolute or relative? See here for more help.
  • coordinates: Coordinates to spawn in, in the format x y z.
  • angle: Angle the spawned object will be facing.
  • momentum: If this is 0, the mob spawns in the exact spot specified and stand there. Otherwise, it will spawn in that spot but be launched in a random direction, with the specified momentum. 100 is a good general case value.
  • vars: Any script variables to include, separated by semicolon. Example: vars = maturity = 0; sprout = true.
  • link_spawn_to_object: If true, a link will be created from the spawned object to your object.
  • link_object_to_spawn: If true, a link will be created from your object to the spawned object.

Parent/Child objects

Your object can be a parent object, meaning it is actually composed of several different child objects. This feature is especially useful when you need several independently-moving parts. For instance, in a Beady Long Legs, the head is the parent object, meaning it is the enemy proper, and each leg is a child object.

A parent will spawn its children at the same time that it itself is spawned. Because every child is meant to be its own individual thing but also serve as components of the parent object, there are several ways for you to specify what it should do when it interacts with the world. This means specifying what happens when it receives damage, receives a script event, or receives a status effect: it can either ignore what it received or not, and it can either relay it to the parent object or not.

Children objects can also be connected to a specific body part in the parent. Because children objects are commonly used as appendages of the creature, it is possible to draw a "limb" connecting a parent object to a child object. This limb is a rectangular shaped sprite that stretches and rotates accordingly.

To make your object type a parent, go to Data.txt, and add a block called children. Inside, you will include a series of blocks, each one with a unique name that represents the child, e.g. "left_foot". Now, when your object is spawned, it will spawn these children along with it. Each of these children blocks needs to have the following attributes:

The blocks can also have the following optional attributes:

  • parent_holds: If true, then the parent object is holding this one, much like an enemy holds a Pikmin that is latched on to it. Use the following attributes to specify the location.
  • hold_body_part: If the parent holds this child, this is the name of the body part it is held on. If empty, the center of the parent object is used instead.
  • hold_offset_distance: If the parent holds this child, this is how far away from the center of the body part/object the child is. 0 means dead center, and 1 means on the edge, but you can write numbers beyond this range.
  • hold_offset_angle: If the parent holds this child, this is the angle from the body part/object's default position that the child is located at.
  • hold_rotation_method: Indicates how the child can rotate. never means it never rotates (besides the starting angle). face_parent means it always rotates to face the center of the parent object. copy_parent means it's always the same angle as the parent object. Defaults to never.
  • handle_damage: If true, the child object loses health when it receives damage. If false, it ignores the damage.
  • relay_damage: If true, the child object relays any damage to the parent object, so it can handle it.
  • handle_events: If true, the child object handles any script event that it receives. If false, it ignores the event.
  • relay_events: If true, the child object relays any events received to the parent object, so it can handle them.
  • handle_statuses: If true, the child object handles any status effect that it receives. If false, it ignores the status.
  • relay_statuses: If true, the child object relays any status effects received to the parent object, so it can handle them.
  • limb_animation: If there is meant to be a "limb" drawn between the child and parent, specify the name of its animation here. This animation must be included in the parent object's animation set.
  • limb_thickness: If there is a limb, this specifies how thick it is.
  • limb_parent_body_part: If there is a limb, this specifies where it connects to in the parent. If it's empty, it connects to the parent's center. Otherwise, it connects to the center of the specified body part.
  • limb_parent_offset: If there is a limb, you can specify how far away it is from the center of the parent-side connection.
  • limb_child_body_part: Same as limb_parent_body_part, but for the child object.
  • limb_child_offset: Same as limb_parent_offset, but for the child object.
  • limb_draw_method: How to draw the limb. This can be one of the following:
    • below_both: Draw the limb below both the parent and the child.
    • below_child: Draw the limb below the child. It may appear above or below the parent, depending on the child and parent's positions.
    • below_parent: Draw the limb below the parent. It may appear above or below the child, depending on the child and parent's positions.
    • above_parent: Draw the limb above the parent. It may appear above or below the child, depending on the child and parent's positions.
    • above_child: Draw the limb above the child. It may appear above or below the parent, depending on the child and parent's positions.
    • above_both: Draw the limb above both the parent and the child.

Vulnerabilities

You can make it so that an object is completely invulnerable to a hazard, more vulnerable to another, etc.

In Data.txt, add a block titled vulnerabilities. Inside, each line will indicate a hazard, and a multiplier, in the format hazard = multiplier. The hazard is the name of the hazard you want to receive special treatment, and the multiplier is how much the damage will be multiplied by. So for instance, if you want an object to be invulnerable to fire attacks, write a line with fire = 0, and if you want the object to take double damage to water attacks, write water = 2.

You can use this in conjunction with the default_vulnerability attribute to make an object that is invulnerable to anything except explosions, for instance.

Notes

  • If objects of your new type are not being hunted down or hurt, confirm the following:
    • The object's target type is one of the types the attacker wants to hunt or can hurt.
    • The object is not in the same team as the attacker.
    • The object has more than zero health.
    • The object is not unhuntable via the set_huntable script action.
    • The object is not invisible via a status effect.