Tutorials

Episode 1 Crank



This tutorial will show you how to recreate the crank mini-puzzle from just after the elevator in Episode 1. It uses two models from Episode 1. If you don't have it, there's a short section at the bottom on getting this to work with a brush-based crank. Example maps are included for both.

I'll assume you know how to create brushes, entities, assign models, and have a working knowledge of the I/O system. I'll go step by step.

The Puzzle:
In this puzzle, the player must first find a crank wheel, put it into its little hole, and then turn it to open a door. The distance he turns it is equivalent to the distance the door moves.

There are 10 entities used:

Props
prop_dynamic_override
prop_physics
prop_static

Points
ambient_generic
filter_activator_name
point_template

Brush
func_brush
func_movelinear
momentary_rot_button
trigger_once

1. Visual Setup


First, make a room divided into two sections with a gate in the middle. Now, build a slot above the gate that is slightly wider than it:

news post image news post image

Turn the gate into a func_movelinear entity give it these properties:
Name: fml_gate
Move direction: Up
Speed: 100
Move distance: This depends on the height of your gate. You want to set it to the height of the gate minus a reasonable lip. Mine is 128 units high with a move distance of 96. This way it will be protruding nicely from the ceiling when it stops moving.
Sound played when the brush starts: Doors.Move11
Sound played when the brush stops: Doors.FullClose8

Now, create a prop_static using the 'widget' model from Episode 1. Then, create a prop_dynamic_override using the 'crank' model align the two so that the prop_dynamic_override is inserted into the 'widget' hole:

news post image

Give the prop_dynamic_override these properties:
Name: pdo_crank_inserted
Disable shadows: yes for performance, no for realism

Now create a prop_physics, also using the 'crank' model with these properties:
Name: pp_crank
Disable shadows: once again, your choice for performance issues

Rotate the prop_physics model slightly and stick it in the corner, otherwise it will roll around in circles incessantly:

news post image

2. Triggers and such

Hide the 'widget' prop and get your trigger texture out. Create a small brush, 4x4x3 around the hole, extending 1.5 units into the model and 1.5 units out. Turn it into a trigger_once with these properties:
Name: to_crank
Start disabled: yes

news post image

The only flag checked should be 'Physics objects'

Create a brush covered in nodraw that is slightly thiner and shorter than the crank, and extends to the wall and just past the prop_dynamic_override crank:

news post image

Turn this brush into a momentary_rot_button and give it the following properties:
Name: mrb_crank
Speed: 100
Sounds: Clean Ratchet
Distance: 1000
Auto Return Speed: You have a choice here. If you want the wheel to rotate backwards and the gate to drop if the player stops using it before it's fully open then set a speed here and uncheck the Toggle flag. I didnt.
Solid BSP: No
Flags:
Not Solid, Toggle, Use Activates, Starts Locked also set x or y axis depending on it and the prop_dynamic_override's axis of rotation

Now, go back to the prop_dynamic_override and set it's Parent property to the name of the momentary_rot_button; mrb_crank

Select the playerclip texture and create a brush encasing the whole prop_dynamic_override crank setup on the wall. Make it end in the same place as the momentary_rot_button and extend a few units to each side:

news post image

Turn the clip brush into a func_brush with the following properties:
Name: fb_clip
Solidity: Always solid
Solid BSP: No

Create a point_template and give it the following properties:
Template 1: name of the prop_dynamic_override; pdo_crank

Now make a filter_activator_name and give it these properties:
Name: fac_crank
Filter name: name of the prop_physics crank, pp_crank

Now go back to the trigger_once, to_crank, and set it's Filter Name property to the name of the filter_activator_name; fac_crank. This is so only the crank can activate the inputs and outputs that make this all work

Time for the last entity, an ambient_generic with the properties:
Name: ag_crankinserted
Sound Name: Metal_Barrel.BulletImpact

3. The 'ol in and out

Time for the I/O to get it all working:

prop_physics; pp_crank
My output named: OnPhysGunDrop
Target entities named: to_crank
Via this input: Disable

My output name: OnPhysGunPickup
Target entities named: to_crank
Via this input: Enable

These outputs make sure that the player can't throw the crank into the hole with either the gravity gun, or +USE

trigger_once; to_crank

My output named: OnTrigger
Target entities named: pt_crank
Via this input: ForceSpawn

This causes the point_template to create the model of the crank which is inserted into the hole when the prop_physics version get's close enough

My output named: OnTrigger
Target entities named: ag_crankinserted
Via this input: PlaySound

Play's a sound of metal hitting metal

My output named: OnTrigger
Target entities named: to_crank
Via this input: Kill

This removes the trigger_once from the world so that A. it can't be triggered again and B. the game engine's world manager doesn't have to think about it any more, which frees up CPU and RAM resources

My output named: OnTrigger
Target entities named: pp_crank
Via this input: Kill

Removes the prop_physics from the world, making it disappear and freeing up resources

My output named: OnTrigger
Target entities named: mrb_crank
Via this input: Unlock

Makes the momentary_rot_button useable

point_template; pt_crank

My output named: OnEntitySpawned
Target entities named: fb_clip
Via this input: Kill

This removes the clip brush from the world, allowing the player to get closer to the crank, and once again, freeing up resources
The reason the clip brush is there in the first place is to prevent all possible of the prop_dynamic_override crank from spawning inside the player, which would kill him

momentary_rot_button; mrb_crank

My output named: Position
Target entities named: fml_gate
Via this input: SetPosition

This makes the gate move relative to the turning of the crank. For example, because the momentary_rot_button's Move distance property is set to 1000 and Speed is set to 100, it will take ten seconds to fully turn the crank. So after, five seconds, or 500 degrees, the gate will half moved up by half of it's final distance.

IF and only IF you set an Auto-retun speed for the momentary_rot_button, mro_crank, you should add these outputs to the func_move_linear, fml_gate:

My output named: OnFullyOpen
Target entities named: pdo_crank
Via this input: SetParent
With a parameter override of: <none>

My output named: OnFullyOpen
Target entities named: mrb_crank
Via this input: Kill

This will cause the gate to 'lock' into place so it won't auto-return when fully opened preventing the player from closing the gate.

4. Using Brushes instead of Models

So you don't have Episode 1, or you just don't like the crank model? Don't despair, you can get this to work with a brush based crank!

First your going to need to make a crank sitting on the floor, and a little thingy on the wall that will hold it.
Now, copy the crank and align it with the little holder on the wall, just like as if you were doing with the models.
Turn the crank sitting on the floor into a func_physbox and give it the following properties and flags:
Name: fpb_crank
Prop Data: Metal.Small
Preferred Player-carry Angles: This depends on the orientation of your crank in the world, so you'll have to experiment. You'll know you got it right when the wheel part is facing you and the axle sticks straight out in front.
Flags: Use preferred carry angles, Generate ouput on +USE

Give it the same Outputs as the above prop_physics

Now, turn the crank that's sticking into the holder into a momentary_rot_button with all the same properties as the one above except don't check the Starts Locked flag
Set the point_template's Template 1 property to the name of the momentary_rot_button, mrb_crank
Get rid of the output on the trigger_once that target's the momentary_rot_button. Change the output that kill's the prop_physics pp_crank so that it target's the func_physbox fpb_crank
Select the filter_activator_name and change it's Filter name property to the name of the func_physbox, fpb_crank.

And that's it! You should now have the same crank mini-puzzle from Episode 1!

The sample .vmf's are in a .zip archive located here

-Mr Happy

View comments ( 15 )

Back to top