
<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
        <link rel="prev" href="json.html">
      
      
        <link rel="next" href="best_practices.html">
      
      
      <link rel="icon" href="../src/images/logo_square.png">
      <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.19">
    
    
      
        <title>JavaScript Scripting - Synesthesia Docs</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.7e37652d.min.css">
      
      


    
    
      
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
      <link rel="stylesheet" href="../stylesheets/sass_output.css">
    
    <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
    
  </head>
  
  
    <body dir="ltr">
  
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#javascript-scripting" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

  

<header class="md-header md-header--shadow" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href="../index.html" title="Synesthesia Docs" class="md-header__button md-logo" aria-label="Synesthesia Docs" data-md-component="logo">
      
  <img src="../src/images/logo_square.png" alt="logo">

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            Synesthesia Docs
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              JavaScript Scripting
            
          </span>
        </div>
      </div>
    </div>
    
    
      <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
    
    
    
      
      
        <label class="md-header__button md-icon" for="__search">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        </label>
        <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
        
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
          
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list" role="presentation"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
      
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    



<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="../index.html" title="Synesthesia Docs" class="md-nav__button md-logo" aria-label="Synesthesia Docs" data-md-component="logo">
      
  <img src="../src/images/logo_square.png" alt="logo">

    </a>
    Synesthesia Docs
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
  
  
  
  
    <li class="md-nav__item">
      <a href="../index.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Introduction
    
  </span>
  

      </a>
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
        
          
          <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Quick Links
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_2">
            <span class="md-nav__icon md-icon"></span>
            Quick Links
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="audio_uniforms.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Audio Uniforms
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="standard_uniforms.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Standard Uniforms
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="functions.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Functions
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="json.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    JSON Configuration
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
        
          
          <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    FAQ
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_3">
            <span class="md-nav__icon md-icon"></span>
            FAQ
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/index.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    General
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/troubleshooting.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Troubleshooting
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/license.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    License
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/audio.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Audio
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/video.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Video
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/settings.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Settings
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../faq/midi_osc.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    MIDI & OSC
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
    
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--active md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
        
          
          <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    SSF Documentation
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
          <label class="md-nav__title" for="__nav_4">
            <span class="md-nav__icon md-icon"></span>
            SSF Documentation
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="ssf.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Synesthesia Shader Format (SSF)
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="audio_uniforms.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Audio Uniforms
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="standard_uniforms.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Standard Uniforms
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="functions.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    SSF Functions
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="libraries.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    External Libraries
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="json.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    JSON Configuration
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
    
  
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
      
      
        
      
      
        <label class="md-nav__link md-nav__link--active" for="__toc">
          
  
  
  <span class="md-ellipsis">
    JavaScript Scripting
    
  </span>
  

          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <a href="script.html" class="md-nav__link md-nav__link--active">
        
  
  
  <span class="md-ellipsis">
    JavaScript Scripting
    
  </span>
  

      </a>
      
        

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#overview" class="md-nav__link">
    <span class="md-ellipsis">
      Overview
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#update-and-setup-functions" class="md-nav__link">
    <span class="md-ellipsis">
      Update and Setup Functions
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#gettingsetting-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Getting/Setting Uniforms
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Getting/Setting Uniforms">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#accessing-input-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Accessing Input Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#setting-output-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Setting Output Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#modifying-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Modifying Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#deprecated-inputs-and-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      DEPRECATED: inputs and uniforms
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#updating-controls" class="md-nav__link">
    <span class="md-ellipsis">
      Updating Controls
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Updating Controls">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#setcontrol" class="md-nav__link">
    <span class="md-ellipsis">
      setControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#setcontrolnormalized" class="md-nav__link">
    <span class="md-ellipsis">
      setControlNormalized()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#randomizecontrol" class="md-nav__link">
    <span class="md-ellipsis">
      randomizeControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#defaultcontrol" class="md-nav__link">
    <span class="md-ellipsis">
      defaultControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#randomizegroup" class="md-nav__link">
    <span class="md-ellipsis">
      randomizeGroup()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#defaultgroup" class="md-nav__link">
    <span class="md-ellipsis">
      defaultGroup()
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#event-system" class="md-nav__link">
    <span class="md-ellipsis">
      Event System
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Event System">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#registering-event-handlers" class="md-nav__link">
    <span class="md-ellipsis">
      Registering Event Handlers
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#examples" class="md-nav__link">
    <span class="md-ellipsis">
      Examples
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#object-oriented-programming" class="md-nav__link">
    <span class="md-ellipsis">
      Object Oriented Programming
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#reading-pixel-data" class="md-nav__link">
    <span class="md-ellipsis">
      Reading Pixel Data
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Reading Pixel Data">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#texturefinalpassxy" class="md-nav__link">
    <span class="md-ellipsis">
      textureFinalPass(x,y)
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#example" class="md-nav__link">
    <span class="md-ellipsis">
      Example
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#printing-to-the-console" class="md-nav__link">
    <span class="md-ellipsis">
      Printing to the Console
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
      
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="best_practices.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Best Practices
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
        
          
          <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Synesthesia Manual
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_5">
            <span class="md-nav__icon md-icon"></span>
            Synesthesia Manual
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../manual/control_hotkeys.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Control Hotkeys
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../manual/osc.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    OSC
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
        
          
          <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Tutorials
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_6">
            <span class="md-nav__icon md-icon"></span>
            Tutorials
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/links.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    External Links
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/quickstart_guide.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Quickstart Guide
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/first_scene.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Creating Your First Scene
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/presets_favslots_playlists.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    How to Use Presets, Favslots, and Playlists
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/control_hotkeys.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    How to Use Control Hotkeys
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/livestream.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    How to Add Audio Reactive Visuals to a Livestream with OBS
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/shadertoy_conversion.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    How to Manually Convert from Shadertoy.com to SSF
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/1.19_javascript.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    How to Update Controls and Use Event Handlers with JavaScript
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../tutorials/1.16_walkthrough.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    v1.16 Feature Walkthrough
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
      
      
  
  
  
  
    
    
    
    
    
    <li class="md-nav__item md-nav__item--nested">
      
        
        
        <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
        
          
          <label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
            
  
  
  <span class="md-ellipsis">
    Resources
    
  </span>
  

            <span class="md-nav__icon md-icon"></span>
          </label>
        
        <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
          <label class="md-nav__title" for="__nav_7">
            <span class="md-nav__icon md-icon"></span>
            Resources
          </label>
          <ul class="md-nav__list" data-md-scrollfix>
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../resources/syn_installers.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Synesthesia Installers
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../resources/changelogs.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Synesthesia Changelogs
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../resources/syn_resources.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    Synesthesia Resources
    
  </span>
  

      </a>
    </li>
  

              
            
              
                
  
  
  
  
    <li class="md-nav__item">
      <a href="../resources/glsl_resources.html" class="md-nav__link">
        
  
  
  <span class="md-ellipsis">
    GLSL Resources
    
  </span>
  

      </a>
    </li>
  

              
            
          </ul>
        </nav>
      
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#overview" class="md-nav__link">
    <span class="md-ellipsis">
      Overview
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#update-and-setup-functions" class="md-nav__link">
    <span class="md-ellipsis">
      Update and Setup Functions
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#gettingsetting-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Getting/Setting Uniforms
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Getting/Setting Uniforms">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#accessing-input-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Accessing Input Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#setting-output-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Setting Output Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#modifying-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      Modifying Uniforms
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#deprecated-inputs-and-uniforms" class="md-nav__link">
    <span class="md-ellipsis">
      DEPRECATED: inputs and uniforms
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#updating-controls" class="md-nav__link">
    <span class="md-ellipsis">
      Updating Controls
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Updating Controls">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#setcontrol" class="md-nav__link">
    <span class="md-ellipsis">
      setControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#setcontrolnormalized" class="md-nav__link">
    <span class="md-ellipsis">
      setControlNormalized()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#randomizecontrol" class="md-nav__link">
    <span class="md-ellipsis">
      randomizeControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#defaultcontrol" class="md-nav__link">
    <span class="md-ellipsis">
      defaultControl()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#randomizegroup" class="md-nav__link">
    <span class="md-ellipsis">
      randomizeGroup()
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#defaultgroup" class="md-nav__link">
    <span class="md-ellipsis">
      defaultGroup()
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#event-system" class="md-nav__link">
    <span class="md-ellipsis">
      Event System
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Event System">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#registering-event-handlers" class="md-nav__link">
    <span class="md-ellipsis">
      Registering Event Handlers
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#examples" class="md-nav__link">
    <span class="md-ellipsis">
      Examples
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#object-oriented-programming" class="md-nav__link">
    <span class="md-ellipsis">
      Object Oriented Programming
    </span>
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#reading-pixel-data" class="md-nav__link">
    <span class="md-ellipsis">
      Reading Pixel Data
    </span>
  </a>
  
    <nav class="md-nav" aria-label="Reading Pixel Data">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#texturefinalpassxy" class="md-nav__link">
    <span class="md-ellipsis">
      textureFinalPass(x,y)
    </span>
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#example" class="md-nav__link">
    <span class="md-ellipsis">
      Example
    </span>
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#printing-to-the-console" class="md-nav__link">
    <span class="md-ellipsis">
      Printing to the Console
    </span>
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          
            <div class="md-content" data-md-component="content">
              <article class="md-content__inner md-typeset">
                
                  



<div><h1 id="javascript-scripting">JavaScript Scripting</h1>
<h2 id="overview">Overview</h2>
<p>In addition to a scene's GLSL and JSON files, you can add an optional JavaScript scripting file. This script will be run on every frame before <code>main.glsl</code>, calculating variables on a frame-wide basis and passing them into the shader as uniforms.</p>
<p>Unlike GLSL, objects and data declared in the JavaScript persist across multiple frames, enabling useful functionality like timers and <a href="#object-oriented-programming">Object Oriented Programming</a>. The JavaScript engine is also equipped with a powerful <a href="#event-system">event system</a> and built-in functions to <a href="#updating-controls">update controls</a>, allowing complex control over your scene.</p>
<p>Check out this video tutorial to see JavaScript in action:</p>
<ul>
<li><a href="link:www.youtube.com/watch?v=Yr7GxKFLt6s&amp;ab_channel=SynesthesiaLive">v1.19 JavaScript Updates Walkthrough</a></li>
</ul>
<h2 id="update-and-setup-functions">Update and Setup Functions</h2>
<p>There are two main functions involved in a <code>script.js</code> file: the <code>setup()</code> function and the <code>update(dt)</code> function. They are both optional, but you must define at least one for anything to happen in the script.</p>
<p>The <code>setup()</code> function which will be run <em>once</em> when the scene loads. This is useful for initializing variables and registering <a href="#event-system">event handlers</a>. By registering event handlers in the setup function, you can completely forgo the update function.</p>
<p>The <code>update(dt)</code> function which will be run on every frame. The argument <code>dt</code> stores the time elapsed since the previous frame, which is useful for a variety of purposes (physics simulations, timers, consistent speeds, etc.).</p>
<h2 id="gettingsetting-uniforms">Getting/Setting Uniforms</h2>
<p>One of the primary functions of <code>script.js</code> is to take the current scene uniforms as input and create new uniforms as output. </p>
<h3 id="accessing-input-uniforms">Accessing Input Uniforms</h3>
<p>All of the scene's uniforms are available as global variables in the script, so you can access them like you would in the GLSL. This includes built-in <a href="standard_uniforms.html">standard GLSL uniforms</a>, <a href="audio_uniforms.html">audio reactive uniforms</a>, and any uniforms created by the <a href="json.html#controls">controls defined in <code>scene.json</code></a>. It <em>does not</em> include uniforms that apply to individual pixels and passes, like <code>_uvc</code>, <code>PASSINDEX</code>, and <code>RENDERSIZE</code>. Vector uniforms are available as objects with <code>xyzw</code> properties. </p>
<p>Here are some examples of these global variables:</p>
<ul>
<li><code>TIME</code> <em>(standard uniform)</em></li>
<li><code>syn_BassLevel</code> <em>(audio reactive uniform)</em></li>
<li><code>mySlider</code> <em>(control uniform)</em></li>
<li><code>myXy.y</code> <em>(access the components of a vector uniform)</em></li>
</ul>
<blockquote>
<p><strong>TIP:</strong> You can print out all the available global variables and functions to Synesthesia's console using the utility function <code>printGlobalKeys()</code></p>
</blockquote>
<h3 id="setting-output-uniforms">Setting Output Uniforms</h3>
<p>To set a uniform for the shader, use the <code>setUniform()</code> function. There are three ways to use this function: you can pass in up to four float values, pass in an array containing up to four values, or pass in an object containing <code>xyzw</code> or <code>rgba</code> properties.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">setUniform</span><span class="p">(</span><span class="nx">uniformName</span><span class="p">,</span><span class="w"> </span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="p">,</span><span class="w"> </span><span class="nx">z</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="p">);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="nx">uniformName</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="p">,</span><span class="w"> </span><span class="nx">z</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="p">]);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="nx">uniformName</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="p">,</span><span class="w"> </span><span class="nx">z</span><span class="p">,</span><span class="w"> </span><span class="nx">w</span><span class="w"> </span><span class="p">});</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="nx">uniformName</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">r</span><span class="p">,</span><span class="w"> </span><span class="nx">g</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="p">,</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="p">});</span>
</code></pre></div>

<p>This function will automatically create a uniform available in your shader called <code>uniformName</code>, determining the uniform type based on the amount of data you pass in.</p>
<p><strong>Examples</strong></p>
<div class="codehilite"><pre><span></span><code><span class="c1">// set a float uniform</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"size"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">);</span>
<span class="c1">// set a vec2 uniform</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"position"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">0.3</span><span class="p">);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"position"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">0.3</span><span class="p">]);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"position"</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">x</span><span class="o">:</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="o">:</span><span class="w"> </span><span class="mf">0.3</span><span class="w"> </span><span class="p">});</span>
<span class="c1">// set a vec3 uniform</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"color"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"color"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">]);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"color"</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">r</span><span class="o">:</span><span class="w"> </span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="nx">g</span><span class="o">:</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="o">:</span><span class="w"> </span><span class="mf">1.0</span><span class="w"> </span><span class="p">});</span>
<span class="c1">// set a vec4 uniform</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"colorWithAlpha"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"colorWithAlpha"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">]);</span>
<span class="nx">setUniform</span><span class="p">(</span><span class="s2">"colorWithAlpha"</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">r</span><span class="o">:</span><span class="w"> </span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="nx">g</span><span class="o">:</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="o">:</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="nx">a</span><span class="o">:</span><span class="w"> </span><span class="mf">1.0</span><span class="w"> </span><span class="p">});</span>
</code></pre></div>

<p>It is good practice to initialize all the output uniforms you'd like to use within the <code>setup()</code> function to ensure that they will always be defined in the shader.</p>
<h3 id="modifying-uniforms">Modifying Uniforms</h3>
<p>The most common usage of <code>script.js</code> is to modify Synesthesia's <a href="standard_uniforms.html">built-in uniforms</a> — especially the <a href="audio_uniforms.html">audio reactive</a> variety. To achieve a desired effect, sometimes these uniforms need to be larger, faster, squared, combined, inverted, etc.</p>
<p>For example, let's say you want to modify <code>syn_BassLevel</code> to be more reactive, so you square it. You want its effects to be more subtle, so you scale it by <code>0.5</code>. And you want it to turn on/off based on a toggle control you've created called <code>"move_with_bass"</code>. Here's what your code might look like: </p>
<div class="codehilite"><pre><span></span><code><span class="kd">function</span><span class="w"> </span><span class="nx">update</span><span class="p">(</span><span class="nx">dt</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">modified_BassLevel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0.5</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">pow</span><span class="p">(</span><span class="nx">syn_BassLevel</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">move_with_bass</span><span class="p">;</span>
<span class="w">  </span><span class="nx">setUniform</span><span class="p">(</span><span class="s2">"modified_BassLevel"</span><span class="p">,</span><span class="w"> </span><span class="nx">modified_BassLevel</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<p>For more examples of scenes that modify audio uniforms, check out <code>kaleidoWHOA, MAN</code>, <code>Meta Experiment 3</code>, <code>Circles5</code>, or <code>Hills, Eels</code>.</p>
<h3 id="deprecated-inputs-and-uniforms">DEPRECATED: <code>inputs</code> and <code>uniforms</code></h3>
<p>If you look at the <code>script.js</code> code for some scenes in Synesthesia, you'll notice that uniforms are accessed and set using two global objects called <code>inputs</code> and <code>uniforms</code>. You can access all input uniforms as properties of <code>inputs</code>, and you can set uniforms by adding a property to the <code>uniforms</code> object.</p>
<p>These global objects are still supported and available in the JavaScript, but they have been deprecated in favor of global input variables and the <code>setUniform</code> function.</p>
<h2 id="updating-controls">Updating Controls</h2>
<p>Using the following built-in JavaScript functions, you can update the controls of a scene.</p>
<h3 id="setcontrol"><code>setControl()</code></h3>
<p>Set the value of a control. You can include up to three values based on the dimension of the target control (include three to change colors, two to change xys, and one for anything else).</p>
<div class="codehilite"><pre><span></span><code><span class="nx">setControl</span><span class="p">(</span><span class="nx">controlName</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="nx">values</span><span class="p">],</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">options</span><span class="w"> </span><span class="p">})</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>controlName <code>string</code> - the name of the control (insensitive to case and spacing characters). To target a meta control, you can add <code>"meta/"</code> in front of the name, like <code>"meta/brightness"</code> (or use the <code>"bank"</code> option discussed below)</li>
<li>value <code>float array</code> - the new value of the control. Can be either a single float or an array of floats depending on the control type. These should be raw, scaled values — the same as the value the control will have within the shader. To set a control with normalized values, use the <code>setControlNormalized()</code> function</li>
<li>options <code>object</code> - an object that can customize the behavior of the control update, using the following keys:</li>
<li>dimension <code>int</code> - choose a single dimension of a multidimensional control to update</li>
<li>bank <code>string</code> - select which bank (scene or meta) to target in cases of overlap</li>
</ul>
<p><strong>Examples</strong></p>
<div class="codehilite"><pre><span></span><code><span class="c1">// pass in up to three values within an array</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"mySlider"</span><span class="p">,</span><span class="w"> </span><span class="mf">5.0</span><span class="p">);</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"myXyPad"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="mf">2.0</span><span class="p">]);</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"myColor"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">]);</span>

<span class="c1">// target a meta control using "meta/" or the "bank" option</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"meta/brightness"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">0.5</span><span class="p">);</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"brightness"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">bank</span><span class="o">:</span><span class="w"> </span><span class="s2">"meta"</span><span class="w"> </span><span class="p">});</span>

<span class="c1">// target specific dimensions using the "dimension" option</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"myXyPad"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">dimension</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="p">});</span>
<span class="nx">setControl</span><span class="p">(</span><span class="s2">"myColor"</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">dimension</span><span class="o">:</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="p">});</span>
</code></pre></div>

<h3 id="setcontrolnormalized"><code>setControlNormalized()</code></h3>
<p>Set a control using values normalized between <code>0</code> and <code>1</code>. This is helpful to update controls regardless of their range.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">setControlNormalized</span><span class="p">(</span><span class="nx">controlName</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="nx">values</span><span class="p">],</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">options</span><span class="w"> </span><span class="p">})</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>controlName <code>string</code> - the name of the control (insensitive to case and spacing characters). To target a meta control, you can add <code>"meta/"</code> in front of the name, like <code>"meta/brightness"</code> (or use the <code>"bank"</code> option discussed below)</li>
<li>values <code>float array</code> - the new values of the control. Can be either a single float or an array of floats depending on the control type. These values should be normalized between 0 and 1, and they will be scaled to the range of the control. To set a control with raw values, use the <code>setControl()</code> function</li>
<li>options <code>object</code> - an object that can customize the behavior of the control update, using the following keys:</li>
<li>dimension <code>int</code> - choose a single dimension of a multidimensional control to update</li>
<li>bank <code>string</code> - select which bank (scene or meta) to target in cases of overlap</li>
</ul>
<p><strong>Examples</strong></p>
<div class="codehilite"><pre><span></span><code><span class="c1">// pass in up to three values within an array</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"mySlider"</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">);</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"myXyPad"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">]);</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"myColor"</span><span class="p">,</span><span class="w"> </span><span class="p">[</span><span class="mf">0.1</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">]);</span>

<span class="c1">// target a meta control using "meta/" or the "bank" option</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"meta/brightness"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">);</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"brightness"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.5</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">bank</span><span class="o">:</span><span class="w"> </span><span class="s2">"meta"</span><span class="w"> </span><span class="p">});</span>

<span class="c1">// target specific dimensions using the "dimension" option</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"myXyPad"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">dimension</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="p">});</span>
<span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"myColor"</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">dimension</span><span class="o">:</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="p">});</span>
</code></pre></div>

<h3 id="randomizecontrol"><code>randomizeControl()</code></h3>
<p>Randomize the value of a control.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">randomizeControl</span><span class="p">(</span><span class="nx">controlName</span><span class="p">)</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>controlName <code>string</code> - the name of the control (insensitive to case and spacing characters). To target a meta control, you can add <code>"meta/"</code> in front of the name, like <code>"meta/brightness"</code></li>
</ul>
<h3 id="defaultcontrol"><code>defaultControl()</code></h3>
<p>Set a control to its default value.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">defaultControl</span><span class="p">(</span><span class="nx">controlName</span><span class="p">)</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>controlName <code>string</code> - the name of the control (insensitive to case and spacing characters). To target a meta control, you can add <code>"meta/"</code> in front of the name, like <code>"meta/brightness"</code></li>
</ul>
<h3 id="randomizegroup"><code>randomizeGroup()</code></h3>
<p>Randomize a group of controls.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">randomizeGroup</span><span class="p">(</span><span class="nx">groupName</span><span class="p">)</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>groupName <code>string</code> - the name of the control group to randomize (insensitive to case and spacing characters). To target a group of meta controls, you can add <code>"meta/"</code> in front of the name, like <code>"meta/color"</code></li>
</ul>
<h3 id="defaultgroup"><code>defaultGroup()</code></h3>
<p>Set a control to its default value.</p>
<div class="codehilite"><pre><span></span><code><span class="nx">defaultGroup</span><span class="p">(</span><span class="nx">groupName</span><span class="p">)</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>groupName <code>string</code> - the name of the control group to randomize (insensitive to case and spacing characters). To target a group of meta controls, you can add <code>"meta/"</code> in front of the name, like <code>"meta/color"</code></li>
</ul>
<h2 id="event-system">Event System</h2>
<p>Synesthesia's JavaScript engine includes an event system — by defining event handlers, you can run code conditionally based on the state of the script's input variables. </p>
<h3 id="registering-event-handlers">Registering Event Handlers</h3>
<p>There are five built-in functions you can use to register different types of event handlers. These functions should be called within the <code>setup()</code> function, since they only need to be registered once. Event handler registration functions all have the signature: </p>
<div class="codehilite"><pre><span></span><code><span class="nx">eventType</span><span class="p">(</span><span class="nx">target</span><span class="p">,</span><span class="w"> </span><span class="nx">callback</span><span class="p">)</span>
</code></pre></div>

<p><strong>Params</strong></p>
<ul>
<li>target <code>string</code> — the name of the input variable you'd like to track. You can use any of the script's <a href="#accessing-input-uniforms">global input uniforms</a> (the name of a slider, audio uniform, standard uniform, etc.). This argument is insensitive to case and spacing characters like <code>"_"</code> and <code>"-"</code>, so <code>"my_slider"</code>, <code>"MySlider"</code>, and <code>"m-Y-s-L-i-D-e-R"</code> would all work to track your slider</li>
<li>callback <code>string</code> — the name of the JavaScript callback function you'd like to call whenever the event occurs (must be an exact match) </li>
</ul>
<p>Whenever an event occurs and an event handler callback function is called, two arguments will be passed in:</p>
<ul>
<li><code>value</code> — the current value of the <code>target</code></li>
<li><code>previousValue</code> — the value of the <code>target</code> in the previous frame</li>
</ul>
<p>Here's a complete list of the event handler registration functions:</p>
<table>
<thead>
<tr>
<th>Function</th>
<th>Effect</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>onChange(target, callback)</code></td>
<td><code>callback</code> will be called whenever <code>target</code> changes value</td>
</tr>
<tr>
<td><code>onOffToOn(target, callback)</code></td>
<td><code>callback</code> will be called whenever <code>target</code> changes from less than 0.5 to greater than 0.5</td>
</tr>
<tr>
<td><code>onOnToOff(target, callback)</code></td>
<td><code>callback</code> will be called whenever <code>target</code> changes from greater than 0.5 to less than 0.5</td>
</tr>
<tr>
<td><code>whileOn(target, callback)</code></td>
<td><code>callback</code> will be called on every frame that <code>target</code> is greater than 0.5</td>
</tr>
<tr>
<td><code>whileOff(target, callback)</code></td>
<td><code>callback</code> will be called on every frame that <code>target</code> is less than 0.5</td>
</tr>
</tbody>
</table>
<h3 id="examples">Examples</h3>
<p>Here are some examples of how the event system could be used, incorporating the built-in JavaScript functions to <a href="#updating-controls">update controls</a>:</p>
<div class="codehilite"><pre><span></span><code><span class="c1">// the following functions before setup() are all custom event handlers</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onMacroChange</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param1"</span><span class="p">,</span><span class="w"> </span><span class="nx">value</span><span class="p">);</span>
<span class="w">  </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param2"</span><span class="p">,</span><span class="w"> </span><span class="nx">value</span><span class="p">);</span>
<span class="w">  </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param3"</span><span class="p">,</span><span class="w"> </span><span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onPresetChange</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="c1">// trigger one of three presets based on the dropdown index</span>
<span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">dropdownIndex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">value</span><span class="p">;</span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">dropdownIndex</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param1"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">1.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param2"</span><span class="p">,</span><span class="w"> </span><span class="mf">10.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param3"</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">5.1</span><span class="p">);</span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">dropdownIndex</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param1"</span><span class="p">,</span><span class="w"> </span><span class="mf">2.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param2"</span><span class="p">,</span><span class="w"> </span><span class="mf">20.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param3"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">);</span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">dropdownIndex</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param1"</span><span class="p">,</span><span class="w"> </span><span class="mf">0.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param2"</span><span class="p">,</span><span class="w"> </span><span class="mf">15.0</span><span class="p">);</span>
<span class="w">    </span><span class="nx">setControl</span><span class="p">(</span><span class="s2">"param3"</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">);</span>
<span class="w">  </span><span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onLoudBass</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">value</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0.9</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nx">randomizeControl</span><span class="p">(</span><span class="s2">"meta/hue"</span><span class="p">);</span>
<span class="w">  </span><span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onChangeSeed</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">randomSeed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">100</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onRandomizeColors</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">randomizeGroup</span><span class="p">(</span><span class="s2">"colors"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">onDefaultColors</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">defaultGroup</span><span class="p">(</span><span class="s2">"colors"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">whileBrightnessLFO</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">setControlNormalized</span><span class="p">(</span><span class="s2">"meta/brightness"</span><span class="p">,</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">sin</span><span class="p">(</span><span class="nx">TIME</span><span class="o">*</span><span class="mf">2</span><span class="p">)</span><span class="o">*</span><span class="mf">0.5</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">0.5</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">defaultBrightness</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">defaultControl</span><span class="p">(</span><span class="s2">"meta/brightness"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">whileDebug</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">previousValue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="nx">print</span><span class="p">(</span><span class="s2">"random seed: "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">randomSeed</span><span class="p">);</span>
<span class="w">  </span><span class="nx">print</span><span class="p">(</span><span class="s2">"bass level: "</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">syn_BassLevel</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">var</span><span class="w"> </span><span class="nx">randomSeed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">setup</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="c1">// create a "macro" slider that sets the value of multiple other controls</span>
<span class="w">  </span><span class="nx">onChange</span><span class="p">(</span><span class="s2">"macro"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onMacroChange"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// trigger a hard-coded preset based on the value of a dropdown</span>
<span class="w">  </span><span class="nx">onChange</span><span class="p">(</span><span class="s2">"preset_dropdown"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onPresetChange"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// randomize the "hue" meta control whenever the bass gets loud</span>
<span class="w">  </span><span class="nx">onChange</span><span class="p">(</span><span class="s2">"syn_BassLevel"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onLoudBass"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// update a JavaScript seed variable whenever a button is pressed</span>
<span class="w">  </span><span class="nx">onOffToOn</span><span class="p">(</span><span class="s2">"change_seed"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onChangeSeed"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// randomize a group of controls when a button called 'randomize_colors' is pressed</span>
<span class="w">  </span><span class="nx">onOffToOn</span><span class="p">(</span><span class="s2">"randomize_colors"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onRandomizeColors"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// set those controls back to default when a different button is pressed</span>
<span class="w">  </span><span class="nx">onOffToOn</span><span class="p">(</span><span class="s2">"default_colors"</span><span class="p">,</span><span class="w"> </span><span class="s2">"onDefaultColors"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// use an LFO to control the "brightness" meta control when a toggle is on</span>
<span class="w">  </span><span class="nx">whileOn</span><span class="p">(</span><span class="s2">"brightness_LFO"</span><span class="p">,</span><span class="w"> </span><span class="s2">"whileBrightnessLFO"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// return brightness to its default value when the LFO toggle is turned off</span>
<span class="w">  </span><span class="nx">onOnToOff</span><span class="p">(</span><span class="s2">"brightness_LFO"</span><span class="p">,</span><span class="w"> </span><span class="s2">"defaultBrightness"</span><span class="p">);</span>
<span class="w">  </span><span class="c1">// print debug information whenever debug toggle is on</span>
<span class="w">  </span><span class="nx">whileOn</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">,</span><span class="w"> </span><span class="s2">"whileDebug"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<h2 id="object-oriented-programming">Object Oriented Programming</h2>
<p>Other use cases of <code>script.js</code> involve <a href="link:developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object Oriented Programming</a> (OOP), which allows complex functionality that would be otherwise impossible (or at least impractical) with shaders. Generally, this involves creating a custom class, constructing an instance, updating it each frame, and sending its properties into the shader as uniforms. An instance declared above <code>update()</code> will remain available until the scene stops, which allows you to create cohesive behavior over time.</p>
<p>Here are some examples of the custom classes that have been used in Synesthesia's built-in scenes:</p>
<ul>
<li>camera movement (<code>Molten</code>, <code>Alien Cavern</code>, <code>Deeper</code>)</li>
<li>BPM counter (<code>Alien Cavern</code>, <code>Deeper</code>, <code>Hex Array</code>, etc.)</li>
<li>smooth counter (<code>Hue Review</code>, <code>KIFS Flythrough</code>, <code>Lattix</code>, etc.)</li>
<li>timer (<code>Circles5</code>, <code>Circuit Bending</code>, <code>Voronoi Geode</code>, etc.)</li>
<li>physics simulation (<code>Biopsy</code>)</li>
<li>introducing randomness (<code>Stained Glass</code>, <code>Thresholder</code>)</li>
</ul>
<h2 id="reading-pixel-data">Reading Pixel Data</h2>
<h3 id="texturefinalpassxy"><code>textureFinalPass(x,y)</code></h3>
<p>Sample the output color of the final pass at normalized (0 to 1) x, y coordinates and return an array of RGB values.</p>
<p><strong>Params</strong></p>
<ul>
<li>x <code>float</code> - x coordinate of sample pixel, normalized between 0 and 1</li>
<li>y <code>float</code> - y coordinate of sample pixel, normalized between 0 and 1</li>
</ul>
<p><strong>Returns</strong>: <code>float array</code> - an array of three values for <code>r</code>, <code>g</code> and <code>b</code>, normalized between 0 and 1  </p>
<h3 id="example">Example</h3>
<p>Enable color picking from the visualizer by passing in the mouse coordinates and returning the pixel values directly to the setControl function like so:</p>
<div class="codehilite"><pre><span></span><code><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">_click</span><span class="p">.</span><span class="nx">x</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0.5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">pixelColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">textureFinalPass</span><span class="p">(</span><span class="nx">_muv</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">_muv</span><span class="p">.</span><span class="nx">y</span><span class="p">);</span>
<span class="w">  </span><span class="nx">setControl</span><span class="p">(</span><span class="s1">'my_color'</span><span class="p">,</span><span class="w"> </span><span class="nx">pixelColor</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<h2 id="printing-to-the-console">Printing to the Console</h2>
<p>You can use <code>print()</code> or <code>console.log()</code> to print to Synesthesia's built-in developer console. This can be useful for debugging shaders, since you can display uniform values.</p>
<p>Here's a trick used to only print values on a periodic basis:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">var</span><span class="w"> </span><span class="nx">frameCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
<span class="kd">var</span><span class="w"> </span><span class="nx">printPeriod</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">50</span><span class="p">;</span>

<span class="kd">function</span><span class="w"> </span><span class="nx">update</span><span class="p">(</span><span class="nx">dt</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">frameCount</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">printPeriod</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0</span><span class="p">){</span>
<span class="w">    </span><span class="nx">print</span><span class="p">(</span><span class="s2">"suh dude"</span><span class="p">);</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">frameCount</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>












                
              </article>
            </div>
          
          
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="link:squidfunk.github.io/mkdocs-material" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    
    
    
      
      <script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
    
    
      <script src="../assets/javascripts/bundle.92b07e13.min.js"></script>
      
    
  </body>
</html>