{
  "schemaVersion": "1.0",
  "item": {
    "slug": "flstudio-scripting",
    "name": "FL Studio Scripting",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/delorenj/flstudio-scripting",
    "canonicalUrl": "https://clawhub.ai/delorenj/flstudio-scripting",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/flstudio-scripting",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=flstudio-scripting",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/api-arrangement-patterns.md",
      "references/api-callbacks.md",
      "references/api-channels.md",
      "references/api-device.md",
      "references/api-mixer.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/flstudio-scripting"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/flstudio-scripting",
    "agentPageUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent",
    "manifestUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "FL Studio Python Scripting",
        "body": "Complete reference for FL Studio's Python API: MIDI controller scripting (14 modules, 427+ functions), piano roll note manipulation, Edison audio editing, and FLP file parsing with PyFLP."
      },
      {
        "title": "Requirements",
        "body": "FL Studio 20.8.4+, Python 3.6+"
      },
      {
        "title": "Check API Version",
        "body": "import general\nprint(f\"API Version: {general.getVersion()}\")"
      },
      {
        "title": "Script Installation",
        "body": "Place scripts in Shared\\Python\\User Scripts folder."
      },
      {
        "title": "1. MIDI Controller Scripting",
        "body": "Purpose: Control FL Studio through hardware MIDI controllers and send feedback to devices.\nRuns: Continuously while FL Studio is open.\nAvailable modules: transport, mixer, channels, arrangement, patterns, playlist, device, ui, general, plugins, screen, launchMapPages, utils, callbacks\n\nEntry points:\n\ndef OnInit():\n    \"\"\"Called when script starts.\"\"\"\n    pass\n\ndef OnDeInit():\n    \"\"\"Called when script stops.\"\"\"\n    pass\n\ndef OnMidiMsg(msg):\n    \"\"\"Called for incoming MIDI messages.\"\"\"\n    pass\n\ndef OnControlChange(msg):\n    \"\"\"Called for CC messages.\"\"\"\n    pass\n\ndef OnNoteOn(msg):\n    \"\"\"Called for note-on messages.\"\"\"\n    pass\n\ndef OnRefresh(flags):\n    \"\"\"Called when FL Studio state changes.\"\"\"\n    pass"
      },
      {
        "title": "2. Piano Roll Scripting",
        "body": "Purpose: Manipulate notes and markers in the piano roll editor.\nRuns: Once when user invokes through Scripts menu.\nAvailable modules: flpianoroll, enveditor\n\nimport flpianoroll\nscore = flpianoroll.score\nfor note in score.notes:\n    note.velocity = 0.8  # Set all velocities to 80%"
      },
      {
        "title": "3. Edison Audio Scripting",
        "body": "Purpose: Edit and process audio samples in Edison.\nRuns: Once within Edison's context.\nAvailable modules: enveditor"
      },
      {
        "title": "API Module Reference Map",
        "body": "Navigate to the appropriate reference file based on what you need to control.\nRead these files ONLY when you need specific API signatures."
      },
      {
        "title": "Core Workflow Modules",
        "body": "ModuleFunctionsWhat It ControlsReferencetransport20Play, stop, record, position, tempo, loopingapi-transport.mdmixer69Track volume/pan/mute/solo, EQ, routing, effectsapi-mixer.mdchannels48Channel rack, grid bits, step sequencer, notesapi-channels.md"
      },
      {
        "title": "Arrangement Modules",
        "body": "ModuleFunctionsWhat It ControlsReferencearrangement + patterns9 + 25Markers, time, pattern control, groupsapi-arrangement-patterns.mdplaylist41Playlist tracks, live mode, performance, blocksapi-playlist.md"
      },
      {
        "title": "Device & Communication",
        "body": "ModuleFunctionsWhat It ControlsReferencedevice34MIDI I/O, sysex, dispatch, hardware refreshapi-device.md"
      },
      {
        "title": "UI & Application Control",
        "body": "ModuleFunctionsWhat It ControlsReferenceui + general71 + 24Windows, navigation, undo/redo, version, snapapi-ui-general.md"
      },
      {
        "title": "Plugins",
        "body": "ModuleFunctionsWhat It ControlsReferenceplugins13Plugin parameters, presets, names, colorsapi-plugins.md"
      },
      {
        "title": "Specialized Hardware Display",
        "body": "ModuleFunctionsWhat It ControlsReferencescreen + launchMapPages9 + 12AKAI Fire screen, launchpad page managementapi-screen-launchmap.md"
      },
      {
        "title": "Utilities, Constants & MIDI Reference",
        "body": "ModuleFunctionsWhat It ControlsReferenceutils + constants21Color conversion, math, note names, MIDI tablesapi-utils-constants.md"
      },
      {
        "title": "Callbacks & FlMidiMsg",
        "body": "ModuleFunctionsWhat It ControlsReferencecallbacks26All callback functions, FlMidiMsg class, event flowapi-callbacks.md"
      },
      {
        "title": "Piano Roll & Edison",
        "body": "Note, Marker, ScriptDialog, score classes for piano roll manipulation plus Edison enveditor utilities.\nSee piano-roll-edison.md"
      },
      {
        "title": "FLP File Parsing (PyFLP)",
        "body": "External library for reading/writing .flp project files without FL Studio running. Batch processing, analysis, automated generation.\nSee pyflp.md"
      },
      {
        "title": "Minimal MIDI Controller Skeleton",
        "body": "# name=My Controller\n# url=https://example.com\n\nimport device\nimport mixer\nimport transport\n\ndef OnInit():\n    if device.isAssigned():\n        print(f\"Connected: {device.getName()}\")\n\ndef OnDeInit():\n    print(\"Script shut down\")\n\ndef OnControlChange(msg):\n    if msg.data1 == 7:  # Volume CC\n        mixer.setTrackVolume(mixer.trackNumber(), msg.data2 / 127.0)\n        msg.handled = True\n\ndef OnNoteOn(msg):\n    track = msg.data1 % 8\n    mixer.setActiveTrack(track)\n    msg.handled = True\n\ndef OnRefresh(flags):\n    pass  # Update hardware display here"
      },
      {
        "title": "Key Pattern: Always Check Device Assignment",
        "body": "def OnInit():\n    if not device.isAssigned():\n        print(\"No output device linked!\")\n        return\n    # Safe to use device.midiOutMsg() etc."
      },
      {
        "title": "Key Pattern: Mark Events as Handled",
        "body": "def OnControlChange(msg):\n    if msg.data1 == 7:\n        mixer.setTrackVolume(0, msg.data2 / 127.0)\n        msg.handled = True  # Prevent FL Studio from also processing this"
      },
      {
        "title": "Key Pattern: Send Feedback to Hardware",
        "body": "def OnRefresh(flags):\n    if device.isAssigned():\n        # Update volume fader LED\n        vol = int(mixer.getTrackVolume(0) * 127)\n        device.midiOutMsg(0xB0, 0, 7, vol)\n\nFor complete examples (MIDI learn, scale enforcer, LED feedback, batch quantization, sysex handling, performance monitoring, automation engine, debugging):\nSee examples-patterns.md"
      },
      {
        "title": "Performance",
        "body": "Cache module references at top level (import once)\nAvoid tight loops in MIDI callbacks (keep under 10ms)\nBatch UI updates; use device.directFeedback() for controller echo"
      },
      {
        "title": "Hardware Integration",
        "body": "Always check device.isAssigned() before device functions\nImplement two-way sync for all controls (send feedback on state change)\nTest on real hardware (virtual ports behave differently)"
      },
      {
        "title": "Code Organization",
        "body": "Separate MIDI mapping from business logic (use a controller class)\nKeep callbacks responsive; offload complex work\nHandle edge cases: invalid indices, missing devices, out-of-range values"
      },
      {
        "title": "Script Not Receiving MIDI",
        "body": "Check device.isAssigned() returns True\nVerify MIDI input port in FL Studio MIDI Settings\nEnsure callback functions are defined at module level (not nested)\nCheck MIDI message status bytes match expected values"
      },
      {
        "title": "Piano Roll Script Not Working",
        "body": "Verify script is in Shared\\Python\\User Scripts folder\nEnsure a pattern is open in piano roll before running\nAccess notes via flpianoroll.score.notes"
      },
      {
        "title": "Performance Issues",
        "body": "Avoid complex calculations inside OnIdle() (called every ~20ms)\nDon't repeatedly query values that haven't changed\nUse device.setHasMeters() only if peak meters are needed"
      },
      {
        "title": "FAQ",
        "body": "Double-click detection: Use device.isDoubleClick(index)\nInter-script communication: Use device.dispatch(ctrlIndex, message)\nLED control: device.midiOutMsg(0x90, 0, note, velocity) for note-on LEDs\nprocessMIDICC vs OnControlChange: Use On* callbacks for modern code\nGUI access: Limited through ui module; full UI automation not available\nMultiple devices: Check device.getName() to identify, handle per-port"
      },
      {
        "title": "Resources",
        "body": "Official FL Studio API: https://www.image-line.com/fl-studio/modules/python-scripting/\nPyFLP GitHub: https://github.com/demberto/PyFLP\nAPI Functions: 427+ across 14 modules | Last Updated: 2025"
      }
    ],
    "body": "FL Studio Python Scripting\n\nComplete reference for FL Studio's Python API: MIDI controller scripting (14 modules, 427+ functions), piano roll note manipulation, Edison audio editing, and FLP file parsing with PyFLP.\n\nQuick Start\nRequirements\nFL Studio 20.8.4+, Python 3.6+\nCheck API Version\nimport general\nprint(f\"API Version: {general.getVersion()}\")\n\nScript Installation\n\nPlace scripts in Shared\\Python\\User Scripts folder.\n\nThree Scripting Contexts\n1. MIDI Controller Scripting\n\nPurpose: Control FL Studio through hardware MIDI controllers and send feedback to devices. Runs: Continuously while FL Studio is open. Available modules: transport, mixer, channels, arrangement, patterns, playlist, device, ui, general, plugins, screen, launchMapPages, utils, callbacks\n\nEntry points:\n\ndef OnInit():\n    \"\"\"Called when script starts.\"\"\"\n    pass\n\ndef OnDeInit():\n    \"\"\"Called when script stops.\"\"\"\n    pass\n\ndef OnMidiMsg(msg):\n    \"\"\"Called for incoming MIDI messages.\"\"\"\n    pass\n\ndef OnControlChange(msg):\n    \"\"\"Called for CC messages.\"\"\"\n    pass\n\ndef OnNoteOn(msg):\n    \"\"\"Called for note-on messages.\"\"\"\n    pass\n\ndef OnRefresh(flags):\n    \"\"\"Called when FL Studio state changes.\"\"\"\n    pass\n\n2. Piano Roll Scripting\n\nPurpose: Manipulate notes and markers in the piano roll editor. Runs: Once when user invokes through Scripts menu. Available modules: flpianoroll, enveditor\n\nimport flpianoroll\nscore = flpianoroll.score\nfor note in score.notes:\n    note.velocity = 0.8  # Set all velocities to 80%\n\n3. Edison Audio Scripting\n\nPurpose: Edit and process audio samples in Edison. Runs: Once within Edison's context. Available modules: enveditor\n\nAPI Module Reference Map\n\nNavigate to the appropriate reference file based on what you need to control. Read these files ONLY when you need specific API signatures.\n\nCore Workflow Modules\nModule\tFunctions\tWhat It Controls\tReference\ntransport\t20\tPlay, stop, record, position, tempo, looping\tapi-transport.md\nmixer\t69\tTrack volume/pan/mute/solo, EQ, routing, effects\tapi-mixer.md\nchannels\t48\tChannel rack, grid bits, step sequencer, notes\tapi-channels.md\nArrangement Modules\nModule\tFunctions\tWhat It Controls\tReference\narrangement + patterns\t9 + 25\tMarkers, time, pattern control, groups\tapi-arrangement-patterns.md\nplaylist\t41\tPlaylist tracks, live mode, performance, blocks\tapi-playlist.md\nDevice & Communication\nModule\tFunctions\tWhat It Controls\tReference\ndevice\t34\tMIDI I/O, sysex, dispatch, hardware refresh\tapi-device.md\nUI & Application Control\nModule\tFunctions\tWhat It Controls\tReference\nui + general\t71 + 24\tWindows, navigation, undo/redo, version, snap\tapi-ui-general.md\nPlugins\nModule\tFunctions\tWhat It Controls\tReference\nplugins\t13\tPlugin parameters, presets, names, colors\tapi-plugins.md\nSpecialized Hardware Display\nModule\tFunctions\tWhat It Controls\tReference\nscreen + launchMapPages\t9 + 12\tAKAI Fire screen, launchpad page management\tapi-screen-launchmap.md\nUtilities, Constants & MIDI Reference\nModule\tFunctions\tWhat It Controls\tReference\nutils + constants\t21\tColor conversion, math, note names, MIDI tables\tapi-utils-constants.md\nCallbacks & FlMidiMsg\nModule\tFunctions\tWhat It Controls\tReference\ncallbacks\t26\tAll callback functions, FlMidiMsg class, event flow\tapi-callbacks.md\nNon-MIDI Scripting APIs\nPiano Roll & Edison\n\nNote, Marker, ScriptDialog, score classes for piano roll manipulation plus Edison enveditor utilities. See piano-roll-edison.md\n\nFLP File Parsing (PyFLP)\n\nExternal library for reading/writing .flp project files without FL Studio running. Batch processing, analysis, automated generation. See pyflp.md\n\nCommon Patterns\nMinimal MIDI Controller Skeleton\n# name=My Controller\n# url=https://example.com\n\nimport device\nimport mixer\nimport transport\n\ndef OnInit():\n    if device.isAssigned():\n        print(f\"Connected: {device.getName()}\")\n\ndef OnDeInit():\n    print(\"Script shut down\")\n\ndef OnControlChange(msg):\n    if msg.data1 == 7:  # Volume CC\n        mixer.setTrackVolume(mixer.trackNumber(), msg.data2 / 127.0)\n        msg.handled = True\n\ndef OnNoteOn(msg):\n    track = msg.data1 % 8\n    mixer.setActiveTrack(track)\n    msg.handled = True\n\ndef OnRefresh(flags):\n    pass  # Update hardware display here\n\nKey Pattern: Always Check Device Assignment\ndef OnInit():\n    if not device.isAssigned():\n        print(\"No output device linked!\")\n        return\n    # Safe to use device.midiOutMsg() etc.\n\nKey Pattern: Mark Events as Handled\ndef OnControlChange(msg):\n    if msg.data1 == 7:\n        mixer.setTrackVolume(0, msg.data2 / 127.0)\n        msg.handled = True  # Prevent FL Studio from also processing this\n\nKey Pattern: Send Feedback to Hardware\ndef OnRefresh(flags):\n    if device.isAssigned():\n        # Update volume fader LED\n        vol = int(mixer.getTrackVolume(0) * 127)\n        device.midiOutMsg(0xB0, 0, 7, vol)\n\n\nFor complete examples (MIDI learn, scale enforcer, LED feedback, batch quantization, sysex handling, performance monitoring, automation engine, debugging): See examples-patterns.md\n\nBest Practices\nPerformance\nCache module references at top level (import once)\nAvoid tight loops in MIDI callbacks (keep under 10ms)\nBatch UI updates; use device.directFeedback() for controller echo\nHardware Integration\nAlways check device.isAssigned() before device functions\nImplement two-way sync for all controls (send feedback on state change)\nTest on real hardware (virtual ports behave differently)\nCode Organization\nSeparate MIDI mapping from business logic (use a controller class)\nKeep callbacks responsive; offload complex work\nHandle edge cases: invalid indices, missing devices, out-of-range values\nTroubleshooting\nScript Not Receiving MIDI\nCheck device.isAssigned() returns True\nVerify MIDI input port in FL Studio MIDI Settings\nEnsure callback functions are defined at module level (not nested)\nCheck MIDI message status bytes match expected values\nPiano Roll Script Not Working\nVerify script is in Shared\\Python\\User Scripts folder\nEnsure a pattern is open in piano roll before running\nAccess notes via flpianoroll.score.notes\nPerformance Issues\nAvoid complex calculations inside OnIdle() (called every ~20ms)\nDon't repeatedly query values that haven't changed\nUse device.setHasMeters() only if peak meters are needed\nFAQ\nDouble-click detection: Use device.isDoubleClick(index)\nInter-script communication: Use device.dispatch(ctrlIndex, message)\nLED control: device.midiOutMsg(0x90, 0, note, velocity) for note-on LEDs\nprocessMIDICC vs OnControlChange: Use On* callbacks for modern code\nGUI access: Limited through ui module; full UI automation not available\nMultiple devices: Check device.getName() to identify, handle per-port\nResources\nOfficial FL Studio API: https://www.image-line.com/fl-studio/modules/python-scripting/\nPyFLP GitHub: https://github.com/demberto/PyFLP\nAPI Functions: 427+ across 14 modules | Last Updated: 2025"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/delorenj/flstudio-scripting",
    "publisherUrl": "https://clawhub.ai/delorenj/flstudio-scripting",
    "owner": "delorenj",
    "version": "0.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/flstudio-scripting",
    "downloadUrl": "https://openagent3.xyz/downloads/flstudio-scripting",
    "agentUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent",
    "manifestUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/flstudio-scripting/agent.md"
  }
}