Skip to main content

Starting Scripts

Script.start Method

The primary method for starting scripts programmatically:
# Basic usage
script_obj = Script.start("script_name")

# With arguments
script_obj = Script.start("script_name", "arg1 arg2 arg3")

# With options
script_obj = Script.start("script_name", "args", { quiet: true })

# Force start (even if already running)
script_obj = Script.start("script_name", "args", { force: true })

Global Helper Methods

# Convenient wrapper for Script.start
start_script("script_name", ["arg1", "arg2"])

# Start multiple scripts
start_scripts("script1", "script2", "script3")

# Force start (restart if running)
force_start_script("script_name", ["args"], { quiet: true })

Script.run (Blocking)

Wait for a script to complete before continuing:
# Start script and wait for it to finish
Script.run("helper_script", "args")
echo "Helper script has completed"

Script.current

Access the currently executing script:
script = Script.current

echo "Script name: #{script.name}"
echo "Script args: #{script.vars.inspect}"
echo "Script file: #{script.file_name}"
echo "Is custom? #{script.custom?}"
Script.current returns nil if called outside of a script context (e.g., from the command line).

Script Properties

script = Script.current

# Identification
script.name           # Script name
script.file_name      # Full path to script file
script.custom?        # true if in custom/ directory

# Arguments
script.vars           # Array of command-line arguments
script.command_line   # Original command line

# Behavior flags
script.quiet          # Suppress start/stop messages
script.no_echo        # Suppress echo output
script.silent         # Completely silent mode
script.hidden         # Hidden from script list

# State
script.paused         # Paused state
script.paused?        # Check if paused

Before Dying Callbacks

Register cleanup code to run when a script exits:
# Using Script.at_exit
Script.at_exit do
  echo "Cleaning up resources..."
  fput "stance defensive"
  Settings.save
end

# Using before_dying helper
before_dying {
  echo "Script is exiting"
  # Restore original state
  fput "remove my weapon"
}

# Multiple callbacks are supported
Script.at_exit { echo "First cleanup" }
Script.at_exit { echo "Second cleanup" }
Callbacks are executed in the order they were registered. If a callback raises an error, subsequent callbacks will still run.

Clearing Exit Callbacks

# Remove all registered callbacks
Script.clear_exit_procs
undo_before_dying  # Helper method

Script Termination

Normal Exit

# Exit with cleanup (runs before_dying callbacks)
exit

# Exit immediately without cleanup
Script.exit!
abort!  # Helper method

Killing Other Scripts

# Check if script is running
if Script.running?("other_script")
  Script.kill("other_script")
end

# Using helper method
stop_script("script1", "script2")

# Check running status
if running?("combat_script", "healing_script")
  echo "All required scripts are running"
end

Die With Me

Automatically kill other scripts when current script exits:
# These scripts will be killed when current script exits
die_with_me("helper_script", "support_script")

# Via script property
script = Script.current
script.die_with.push("dependent_script")

Script States

Pausing and Unpausing

# Pause current script
pause_script
Script.pause

# Pause another script
Script.pause("other_script")
pause_script("other_script")

# Unpause
Script.unpause("other_script")
unpause_script("other_script")

# Check pause state
if Script.paused?("other_script")
  echo "Script is paused"
end

Hiding Scripts

# Hide current script from ;listscripts
hide_me

# Hide another script
hide_script("background_script")

# Scripts in script.hidden are still accessible
all_scripts = Script.running + Script.hidden

Pause/Kill Protection

# Protect from ;pauseall
no_pause_all

# Protect from ;killall  
no_kill_all

script = Script.current
script.no_pause_all = true
script.no_kill_all = true

Listing Scripts

# Get all visible running scripts
Script.running.each do |s|
  echo "Running: #{s.name}"
end

# Get all scripts (including hidden)
Script.list.each do |s|
  echo "#{s.name} (hidden: #{s.hidden})"
end

# Get only hidden scripts
Script.hidden.each do |s|
  echo "Hidden: #{s.name}"
end

Script Existence

# Check if script file exists
if Script.exists?("helper")
  start_script("helper")
else
  echo "helper.lic not found"
end

# Supports various extensions
Script.exists?("myscript")      # Checks .lic, .rb, .cmd, .wiz
Script.exists?("myscript.lic")  # Exact filename

Thread Management

script = Script.current

# Get script's thread group
thread_group = script.thread_group

# Check if thread belongs to script
if script.has_thread?(Thread.current)
  echo "This thread belongs to the script"
end

# List all threads in script
script.thread_group.list.each do |thread|
  echo "Thread: #{thread.inspect}"
end

Execution Scripts

Execute code snippets as temporary scripts:
# Start an exec script
exec_script = start_exec_script('echo "Hello from exec script"')

# With options
exec_script = start_exec_script(
  'put "look"\nwaitfor "Obvious"',
  { quiet: true, name: "quick_look" }
)
Exec scripts are automatically named exec1, exec2, etc. unless a custom name is provided.

Complete Example

# Script: example_lifecycle.lic
# version: 1.0.0

script = Script.current

# Setup
echo "Starting #{script.name}"
script.hidden = true
no_kill_all

# Register cleanup
before_dying {
  echo "Cleaning up..."
  fput "stance defensive"
  stop_script("helper") if running?("helper")
}

# Start dependencies
start_script("helper")
die_with_me("helper")

# Main logic
begin
  loop do
    # Script work here
    pause 1
  end
rescue SystemExit
  echo "Exit requested"
rescue => e
  echo "Error: #{e.message}"
  echo e.backtrace.first
ensure
  # This runs even on errors
  echo "Script ending"
end

Next Steps

Global Methods

Learn about available game interaction methods

Threading

Create multi-threaded scripts for parallel execution

Build docs developers (and LLMs) love