RCT Help Documentation
Home
  • Getting Started
  • Script Metadata
  • Custom UI
  • Core API
  • Chart Class
  • Data Classes
  • Examples
  • Best Practices
Plugin Store
  • 简体中文
  • English
Home
  • Getting Started
  • Script Metadata
  • Custom UI
  • Core API
  • Chart Class
  • Data Classes
  • Examples
  • Best Practices
Plugin Store
  • 简体中文
  • English
  • API Reference

    • Home
    • Getting Started
    • Script Metadata
    • Custom UI Dialog
    • Core API
    • Chart Class
    • Data Classes
    • Example Scripts
    • Best Practices

Example Scripts

This page provides multiple complete example scripts demonstrating various uses of the RCT API.

Table of Contents

  • Example Scripts
    • Table of Contents
    • Example 1: Note Statistics
    • Example 2: Note Time Shifting
    • Example 3: Delete Specific Note Types
    • Example 4: Generate Notes by Beats
    • Example 5: Analyze Note Beat Information
    • More Examples
      • Filter Notes by Time Range
      • Keep Only Specific Note Types

Example 1: Note Statistics

Count and display the number of notes by type.

# Description: Count and display the number of notes by type

from rct_api import get_current_chart, Note

def main():
    chart = get_current_chart()
    if not chart:
        print("Error: Unable to get chart")
        return
    
    counts = chart.get_note_count_by_type()
    
    type_names = {
        Note.TAP: "Tap",
        Note.FLICK: "Flick",
        Note.SLIDE: "Slide",
        Note.ROTATE: "Rotate",
        Note.CATCH: "Catch",
        Note.BOMB: "Bomb",
        Note.TRAIL: "Trail"
    }
    
    print("=== Note Statistics ===")
    total = 0
    for note_type, count in counts.items():
        name = type_names.get(note_type, f"Unknown({note_type})")
        print(f"{name}: {count}")
        total += count
    print(f"Total: {total}")

if __name__ == "__main__":
    main()

Features:

  • Get the current chart
  • Count notes by type
  • Display detailed statistics

Example 2: Note Time Shifting

Shift all note times by a specified number of milliseconds.

# Description: Shift all note times by a specified number of milliseconds
# Args: Offset(ms) - positive to delay, negative to advance

import sys
from rct_api import get_current_chart, save_current_chart

def main():
    if len(sys.argv) < 2:
        print("Error: Please provide an offset parameter")
        return
    
    try:
        offset = float(sys.argv[1])
    except ValueError:
        print("Error: Offset must be a number")
        return
    
    chart = get_current_chart()
    if not chart:
        print("Error: Unable to get chart")
        return
    
    # Shift time
    chart.shift_time(offset)
    
    # Save
    save_current_chart(chart)
    print(f"Success: All note times shifted by {offset}ms")

if __name__ == "__main__":
    main()

Features:

  • Accept offset parameter
  • Shift time of all notes, BPMs, and speeds
  • Save modified chart

Example 3: Delete Specific Note Types

Delete specified note types using custom UI.

# Description: Delete specified note types
# UI: {"fields":[{"name":"note_types","field_type":"select","label":"Note types to delete:","default_value":"bomb","options":["tap","flick","slide","rotate","catch","bomb","trail"]}]}

import sys
import json
from rct_api import get_current_chart, save_current_chart, Note

def main():
    if len(sys.argv) < 2:
        print("Error: No parameters provided")
        return
    
    try:
        params = json.loads(sys.argv[1])
        note_type_str = params.get('note_types', 'bomb')
        
        # Map types
        type_map = {
            'tap': Note.TAP,
            'flick': Note.FLICK,
            'slide': Note.SLIDE,
            'rotate': Note.ROTATE,
            'catch': Note.CATCH,
            'bomb': Note.BOMB,
            'trail': Note.TRAIL
        }
        
        if note_type_str not in type_map:
            print(f"Error: Unknown note type '{note_type_str}'")
            return
        
        target_type = type_map[note_type_str]
        
        # Get chart
        chart = get_current_chart()
        if not chart:
            print("Error: Unable to get chart")
            return
        
        # Delete specified type
        original_count = len(chart.notes)
        chart.notes = [note for note in chart.notes if note.type != target_type]
        deleted_count = original_count - len(chart.notes)
        
        # Save
        save_current_chart(chart)
        print(f"Success: Deleted {deleted_count} {note_type_str} notes")
        
    except json.JSONDecodeError as e:
        print(f"Error: Unable to parse parameters - {e}")
    except Exception as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()

Features:

  • Provide graphical interface to select note type
  • Delete all notes of selected type
  • Display deletion count

Example 4: Generate Notes by Beats

Generate Tap notes by beats.

# Description: Generate Tap notes by beats
# Args: Start beat, End beat, Notes per beat

import sys
from rct_api import get_current_chart, save_current_chart, Beat, Note

def main():
    if len(sys.argv) < 4:
        print("Error: Usage: start_beat end_beat notes_per_beat")
        return
    
    try:
        start_beat = float(sys.argv[1])
        end_beat = float(sys.argv[2])
        notes_per_beat = int(sys.argv[3])
    except ValueError:
        print("Error: Parameters must be numbers")
        return
    
    chart = get_current_chart()
    if not chart:
        print("Error: Unable to get chart")
        return
    
    if not chart.bpm:
        print("Error: Chart has no BPM information")
        return
    
    # Create Beat converter
    beat = Beat.from_bpm_objects(chart.bpm)
    
    # Calculate beat interval per note
    beat_interval = 1.0 / notes_per_beat
    
    # Generate notes
    current_beat = start_beat
    added_count = 0
    
    while current_beat <= end_beat:
        time = beat.get_time(current_beat)
        degree = (current_beat * 45) % 360  # Angle varies with beat
        
        chart.add_note(Note.TAP, time, degree)
        added_count += 1
        current_beat += beat_interval
    
    # Sort and save
    chart.sort()
    save_current_chart(chart)
    print(f"Success: Generated {added_count} Tap notes")
    print(f"Time range: {beat.get_time(start_beat):.0f}ms - {beat.get_time(end_beat):.0f}ms")

if __name__ == "__main__":
    main()

Features:

  • Generate notes based on music beats
  • Support custom beat range
  • Support custom note density per beat

Example 5: Analyze Note Beat Information

Analyze the beat distribution of notes in the chart.

# Description: Analyze the beat distribution of notes in the chart

from rct_api import get_current_chart, Beat, Note

def main():
    chart = get_current_chart()
    if not chart:
        print("Error: Unable to get chart")
        return
    
    if not chart.bpm:
        print("Error: Chart has no BPM information")
        return
    
    if not chart.notes:
        print("Error: Chart has no notes")
        return
    
    # Create Beat converter
    beat = Beat.from_bpm_objects(chart.bpm)
    
    print("=== Note Beat Analysis ===")
    print(f"Total notes: {len(chart.notes)}")
    print()
    
    # Analyze first 10 notes
    print("Beat information of first 10 notes:")
    for i, note in enumerate(chart.notes[:10]):
        note_beat = beat.get_beat(note.time)
        type_names = {
            Note.TAP: "Tap",
            Note.FLICK: "Flick",
            Note.SLIDE: "Slide",
            Note.ROTATE: "Rotate",
            Note.CATCH: "Catch",
            Note.BOMB: "Bomb",
            Note.TRAIL: "Trail"
        }
        type_name = type_names.get(note.type, f"Unknown({note.type})")
        print(f"  {i+1}. {type_name} - Time: {note.time:.0f}ms, Beat: {note_beat:.3f}")
    
    # Count notes on whole beats (tolerance ±0.05 beats)
    on_beat_count = 0
    tolerance = 0.05
    
    for note in chart.notes:
        note_beat = beat.get_beat(note.time)
        if abs(note_beat - round(note_beat)) < tolerance:
            on_beat_count += 1
    
    percentage = (on_beat_count / len(chart.notes)) * 100
    print()
    print(f"Notes on whole beats: {on_beat_count}/{len(chart.notes)} ({percentage:.1f}%)")

if __name__ == "__main__":
    main()

Features:

  • Analyze beat information of notes
  • Display detailed information of first 10 notes
  • Count percentage of notes on whole beats

More Examples

Filter Notes by Time Range

# Description: Keep notes within specified time range
# Args: Start time(ms), End time(ms)

import sys
from rct_api import get_current_chart, save_current_chart

def main():
    if len(sys.argv) < 3:
        print("Error: Usage: start_time end_time")
        return
    
    start = float(sys.argv[1])
    end = float(sys.argv[2])
    
    chart = get_current_chart()
    if not chart:
        return
    
    original = len(chart.notes)
    chart.filter_notes_by_time(start, end)
    
    save_current_chart(chart)
    print(f"Kept {len(chart.notes)}/{original} notes")

if __name__ == "__main__":
    main()

Keep Only Specific Note Types

# Description: Keep only Tap and Flick notes

from rct_api import get_current_chart, save_current_chart, Note

def main():
    chart = get_current_chart()
    if not chart:
        return
    
    original = len(chart.notes)
    chart.filter_notes_by_type([Note.TAP, Note.FLICK])
    
    save_current_chart(chart)
    print(f"Kept {len(chart.notes)}/{original} notes")

if __name__ == "__main__":
    main()
Prev
Data Classes
Next
Best Practices