Working with instances
Using instances when creating your Portal 2 map can greatly increase your speed and efficiency between prototyping a puzzle and publishing the final product. Stock instances included with the Portal 2 Authoring Tools can be used to create nearly every element of creating a map - from the most basic things like floor buttons, to more complex setups like box spawners, and even non-gameplay elements such as observation rooms.
What are instances?
Instances are VMF files which are referenced by your map during construction; at compilation the VMF files are combined. An instance VMF can contain anything as simple as a single brush, to an entire puzzle or gameplay element complete with logic entities and Input/Output triggers.
When should I use an instance?
One of the major benefits of using an instance is that any changes you make to the instance VMF is instantly translated to the rest of your maps. If you make a change to the look or operation of your floor button or your door, you do not need to go and change every usage of it in your map, like you would if you had manually created them and/or used a normal Prefab. Instead of creating several copies of the same entities, you can use an instance to build the button or door once, and then reuse it multiple times.
Instances are best used when creating game elements, geometry, complex entity or I/O setups (such as map transitions), or any other grouping of objects that is going to be repeated or reused frequently.
Building an instance from scratch
Placing a func_instance_origin entity in the source VMF this entity will act as the placement-origin of the instance when used in another map. For example, placing the instance file's func_instance_origin on floor level of a button will allow the button to be easily placed flush against the floor in your map. If there is no func_instance_origin placed inside of the instance, the map origin (0,0,0) will be chosen as the origin for the instance.
Instances can deploy parameters; by placing a func_instance_parms in the instance file certain variables can be changed by the referencing map. Each variable must start with a $ symbol, and then must correspond to the value in another entity within the instance. If your instance requires Input/Output interaction with the referencing map add an func_instance_io_proxy entity with the targetname "proxy". For each Input that the instance will be able to receive, a corresponding Output in the func_instance_io_proxy with the Output "OnProxyRelay" will be required.
For example, if you are building a custom box dropper instance, you can setup a parameter "$box_type" which then corresponds to the box entity's "Cube Type" value, and another parameter "$box_trigger" which corresponds to the entity's relay "targetname" value. When you place this instance in your map, you will have the option to use the func_instance's "Replace" fields to change the type and the targetname of the relay entity that is created. You can then address just the box dropping trigger, rather than any other trigger the instance might contain.
A note about using func_instance_parms and targetname
If an entity in an instance has it's targetname set to a replaceable parameter field, any I/O in your map must target the entity's final instance collapsed name. During the VBSP process, all of your instances are gathered and collapsed into your map, and the names of any entities within those instances have their names altered. The renaming system works as follows (assuming the "Entity Name Fix Up" is set to "Prefix (default)":
- (value of your map's func_instance "Fix Up Name")-(instance entity's targetname)
Using Input/Output with instances
An instance can accept Input from your map - assuming it has the proper func_instance_io_proxy Outputs setup - quite easily. Using a basic floor button example, you can add any Outputs that the proper func_instance_io_proxy has setup. You can also target one instance from another, for example using a floor button to turn on or turn off a gel flow. Again you will simply select the target entity and it's Input fields will be automatically filled out.
It's also worth noting that you can send inputs to entities within instances directly. When creating the instance, the said entity should have the @ symbol at the start of its name. After placing the instance in your map, you can then send that entity inputs directly. Valve uses this method copiously in their elevator and level transition instances.