What is Tweaks?

Real-time Parameter Control

Tweaks provides a dynamic panel that allows you to adjust variables, colors, numbers, and boolean values in real-time without modifying code or refreshing your application.

Rapid Prototyping

Perfect for game development, animations, visualizations, and any interactive content where fine-tuning parameters is crucial for achieving the desired effect.

Developer Experience

Enhances the development workflow by providing instant feedback and eliminating the need for constant code changes during the experimentation phase.

How to Use Tweaks

1

Enable Tweaks as an Advanced Ability

When starting a new project, select "Tweaks" from the Advanced Abilities options. This will automatically set up the Tweaks infrastructure in your project.

Project Setup
✅ Tweaks - Real-time parameter adjustment
2

Import and Initialize Tweaks

In your JavaScript file, import the Tweaks library and create a Tweaks instance:

JavaScript
import { Tweaks } from 'https://esm.sh/tweaks';

const tweaks = new Tweaks();
tweaks.show(); // Display the Tweaks panel
3

Add Parameters to Tweak

Use the various methods to add different types of parameters:

Adding Parameters
// Numbers with range
const speed = tweaks.addNumber('Speed', 5, { min: 0, max: 10, step: 0.1 });

// Colors
const color = tweaks.addColor('Background Color', '#ff0000');

// Booleans
const isEnabled = tweaks.addBoolean('Enable Effect', true);

// Strings
const message = tweaks.addString('Message', 'Hello World');

// Select options
const mode = tweaks.addSelect('Mode', 'normal', ['normal', 'fast', 'slow']);
4

Use the Values in Your Code

Access the current values of your parameters in your render loop or event handlers:

Using Values
function animate() {
    // Get current values from Tweaks
    const currentSpeed = speed.value;
    const currentColor = color.value;
    const enabled = isEnabled.value;
    
    if (enabled) {
        // Use the tweaked values
        object.rotation.y += currentSpeed * 0.01;
        renderer.setClearColor(currentColor);
    }
    
    requestAnimationFrame(animate);
}

Adding Tweaks to Existing Projects

Project Already Started?

Don't worry! You can still add Tweaks to your existing project even if you didn't select it initially as an Advanced Ability.

Method 1: Manual Installation

1

Add the Tweaks import to your JavaScript file:

import { Tweaks } from 'https://esm.sh/tweaks';
2

Initialize Tweaks in your code:

const tweaks = new Tweaks();
tweaks.show();
3

Add your parameters and start tweaking!

Method 2: Request Project Update

1

Ask your AI assistant to add Tweaks to your project:

"Please add Tweaks functionality to this project"
2

The AI will automatically set up the necessary imports and initialization code.

3

Specify which parameters you'd like to be tweakable.

Pro Tip:

When requesting Tweaks to be added to an existing project, be specific about which variables or properties you want to control. This helps the AI set up the most useful Tweaks panel for your needs.

Complete API Reference

Parameter Types

addNumber(name, value, options)

Number Parameter
// Basic number
const speed = tweaks.addNumber('Speed', 5);

// With range and step
const precision = tweaks.addNumber('Precision', 0.5, {
    min: 0,
    max: 1,
    step: 0.01
});

// With custom range
const temperature = tweaks.addNumber('Temperature', 20, {
    min: -10,
    max: 50,
    step: 0.5
});

addColor(name, value)

Color Parameter
// Hex color
const bgColor = tweaks.addColor('Background', '#ff0000');

// RGB color
const textColor = tweaks.addColor('Text Color', 'rgb(255, 0, 0)');

// Named color
const accent = tweaks.addColor('Accent', 'crimson');

addBoolean(name, value)

Boolean Parameter
// Simple boolean
const isEnabled = tweaks.addBoolean('Enable Effect', true);

// Multiple booleans
const showDebug = tweaks.addBoolean('Show Debug', false);
const autoRotate = tweaks.addBoolean('Auto Rotate', true);

addString(name, value)

String Parameter
// Text input
const message = tweaks.addString('Message', 'Hello World');

// URL input
const imageUrl = tweaks.addString('Image URL', '/default.jpg');

addSelect(name, value, options)

Select Parameter
// Simple select
const mode = tweaks.addSelect('Mode', 'normal', [
    'normal', 'fast', 'slow'
]);

// Object options
const quality = tweaks.addSelect('Quality', 'medium', {
    'Low': 'low',
    'Medium': 'medium',
    'High': 'high'
});

addVector2(name, x, y, options)

Vector2 Parameter
// 2D position
const position = tweaks.addVector2('Position', 0, 0, {
    min: -100,
    max: 100,
    step: 1
});

// Access values
console.log(position.x, position.y);

addVector3(name, x, y, z, options)

Vector3 Parameter
// 3D rotation
const rotation = tweaks.addVector3('Rotation', 0, 0, 0, {
    min: -Math.PI,
    max: Math.PI,
    step: 0.01
});

// Access values
object.rotation.set(rotation.x, rotation.y, rotation.z);

addButton(name, callback)

Button Parameter
// Action button
tweaks.addButton('Reset Scene', () => {
    resetAllObjects();
});

// Multiple actions
tweaks.addButton('Save Screenshot', saveScreenshot);
tweaks.addButton('Toggle Fullscreen', toggleFullscreen);

Advanced Features

Folders and Organization

Group related parameters into collapsible folders for better organization.

Organizing with Folders
// Create folders
const lightingFolder = tweaks.addFolder('Lighting');
const materialFolder = tweaks.addFolder('Material');

// Add parameters to folders
lightingFolder.addNumber('Intensity', 1, { min: 0, max: 5 });
lightingFolder.addColor('Color', '#ffffff');

materialFolder.addNumber('Roughness', 0.5, { min: 0, max: 1 });
materialFolder.addNumber('Metalness', 0, { min: 0, max: 1 });

// Nested folders
const advancedFolder = lightingFolder.addFolder('Advanced');
advancedFolder.addVector3('Position', 0, 10, 0);

Presets and State Management

Save and load different configurations to quickly switch between setups.

Working with Presets
// Save current state as preset
tweaks.savePreset('Day Scene');
tweaks.savePreset('Night Scene');

// Load a preset
tweaks.loadPreset('Night Scene');

// Get all preset names
const presets = tweaks.getPresets();

// Export/Import presets
const stateData = tweaks.exportState();
localStorage.setItem('tweaks-state', JSON.stringify(stateData));

// Later, restore state
const savedState = JSON.parse(localStorage.getItem('tweaks-state'));
tweaks.importState(savedState);

Event Handling and Callbacks

React to parameter changes with custom callbacks and event listeners.

Parameter Change Events
// Listen to specific parameter changes
const speed = tweaks.addNumber('Speed', 5);
speed.onChange((value) => {
    console.log('Speed changed to:', value);
    updateAnimationSpeed(value);
});

// Listen to all parameter changes
tweaks.onChange((changedParameter, newValue) => {
    console.log(`${changedParameter.name} changed to:`, newValue);
});

// One-time event listeners
speed.once('change', () => {
    console.log('Speed was changed for the first time');
});

// Remove event listeners
const callback = (value) => console.log(value);
speed.onChange(callback);
speed.removeListener('change', callback);

Panel Configuration

Customize the appearance and behavior of the Tweaks panel.

Panel Customization
// Initialize with options
const tweaks = new Tweaks({
    title: 'My Controls',
    position: 'top-left', // top-left, top-right, bottom-left, bottom-right
    width: 300,
    collapsed: false,
    theme: 'dark', // light, dark, auto
    autoPlace: true,
    hideable: true,
    closeable: false
});

// Runtime panel control
tweaks.show();
tweaks.hide();
tweaks.toggle();
tweaks.open(); // expand if collapsed
tweaks.close(); // collapse if expanded

// Position and sizing
tweaks.setPosition('bottom-right');
tweaks.setWidth(400);
tweaks.setTitle('Updated Controls');

Real-World Examples

Game Development

Game Parameter Tweaking
// Player settings
const playerFolder = tweaks.addFolder('Player');
const jumpHeight = playerFolder.addNumber('Jump Height', 10, { min: 5, max: 20 });
const moveSpeed = playerFolder.addNumber('Move Speed', 300, { min: 100, max: 500 });
const playerColor = playerFolder.addColor('Player Color', '#00ff00');

// Enemy settings
const enemyFolder = tweaks.addFolder('Enemies');
const spawnRate = enemyFolder.addNumber('Spawn Rate', 2, { min: 0.5, max: 5, step: 0.1 });
const enemyHealth = enemyFolder.addNumber('Health', 100, { min: 50, max: 200 });

// Game loop
function updateGame() {
    player.jumpPower = jumpHeight.value;
    player.speed = moveSpeed.value;
    player.tint = playerColor.value;
    
    enemyManager.spawnRate = spawnRate.value;
    enemyManager.defaultHealth = enemyHealth.value;
}

3D Visualization

Three.js Scene Controls
// Camera controls
const cameraFolder = tweaks.addFolder('Camera');
const fov = cameraFolder.addNumber('FOV', 75, { min: 10, max: 160 });
const cameraPosition = cameraFolder.addVector3('Position', 0, 5, 10);

// Lighting
const lightFolder = tweaks.addFolder('Lighting');
const ambientIntensity = lightFolder.addNumber('Ambient', 0.4, { min: 0, max: 1 });
const directionalIntensity = lightFolder.addNumber('Directional', 1, { min: 0, max: 3 });
const lightColor = lightFolder.addColor('Light Color', '#ffffff');

// Material properties
const materialFolder = tweaks.addFolder('Material');
const roughness = materialFolder.addNumber('Roughness', 0.5, { min: 0, max: 1 });
const metalness = materialFolder.addNumber('Metalness', 0, { min: 0, max: 1 });

// Animation
function animate() {
    camera.fov = fov.value;
    camera.position.set(cameraPosition.x, cameraPosition.y, cameraPosition.z);
    camera.updateProjectionMatrix();
    
    ambientLight.intensity = ambientIntensity.value;
    directionalLight.intensity = directionalIntensity.value;
    directionalLight.color.set(lightColor.value);
    
    material.roughness = roughness.value;
    material.metalness = metalness.value;
}

Creative Coding

Generative Art Controls
// Canvas settings
const canvasFolder = tweaks.addFolder('Canvas');
const backgroundColor = canvasFolder.addColor('Background', '#000000');
const clearCanvas = canvasFolder.addBoolean('Clear Each Frame', true);

// Pattern generation
const patternFolder = tweaks.addFolder('Pattern');
const particleCount = patternFolder.addNumber('Particles', 100, { min: 10, max: 1000 });
const noiseScale = patternFolder.addNumber('Noise Scale', 0.01, { min: 0.001, max: 0.1, step: 0.001 });
const colorPalette = patternFolder.addSelect('Palette', 'rainbow', [
    'rainbow', 'sunset', 'ocean', 'forest'
]);

// Animation controls
const animFolder = tweaks.addFolder('Animation');
const animSpeed = animFolder.addNumber('Speed', 1, { min: 0, max: 5, step: 0.1 });
const rotationSpeed = animFolder.addNumber('Rotation', 0.01, { min: -0.1, max: 0.1, step: 0.001 });

// Reset button
tweaks.addButton('Reset Pattern', () => {
    initializeParticles();
    resetAnimation();
});

Data Visualization

Chart Configuration
// Data controls
const dataFolder = tweaks.addFolder('Data');
const dataPoints = dataFolder.addNumber('Data Points', 50, { min: 10, max: 200 });
const refreshRate = dataFolder.addNumber('Refresh Rate (ms)', 1000, { min: 100, max: 5000 });
const dataRange = dataFolder.addVector2('Value Range', 0, 100);

// Visualization
const vizFolder = tweaks.addFolder('Visualization');
const chartType = vizFolder.addSelect('Chart Type', 'line', ['line', 'bar', 'scatter', 'area']);
const showGrid = vizFolder.addBoolean('Show Grid', true);
const smoothing = vizFolder.addBoolean('Smooth Lines', true);

// Styling
const styleFolder = tweaks.addFolder('Styling');
const primaryColor = styleFolder.addColor('Primary Color', '#2196F3');
const secondaryColor = styleFolder.addColor('Secondary Color', '#FF9800');
const lineWidth = styleFolder.addNumber('Line Width', 2, { min: 1, max: 10 });

// Update chart
function updateChart() {
    chart.config.data.datasets[0].pointBackgroundColor = primaryColor.value;
    chart.config.data.datasets[0].borderColor = primaryColor.value;
    chart.config.data.datasets[0].borderWidth = lineWidth.value;
    chart.config.options.scales.x.grid.display = showGrid.value;
    chart.update();
}

Performance Considerations

Optimize Update Frequency

Avoid reading Tweaks values on every frame if the calculations are expensive.

Efficient Value Reading
// BAD: Reading on every frame
function animate() {
    heavyCalculation(expensiveParam.value);
    requestAnimationFrame(animate);
}

// GOOD: Cache values and update only when changed
let cachedValue = expensiveParam.value;
expensiveParam.onChange(value => cachedValue = value);

function animate() {
    heavyCalculation(cachedValue);
    requestAnimationFrame(animate);
}

Memory Management

Clean up event listeners when components are destroyed.

Cleanup
class MyComponent {
    constructor() {
        this.tweaks = new Tweaks();
        this.speed = this.tweaks.addNumber('Speed', 5);
        
        // Store callback reference for cleanup
        this.speedCallback = (value) => this.updateSpeed(value);
        this.speed.onChange(this.speedCallback);
    }
    
    destroy() {
        // Clean up listeners
        this.speed.removeListener('change', this.speedCallback);
        this.tweaks.destroy();
    }
}

Mobile Optimization

Consider mobile-specific configurations for better touch interaction.

Mobile Settings
const isMobile = window.innerWidth < 768;

const tweaks = new Tweaks({
    width: isMobile ? 280 : 320,
    position: isMobile ? 'bottom-left' : 'top-right',
    collapsed: isMobile, // Start collapsed on mobile
    hideable: true
});

// Larger step sizes for touch
const sensitivity = isMobile ? 0.1 : 0.01;
const rotation = tweaks.addNumber('Rotation', 0, {
    min: -Math.PI,
    max: Math.PI,
    step: sensitivity
});

Keyboard Shortcuts & Tips

H
Toggle panel visibility
Space
Collapse/expand panel
Tab
Navigate between controls
Enter
Confirm text input
↑↓
Adjust number values
Shift + ↑↓
Adjust with larger steps

Pro Tips

Double-click number inputs to type exact values
Right-click parameters to access additional options like reset to default
Drag number labels to scrub values quickly
Use folders to organize complex parameter sets
Save presets for different scenarios or moods

Best Practices

Meaningful Names

Use descriptive names for your parameters that clearly indicate what they control.

Appropriate Ranges

Set realistic min/max values and step sizes for numeric parameters to provide fine-grained control.

Group Related Parameters

Organize related parameters together and use folders for complex interfaces.

Save Presets

Use Tweaks' preset functionality to save and load different configurations quickly.