cables DocumentationHow To UseWorking with filesKeyboard ShortcutsUser Interface WalkthroughBeginner TutorialBeginner 1: Drawing A CircleBeginner 2: TransformationsBeginner 3: ColorMore TransformationsIntermediateImage CompositionsPost-Processing 3D ScenesCommunicationcables APIExporting And EmbeddingHow to serve files externally and fix CORS headersExporting PatchesExport using the cables command line interfaceExport via IframeExport creating a standalone executableExport to github (pages)Export and deploy to netlifyExport for Cables Standalone VersionExport a ZIP fileExternal triggers / functionsUsing variablesPreviewing / uploading exported cables patchesExamples for EmbeddingPermissionsUsersPatchesTeamsOpsMultiplayerPatchlistsCoding OpsCreating AttachmentsGeneral op/Port CallbacksPortsDynamic PortsArray PortsBoolean portsInteger Number PortsObject PortsString portsTrigger PortsFloating Point Number PortsGUI/UI attributesHello Op - Part 1LibrariesDeveloping OpsRenaming / Creating a new versionCreating Viz OpsGuidelinesObject PortsPatching Ops / SubPatchOpsWriting ShadersWeb Audio Op DevelopmentHTML And CSS In CablesLightingLightsShadowsWorking With AudioBasic Audio SetupWorking with EffectsReal-Time Audio Analyzation & Audio VisualizationOffline Audio Visualization & AnalyzationOptimizing Performance In PatchesTools for debugging your patchHow to optimize cables patches with the Performance opHow to optimize cables patches with the ProfilerCommon pitfalls with the "usual suspects"Optimizing arraysDebugging Shaders with ShaderInfoFAQAudio in web browsersHow to make demoscene demos with cables.glEmbeddingHow to integrate my cables patch into my CMS (webflow/wix/squarespace/...)?How to remove grey rectangles on touch (mobile)?Why doesn't the DownloadTexture op work on iOS?How to disable page scrolling on mobile?Mobile tippsHow to run exported patches on your local machineTransparent CanvasFeatures and SupportHow to contribute code to cablesWill there be support for (animated) GIFs?Can i use a website as a texture?Screenshots and Video recordingHow to report a bug in cablesHow can I share a patch to get help?How can I support cables?Video playback in cablesGeneral questionsWhat is dev.cables.glJavascript Frameworkscordova / phonegapelectronreactvuejsLicenses and paymentWhat license do i need to use cables?Will I have to pay for it in the future?How is my work licensed when using cables?Does cables support midi and OSC?Patch PermissionsMy User Profile & Social MediaShadertoyCables at schools and universitiesTechnical questionsWebGL1 and WebGL2undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined


This is a set of rules that will help you to develop ops inside of cables.

All example files for new ops should be made public else they're not available to all users

Every op that draws/renders a mesh should have a geometry ouput

Every material op should output a shader

Every op that draws something should have a checkbox called "Render". Disabling this stops the shape appearing on screen.

Naming standards

ANY op with the name VALUE should be renamed to Number

ANY op with the name Boolean should become Bool

ANY op with the name Animation should become Anim

ANY op with the name Variable should become Var

ANY op related to a physicsbody gets the prefix body

ANY op which reports the info about a dataType should start with the word Info

Data conversion

If a data type is converted to another then both data names should be in the op name like ArrayToString or NumberToBool


Any op with a trigger in should have this as the first input port, it should also have a trigger out as well.

This avoids having to use too many sequence ops.
If an op has a finished trigger when an action has been completed then this trigger port should always be to the right of the trigger out port.

Anim ops

Should have a boolean finished output port to show if the state is running or not.

Array ops

All array ops should output null if no array is connected or being processed.

Use inValueInt to look up the index of the array.

All arrays should make a copy of an array and not a reference.

let arrIn;
let myArray;
// This line below is a reference.This will modify the array in the op before this one.
//Better to avoid doing this
myArray = arrIn ;
//It's better to make a deep copy like this
for(let i = 0 ; i < arrIn; i++)
  myArray[i] = arrIn[i];

Mesh ops

All ops that work with 3D meshes should adhere to the following rules, to guarantee best integration with other ops.

  • If render input is NOT connected geometry output is always NULL
  • On creation of the op, geometry output is NULL
  • Toggle for rendering should be called "Render Mesh"
  • Next output trigger should be called "next"
  • Optimize meshes to not always rebuild the whole geometry (e.g. scaling of rectangle)
  • Add a checkbox "force update" to disable and change the mesh again


Every op has two short name, e.g. KeyboardInput and a namespace, e.g. Ops.Devices.Keyboard.KeyboardInput.

The name will be presented to the user in the patch-view, the long version exists to group similar ops together.

In the op-add-dialog (when pressing ESC in the patch-view) users can click on any part of the namespace to view all ops with that namespace.

Op names cannot start with a number.

Naming Conventions

All namespace-segments as well as the op name must be written in upper camel case, e.g. KeyboardInput, not keyboard_input or keyboardInput.

If your op uses an abbreviation, e.g. MIDI only the first character should be capitalized, so if you made a MIDI-input, a good name would be MidiInput.

Please note: Op-namespaces can not contain the full namespace of another op, e.g. if an op Ops.Devices.Keyboard exists, you cannot put your newly created op in the namespace Ops.Devices.Keyboard.KeyboardInput.

Found a problem? Edit this file on github and contribute to cables!