Guide:Scripting
Carrion uses a custom configuration/scripting language (.cgs) to connect objects together. When a level loads for the first time in a playthrough, the game loads that level's .cgs script to define those connections. They can range from connecting a switch to a door, camera sweeps, complex circuits involving lasers, jammers, changing water levels and more.
Some objects output signals when activated, broken, or after detecting an enemy nearby, for example. Other objects change states after receiving a signal, like a door closing when the monster touches a laser, or a tentacle growing after entering a Hive Checkpoint.
Connecting objects together can be as simple as switch -> door;
, and by using operators and special methods, they can also be as complex as the user wishes.
Basic Scripting
When creating a custom level, scripts must match the name of the level and be placed in UserContent\<projectname>\Scripts
.
Lines must end in ;
, and typos can make the script stop working entirely.
To find the cause of an error or crash, you can check the gamelog.txt
file, found in %userprofile%\AppData\LocalLow\Phobia\Carrion
.
Logical Operators
NOT
Inverts the signal.
switch -> (NOT()) -> light;
AND
Outputs a signal when all the connected elements send a signal greater than 0.
switch_and = (AND());
switch_1 -> switch_and;
switch_2 -> switch_and;
switch_and -> door;
OR
Outputs a signal when any of connected elements send a signal greater than 0.
switch_or = (OR());
switch_1 -> switch_or;
switch_2 -> switch_or;
switch_or -> door;
NOR
Outputs a signal when none of the connected elements send a signal greater than 0.
switch_nor = (NOR());
switch_1 -> switch_nor;
switch_2 -> switch_nor;
switch_nor -> light;
XOR
Outputs a signal when only one of the connected elements send a signal greater than 0.
switch_xor = (XOR());
switch_1 -> switch_xor;
switch_2 -> switch_xor;
switch_xor -> light;
Truth table
A | B | AND | OR | NOR | XOR |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 0 |
0 | 1 | 0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
Arithmetic Operators
SUM
(SUM())
Adds two or more outputs together.
sum = (SUM());
switch_1 -> sum;
switch_2 -> sum;
sum -> water;
AMP
(AMP(f))
Multiplies a signal by a specified value.
water_sum = (SUM());
switch_1 -> (AMP(2)) -> water_sum; #Multiplies the signal by 2.
switch_2 -> water_sum;
water_sum -> water;
Special Methods
Delay
(DELAY(time))
Delays the signal by a specified amount of time (in seconds).
switch -> (DELAY(2.5)) -> door; #Delay by 2.5 seconds.
Pass
(PASS(initState))
A filter that passes only the specified signal.
switch_1 -> (PASS(1)) -> door_1; #This switch can only open the door.
switch_2 -> (PASS(0)) -> door_1; #This switch can only close the door.
Switch
(SWITCH(initState))
Triggers when receiving a signal opposite of initState
.
lamp_switch = (SWITCH(0));
switch -> lamp_switch;
lamp_switch -> lamp; #lamp turns on, and can't be turned off.
SR Latch
SRLATCH(initValue)
A set/reset latch. Latches on the last signal that was active.
initValue
sets which signal to start with (1 for Q
, 0 for NQ
).
srlatch = SRLATCH(0);
lamp_set -> (srlatch.Set);
lamp_reset -> (srlatch.Reset);
(srlatch.Q) -> lamp_q;
(srlatch.NQ) -> lamp_nq;
- If both Set and Reset signals are active,
Q
andNQ
will turn off. - Setting
initValue
to 0.5 will set bothQ
andNQ
to 0.5.
Sequencer
(SEQUENCER(maxFrames, maxStates, s1, s2, s3, s4))
- maxFrames (Int32): Duration of a state, in "frames" (in this case, 1 frame = a 60th of a second)
- maxStates (Int32): Amount of states, from 1 to 4.
- s1, s2, s3, s4: Signal values of the states.
Loops through up to 4 values, with a specified duration between states. Resembles a music sequencer, with maxFrames being the timing and maxStates the number of steps.
lamp_seq = (SEQUENCER(120, 4, 1, 2, 3, 4));
lamp_seq -> test_lamp; #test_lamp's signal cycles from 1 to 4, changing every 2 seconds.
lamp_seq = (SEQUENCER(210, 2, 1, 2, 3, 4));
lamp_seq -> test_lamp; #test_lamp's signal cycles from 1 to 3, changing every 3.5 seconds.
Smooth
(SMOOTH(initValue, speedOn, speedOff))
Changes the fade-in/fade-out speed of a signal.
switch -> (SMOOTH(0, 0.01, 0.001)) -> test_lamp; #Multiplies the fade-in speed by 0.01, and the fade-out speed by 0.001.
Threshold
(THRESHOLD(threshold))
Outputs a signal if input is greater than or equal to threshold
.
lamp_seq = (SEQUENCER(30, 4, 0, 1, 2, 3));
lamp_seq -> (THRESHOLD(2)) -> test_lamp; #test_lamp only turns on if the signal is greater than or equal to 2
Window Test
(WINDOW_TEST(a, b))
Outputs signal if input is within the set window (a < input < b).
lamp_seq = (SEQUENCER(30, 4, 0, 1, 2, 3));
lamp_seq -> (WINDOW_TEST(1.9, 2.1)) -> test_lamp; #test_lamp only turns on if the signal is between 1.9 and 2.1
Next Level
(NEXT_LEVEL("levelname"))
Starts a level transition.
elevator_trigger -> (NEXT_LEVEL("ending"));
Camera Sweeps
Camera Sweeps are able to move the camera around, even to other chambers. They can be used to show where the player needs to go, if a new path is being opened, if a mechanism that was disabled until now is being activated, etc.
Setting up a simple sweep
To create a sweep, you'll need:
- An input object (a switch, for example)
- A marker that the camera will move to
test_sweep = (SWEEP()) -> [test_marker, duration 0] -> [test_marker, duration 2]; #Camera will move to test_marker instantly, then stay there for 2 seconds.
test_switch -> test_sweep;
Sweep Event
A Sweep Event is a way to trigger something in the middle of a sweep. After creating a sweep event, calling it with (WAIT_FOR_EVENT(sweep_name))
will allow you to output a signal when the event occurs.
test_event = (SWEEP_EVENT());
test_sweep = (SWEEP()) -> [test_marker, duration 0] -> [test_event, duration 0] -> [test_marker, duration 2]; #After the camera reaches test_marker, trigger test_event and stay there for 2 seconds.
(WAIT_FOR_EVENT(test_event)) -> test_door; #When test_event happens, open test_door.
test_switch -> test_sweep;
Wait for Event
(WAIT_FOR_EVENT(sweep_event))
Outputs a signal when sweep_event
occurs.
Sweep Types
Type | Player Control | Enemy AI |
---|---|---|
(SWEEP()) |
Disabled | Disabled |
(SWEEP_CONTROLS()) |
Enabled | Disabled |
(SWEEP_AI()) |
Disabled | Enabled |
(SWEEP_AI_CONTROLS()) |
Enabled | Enabled |