Portal BTS - Tutorial - Piston Crushers
Introduction
This guide will show you how to create various piston types.
Vertical Pistons
Piston Type 1
Piston Base
Create a prop_static and enter the following properties.
| Property Name | Value |
|---|---|
| World Model | models/props_bts/vertical_small_piston_base.mdl |
| Disable Shadows | Yes |
Piston Model
Create a prop_dynamic and enter the following properties.
| Property Name | Value |
|---|---|
| Parent | crusher_1 |
| World Model | models/props_bts/vertical_small_piston_body.mdl |
| Disable Shadows | Yes |
| Collisions | Not Solid |
| Lighting Origin | crusher_lighting_1 |
Piston Movement
Create a 32*32*288 brush with the nodraw texture and create a 146*146*4 Cylinder with 16 sides with the nodraw texture. Position the brushes as seen in the screenshot.
After positioning the brushes, select both brushes and tie them to a func_door and enter the following properties
| Property Name | Value |
|---|---|
| Name | crusher_1 |
| Delay Before Reset | -1 |
| Lip | 128 |
| Blocking Damage | 25 |
| Force Closed | Yes |
| Move Direction | 90 0 0 |
Do not miss the Delay.
Under flags, uncheck Touch Opens and check Door Silent
Piston Collision
Create a 146*146*322 cylinder with 16 sides with the playerclip texture and set tie it to a func_brush. Set its parent to crusher_1.
Piston Sounds
Create a logic_relay entity and enter the following properties
| Property Name | Value |
|---|---|
| Name | relay_stop_sound_room_1_1 |
| Start Disabled | Yes |
Enter this output
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | stop_sound_room_1_1 | Playsound | <none> | 0.00 | No |
Create an ambient_generic and enter the following properties.
| Property Name | Value |
|---|---|
| Name | stop_sound_room_1_1 |
| Sound Name | Portal.giant_piston |
| Pitch | 200 |
| Start Pitch | 200 |
| SourceEntityName | crusher_1 |
Crusher Lighting
Create an info_target and set its name to crusher_lighting_1. This is the light source of the piston body model. Place this in a logical spot like near the piston base model.
Implementation
To start the piston, enable the relay_stop_sound_room_1_1 entity and open crusher_1. When the player gets considerably far away from the piston, disable the relay_stop_sound_room_1_1 entity
Piston Type 2
These pistons were specifically used to block off an entry in escape_00.
Piston Base
Create a prop_static and enter the following properties
| Property Name | Value |
|---|---|
| World Model | models/props_bts/vertical_med_piston_base.mdl |
| Disable Shadows | Yes |
Piston Body
Create a prop_dynamic and enter the following properties
| Property Name | Value |
|---|---|
| Parent | crusher_blocker_1 |
| World Model | models/props_bts/vertical_med_piston_body.mdl |
| Disable Shadows | Yes |
| Lighting Origin | crusher_blocker_lighting_1 |
Piston Movement
Create a 32*32*384 brush with the invisible texture, tie it to a func_door and enter the following properties
| Property Name | Value |
|---|---|
| Name | crusher_blocker_1 |
| Speed | 80 |
| Delay Before Reset | -1 |
| Lip | 288 |
| Blocking Damage | 25 |
| Force Closed | Yes |
| Move Direction | 90 0 0 |
Do not miss the Delay.
Under flags, uncheck Touch Opens, check Passable and Door Silent
Piston Sounds
Create a logic_relay entity and enter the following properties
| Property Name | Value |
|---|---|
| Name | relay_stop_sound_room_1_1 |
| Start Disabled | Yes |
Enter this output
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | stop_sound_room_1_1 | Playsound | <none> | 0.00 | No |
Create an ambient_generic and enter the following properties.
| Property Name | Value |
|---|---|
| Name | stop_sound_room_1_1 |
| Sound Name | Portal.giant_piston |
| Pitch | 200 |
| Start Pitch | 200 |
| SourceEntityName | crusher_blocker_1 |
Crusher Lighting
Create an info_target and set its name to crusher_blocker_lighting_1. This is the light source of the piston body model. Place this in a logical spot like near the piston base model.
Implementation
To start the piston, enable the relay_stop_sound_room_1_1 entity and open crusher_blocker_1. When the player gets considerably far away from the piston, disable the relay_stop_sound_room_1_1 entity.
Piston Type 3
This is the most common vertical piston
Piston Base
Create a prop_static and enter the following properties.
| Property Name | Value |
|---|---|
| World Model | models/props_bts/vertical_large_piston_base.mdl |
| Disable Shadows | Yes |
Piston Body
Create a prop_dynamic and enter the following properties.
| Property Name | Value |
|---|---|
| Parent | crusher_1 |
| World Model | models/props_bts/vertical_large_piston_body.mdl |
| Disable Shadows | Yes |
| Name | crusher_brush_1 |
| Lighting Origin | crusher_lighting_1 |
Piston Movement
Create a 32*32*640 brush with the invisible texture and tie it to a func_door.
| Property Name | Value |
|---|---|
| Name | crusher_1 |
| Speed | 90 |
| Delay Before Reset | -1 |
| Lip | 16 |
| Blocking Damage | 25 |
| Force Closed | Yes |
| Move Direction | 90 0 0 |
Enter these outputs:
Do not miss the delays
Under flags, uncheck Touch Opens and check Door Silent
Piston Collision
Create a 152*152*960 cylinder with 16 sides with the invisible texture and tie it to a func_brush.
Set its parent to crusher_1
Piston Sounds
Create a logic_relay entity and enter the following properties
| Property Name | Value |
|---|---|
| Name | relay_stop_sound_room_1_1 |
| Start Disabled | Yes |
Enter this output
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | stop_sound_room_1_1 | Playsound | <none> | 0.00 | No |
Create an ambient_generic and enter the following properties.
| Property Name | Value |
|---|---|
| Name | stop_sound_room_1_1 |
| Sound Name | Portal.giant_piston |
| Pitch | 200 |
| Start Pitch | 200 |
| SourceEntityName | crusher_1 |
Crusher Lighting
Create an info_target and set its name to crusher_lighting_1. This is the light source of the piston body model. Place this in a logical spot like near the piston base model.
Implementation
To start the piston, enable the relay_stop_sound_room_1_1 entity and open crusher_1. When the player gets considerably far away from the piston, disable the relay_stop_sound_room_1_1 entity.
Horizontal Pistons
Fast Piston
Piston Base
Create a prop_static and enter the following properties
| Property Name | Value |
|---|---|
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/horizontal_piston_base.mdl |
| Disable Shadows | Yes |
Piston Body
Create a prop_dynamic and enter the following properties
| Property Name | Value |
|---|---|
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/horizontal_piston_body.mdl |
| Disable Shadows | Yes |
| Lighting Origin | crusher_lighting01 |
Piston Movement
While all brushes are selected, tie the selection to a func_door and enter the following properties
| Property Name | Value |
|---|---|
| Name | crusher01 |
| Speed | 200 |
| Start Sound | Doors.Move10 |
| Stop Sound | Doors.FullClose10 |
| Delay Before Reset | -1 |
| Lip | 64 |
| Blocking Damage | 100 |
| Force Closed | Yes |
| Move Direction | 0 180 0 |
Enter these outputs:
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnFullyClosed | shake_crusher01 | StartShake | <none> | 0.00 | No | |
| OnFullyClosed | !self | Open | <none> | 2.00 | No | |
| OnFullyOpen | !self | Close | <none> | 2.00 | No |
Under flags, uncheck Touch Opens and check Door Silent
Piston Lighting
Create an info_target and set its name to crusher_lighting01. This is going to be the lighting origin of the piston body prop. Place it in a reasonable spot.
Piston Pressure Pad
Create a 112*144*4 brush with the nodraw texture. Tie the brush to a func_detail and cut the brush as seen in the image.
Open the Transformation window and type 270under the Y Axis and press OK
Open the Face Edit Sheet select all faces except for the back side. Set the texture to metal/metalwall_bts_004a and set the rotation to 90.
Add an overlay with the overlays/stain_oil_03 texture. Center the overlay with the front face.
Piston Shake
Create an env_shake and enter the following properties
| Property Name | Value |
|---|---|
| Name | shake_crusher01 |
| Effect Radius | 496 |
| Frequency | 100 |
Implementation
To start the piston, open crusher_blocker_1. Only start the piston when the player gets considerably close.
Normal Speed Piston
Piston Base
Create a prop_static and enter the following properties
| Property Name | Value |
|---|---|
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/vertical_med_piston_base.mdl |
| Disable Shadows | Yes |
Piston Body
Create a prop_static and enter the following properties
| Property Name | Value |
|---|---|
| Parent | crusher1 |
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/vertical_med_piston_base.mdl |
| Disable Shadows | Yes |
| Collisions | Not Solid |
Piston Movement
While both brushes are selected, tie the entity to a func_door. Position the entity as seen in the image and enter the following properties
| Property Name | Value |
|---|---|
| Name | crusher1 |
| Delay Before Reset | -1 |
| Lip | 64 |
| Blocking Damage | 25 |
| Force Closed | Yes |
| Move Direction | 0 180 0 |
Enter the following outputs
Under flags, uncheck Touch Opens and check Door Silent
Piston Sounds
Create a logic_relay and enter the following properties
| Property Name | Value |
|---|---|
| Name | relay_stop_sound_room_1_1 |
| Start Disabled | Yes |
Enter this output
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | stop_sound_room_1_1 | PlaySound | <none> | 0.00 | No |
Create an ambient_generic and enter the following properties
| Property Name | Value |
|---|---|
| Name | stop_sound_room_1_1 |
| Sound Name | Portal.giant_piston |
| Pitch | 125 |
| Start Pitch | 125 |
| SourceEntityName | crusher1 |
Piston Pressure Pad
Create a 112*144*4 brush with the nodraw texture. Tie the brush to a func_detail and cut the brush as seen in the image.
Open the Transformation window and type 270under the Y Axis and press OK
Open the Face Edit Sheet select all faces except for the back side. Set the texture to metal/metalwall_bts_004a and set the rotation to 90.
Add an overlay with the overlays/stain_oil_03 texture. Center the overlay with the front face.
Other Pistons
Mini Pistons
These pistons are only seen in testchmb_a_15 after exiting and falling down the elevator shaft.
Piston Base
Piston Body
Use the
Vertex Toolto match each vertex as seen in the image.
While all brushes are selected, tie the brushes to a func_door and enter the following properties
| Property Name | Value |
|---|---|
| Name | mini_crusher_1 |
| Disable Shadows | Yes |
| Speed | 50 |
| Start Sound | Doors.Move14 |
| Stop Sound | Doors.FullClose9 |
| Delay Before Reset | -1 |
| Blocking Damage | 1 |
| Move Direction | 90 0 0 |
Enter the following outputs
Under Flags, uncheck Touch Opens and Check Starts Open
Piston Brush
Create a 64*64*180 brush with the playerclip texture. Clip and position the brush as seen in the image.
Create a 64*64*4 brush on top of that brush, clip the brush as seen in the image and texture all faces with metal/metalwall_bts_001b. Set both texture shift values to -256.
Select both the playerclip brush and the top brush and tie them to a func_brush then enter the following properties
| Property Name | Value |
|---|---|
| Parent | mini_crusher_1 |
| Disable Shadows | Yes |
| Minimum Light Level | .2 |
Piston Steam
Create an env_steam and enter the following properties.
| Property Name | Value |
|---|---|
| Name | steam_pressure_release1 |
| Pitch Yaw Roll | -30 0 0 |
| Length of steam jet | 60 |
Create an env_steam and enter the following properties.
| Property Name | Value |
|---|---|
| Name | steam_pressure_release1 |
| Pitch Yaw Roll | -30 90 0 |
| Length of steam jet | 60 |
Create an env_steam and enter the following properties.
| Property Name | Value |
|---|---|
| Name | steam_pressure_release1 |
| Pitch Yaw Roll | -30 180 0 |
| Length of steam jet | 60 |
Create an env_steam and enter the following properties.
| Property Name | Value |
|---|---|
| Name | steam_pressure_release1 |
| Pitch Yaw Roll | -30 270 0 |
| Length of steam jet | 60 |
Place each env_steam as seen in the image.
Create an ambient_generic and enter the following properties
| Property Name | Value |
|---|---|
| Name | sound_steam |
| Sound Name | ambient.steam01 |
Under flags, uncheck Is NOT Looped. Place the ambient_generic inside the mini-piston body
Mini-Piston Logic
Create a logic_relay and set its name to close_mini_crusher_1 and enter the following outputs.
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | mini_crusher_1 | SetSpeed | 40 | 0.00 | No | |
| OnTrigger | mini_crusher_1 | Open | <none> | 0.01 | No |
Create a logic_relay and set its name to open_mini_crusher_1 and enter the following outputs.
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnTrigger | mini_crusher_1 | SetSpeed | 80 | 0.00 | No | |
| OnTrigger | mini_crusher_1 | Close | <none> | 0.01 | No |
Do not miss the delays.
Separator Pistons
These pistons are seen in escape_00 after flinging up high. Only use these pistons in a group. 3-4 at the minimum.
Base Model
Create a prop_dynamic and enter the following properties.
| Property Name | Value |
|---|---|
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/mini_piston_body.mdl |
| Disable Shadows | Yes |
| Lighting Origin | lighting_crusher_blocker_1 |
Body Model
Create a prop_dynamic and enter the following properties.
| Property Name | Value |
|---|---|
| Parent | crusher_blocker_1 |
| Pitch Yaw Roll | 90 0 0 |
| World Model | models/props_bts/mini_piston_inside.mdl |
| Disable Shadows | Yes |
Piston Movement
Create a 160*32*32 with the invisible texture and tie it to a func_door. Enter the following properties.
| Property Name | Value |
|---|---|
| Name | crusher_blocker_1 |
| Speed | 400 |
| Delay Before Reset | -1 |
| Blocking Damage | 25 |
| Force Closed | Yes |
| Move Direction | 0 180 0 |
Enter the following outputs
| My Output | Target Entity | Target Input | Parameter | Delay | Only Once | |
|---|---|---|---|---|---|---|
| OnFullyClosed | !self | Open | <none> | 0.00 | No | |
| OnFullyOpen | !self | Close | <none> | 0.00 | No |
Under flags, uncheck Touch Opens and check Non-solid to Player, Passable and Door Silent.
Piston Lighting
Create an info_target and set its name to lighting_crusher_blocker_1. This is the lighting for the piston base. Place it in a reasonable spot.
Piston Sounds
Create an ambient_generic and enter the following properties. Remember to only place one of these in a group.
| Property Name | Value |
|---|---|
| Name | enginesound_room_1 |
| Sound Name | Portal.moving_pistons |
| Pitch | 50 |
| Start Pitch | 50 |
Under flags uncheck Is NOT Looped.
Implementation
Open crusher_blocker_1 and play the enginesound_room_1 sound. When the player gets considerably far away, stop the enginesound_room_1 sound.
Extra
- If a vertical piston's end point is a concrete texture, add an overlay textured with
overlays/stain_oil_03oroverlays/stain_oil_04.
- If a normal speed horizontal piston's end point is a metal texture, you can remove the pressure pad.
- The Mini Pistons are just scaled down portal beta pistons.



