Skip to content
adosikas edited this page Apr 17, 2021 · 12 revisions

Table of Contents

Intro

E2 works on a trigger based system, this means once the E2 gets triggered by anything, the whole code will be executed, at once, "instantaneous".

This means you cannot "delay" code or make the E2 pause or sleep. Instead you will have to save whatever data you need using @persist and schedule a timer for later.
Another effect is that all code will get executed, so even code you might not want to.
For this reason it is a good idea to have no code outside a if(<trigger check>).
I like using if(<trigger1>){<code1>} elseif(<trigger2>){<code2>} ... to make sure only one block of code runs, but this is by no means required.

Below is an example using 3 different trigger types:

  • first(), triggered when spawning the E2
  • Input, by default any change in a wire input will execute the E2
  • Timers, which are scheduled manually with timer(Name, Delay)
@name TriggerExample
@inputs Start Delay
@output Done
@persist Counter # Keep this variable between executions
if( first() ) {
  print( "E2 was spawned!" )
}
elseif( ~Start ) {
  print( "Start input changed value!")
  if( Start ) {
	Counter = Delay
	stoptimer( "decrease_counter" ) # Stop any existing timers, to combat button-spam
	timer( "decrease_counter", 1000 ) # Schedule a execution in 1000ms (=1s)
  }
}
elseif( clk( "decrease_counter" ) ) {
  print( "Triggered by timer with name decrease_counter" )
  Counter--
  if( Counter > 0) {
	timer( "decrease_counter", 1000 ) # Schedule another execution
  }
  else { # Counter <= 0
	print("Time's up!")
	Done = 1
	timer( "reset_output", 500 ) # Schedule a different timer in 0.5s
  }
}
elseif( clk("reset_output") ) {
  print( "Triggered by timer with name reset_output" )
  Done = 0
}

More Examples

There are many more trigger types, each corresponding to special events, so you do not need constantly running code to detect those.

Here are the most commonly used ones:

Chat

@name Chat
if( first() ) {
  runOnChat(1) # activate chat trigger
}
elseif( chatClk() ) { # just chatClk() returns 1 when someone wrote something in chat
  print( lastSpoke():name() + " wrote in chat: " + lastSaid())
}

Once activated with runOnChat(1), the E2 will be activated any time someone writes something to chat.

The function chatClk() checks if the current execution was trigged by a chat message.

Using chatClk( Player ) allows you to check if that certain Player sent that message.
This is commonly used as if( chatClk( owner() ) ), to make the E2 only react to commands by the owner()

The functions lastSpoke() and lastSaid() allow you to get the sender and content of the message.

For more on how to implement chat commands see: E2: Chat Commands

Dupe

@name Dupe
if( first() ) {
  print( "Spawned with Toolgun" )
}
elseif( duped() ) {
  print( "Spawned by duplicator" )
}

duped() is triggered whenever a E2 is not spawning with the E2 tool, but by any duplicator tool. This is usually used as if( first() | duped() ) to correctly initialize after a dupe or if( duped() ) { reset() } to completely reset and emulate a "fresh spawn"

Note: Advanced Duplicator (both 1 and 2) will additionally trigger for dupefinished() when it is done with spawning everything.

Tick

@name Tick
@inputs On
@outputs Dice
if( ~On ) {
  runOnTick( On ) # If On Input changed, enable/disable the tick-trigger
}
elseif( tickClk() ) {
  Dice = randint( 1, 6 ) # Output a random number every tick
}

Like Chat, the Tick-trigger has to be enabled manually. It will execute the E2 once every gametick (Default: every 15ms, 66.6x per second). You cannot interact with the world faster, so this is usually used to poll inputs, generate outputs or whenever you want something constantly running, such as physics interactions

See also E2: Detect events in the world

File

Since E2 runs on the server, whenever you want it to read one of your files it has to be sent to the server first, which takes time. Once the file is uploaded completely the file trigger executes, assuming you activated runOnFile.

@name Persistent Highscore
@inputs Score
@outputs Highscore
if( first() | duped() ) {
  Highscore=-1 # mark as invalid
  timer("tryLoad", 0) # try loading the next tick
}
elseif( clk("tryLoad") )
  if( fileCanLoad() ) {
    fileLoad("highscore.txt") # Upload data/e2files/highscore.txt
    runOnFile(1)
  }
  else {
    timer("tryLoad", 500) # try again in 500ms
  }
}
elseif( fileClk("highscore.txt") ) { # File trigger
  runOnFile(0) # no longer needed, we got our result
  if( fileStatus()==_FILE_OK ) {
    Highscore = fileRead():toNumber() # Read number and output it
  }
  else {
    error("File load failed with error code: "+fileStatus())
  }
}
elseif( ~Score ) { # Input trigger
  if( Highscore!=-1 & Score>Highscore ){ # Highscore loaded already and the new score is higher
    Highscore = Score
    print("New Highscore: "+Highscore)
    if( fileCanWrite() ) {
      fileWrite("highscore.txt", Highscore:toString() ) # directly save new value to file
    }
    else {
      print("Could not save score!") # retrying later would be much better, similar to tryLoad above
    }
  }
}

You might have noticed that we use a timer to load the file. This is because some features in E2 (like accessing files or http, creating holograms or props and find functions) are throttled, so you might have to wait some time between calling them. If the check (here fileCanRead()) fails, we just try again and again (with a brief delay) until it works, as shown above with the tryLoad timer.
Note that writing to file is done with just the single fileWrite function and needs no special trigger, since you do not have results you need to wait on.

FileList and Http triggers have pretty much the same structure.

Others

Apart from first(), duped(), Inputs, Timers, Chat and Tick there exist many other triggers that you may or may not run into. You can search the E2 Helper for "runOnXYZ" or "XYZclk" to find most of them.

Here is a quick rundown of lesser used triggers:

  • Key: whenever somone presses or releases a key
  • Last: allows you to do one last run when deleting the E2
  • FileList: Works similar to File, but gets a list of directory contents
  • Http: Works similar to File, but downloads data from a given URL
  • (Data)Signals: Used for wireless communication between E2s

Expression 2 ⚙️

Getting Started 🕊

Guides 🎓

Tools 🛠️

Click To Expand

Advanced

Beacon 💡

Control 🎛️

Data 💿

Detection 👀

Display 💻

Render 🖌

I/O 🔌

Physics 🚀

Utilities 🛠️

RFID 💳

Wireless 🛜

Gates 🚥

Click To Expand

TBD

Extras 🔭

Clone this wiki locally