import { runtimeSettings } from './config/runtime-settings'; import type { GardenAppConfig } from './config/types'; import { audioVibes, defaultVibeId, vibePresets } from './config/vibe-presets'; export type { AgentColorInteractionSettings, GardenAppConfig, GardenAudioEngineConfig, GardenRuntimeSettings, GardenSimulationConfig, GardenStorageConfig, GardenVibeSettings, NumberControlConfig, RuntimeSettingControlConfig, VibePreset, } from './config/types'; export const appConfig = { audio: { masterVolume: 0.42, fadeInSeconds: 0.45, updateRampSeconds: 0.08, highPassFrequencyHz: 45, fallbackVibeId: defaultVibeId, compressor: { thresholdDb: -18, kneeDb: 18, ratio: 2.4, attackSeconds: 0.006, releaseSeconds: 0.18, }, delay: { timeSeconds: 0.46, feedback: 0.12, wetGain: 0.044, }, piano: { maxVoices: 24, gain: 0.48, sustainSeconds: 0.42, sustainLevel: 0.32, releaseSeconds: 0.24, lowpassHz: 7600, }, input: { pressureFallback: 0.48, }, rhythm: { bpm: 74, stepsPerBeat: 4, stepsPerBar: 16, lookaheadSeconds: 0.3, speedForFullEnergyPixelsPerSecond: 1800, sparseActivity: 0.055, }, eraser: { minIntervalSeconds: 0.12, noiseGain: 0.028, filterMinHz: 650, filterMaxHz: 3600, }, colorVoices: [ { scaleDegreeOffset: 0, velocityMultiplier: 0.92, panOffset: -0.14, }, { scaleDegreeOffset: 1, velocityMultiplier: 1, panOffset: 0, }, { scaleDegreeOffset: 2, velocityMultiplier: 0.86, panOffset: 0.14, }, ], vibes: audioVibes, }, audioEngine: { energy: { attackSeconds: 0.08, decaySeconds: 0.9, releaseSeconds: 1.15, strokeDecaySeconds: 0.32, }, eraser: { canvasWidthRatioForFullSize: 0.18, defaultSizePixels: 96, durationSeconds: 0.08, filterPressureWeight: 0.26, filterSizeWeight: 0.16, filterSpeedWeight: 0.58, gainBase: 0.45, gainPressureWeight: 0.24, gainSizeWeight: 0.18, gainSpeedWeight: 0.38, }, delay: { erasingActivity: 0.12, }, graph: { closeGain: 0.0001, closeRampSeconds: 0.015, delayActivityFeedbackWeight: 0.08, delayFeedbackMax: 0.32, delayFeedbackMin: 0.04, delayOutputActivityWeight: 0.5, delayOutputBase: 0.65, delayTimeRampSeconds: 0.12, eventBusGain: 1, noiseMax: 1, noiseMin: -1, unlockBufferLength: 1, unlockSampleRate: 22050, }, input: { distanceEnergyBase: 0.34, distanceEnergyScale: 0.66, distanceForFullEnergyPixels: 140, fallbackFrameSeconds: 1 / 60, penMinPressure: 0.56, strokeEnergyBase: 0.18, strokeEnergyPressureWeight: 0.22, strokeEnergySpeedWeight: 0.62, }, muteGain: 0.0001, muteRampSeconds: 0.02, noiseBurst: { attackSeconds: 0.004, filterQ: 1.4, offsetRandomSeconds: 0.4, scheduleAheadSeconds: 0.002, silentGain: 0.0001, }, piano: { filterQ: 0.7, gainAttackSeconds: 0.006, lowpassMaxHz: 12000, lowpassMinHz: 1400, minDurationSeconds: 0.08, minFadeSeconds: 0.08, minGain: 0.0001, pitchSemitonesPerOctave: 12, scheduleAheadSeconds: 0.002, sustainBase: 0.45, sustainVelocityRange: 0.55, tailStopExtraSeconds: 0.05, voiceStealFadeSeconds: 0.025, voiceStealStopSeconds: 0.05, }, startDelaySeconds: 0.02, vibeChangeStingerMinIntervalSeconds: 0.45, }, deltaTime: { fpsExponentialDecayStrength: 0.01, maxDeltaTimeSeconds: 1 / 30, minDeltaTimeSeconds: 1 / 240, }, export4k: { bytesPerPixel: 4, height: 2160, jsHeapSafetyMultiplier: 1.5, lowMemoryDeviceGiB: 2, lowMemoryExportFraction: 0.08, rowAlignmentBytes: 256, width: 3840, }, menuHider: { bottomRevealDistancePx: 96, desktopMediaQuery: '(min-width: 600px) and (hover: hover) and (pointer: fine)', hideDelayMs: 3000, }, pipelines: { brush: { maxLineCount: 240, }, diffusion: { minDiffusionRate: 0.000001, }, eraser: { maxSegmentCount: 384, maxTextureLineCount: 384, segmentFloatCount: 4, workgroupSize: 64, }, }, runtimeSettings, simulation: { budget: { adaptiveCapDecreaseAgentsPerSecond: 50_000, adaptiveCapMin: 500_000, fpsHeadroom: 0.95, fpsSmoothingNew: 0.06, fpsSmoothingRetain: 0.94, }, brushEffectFramesPerSecond: 60, globalAgentCap: 10_000_000, initialAgentCount: 180_000, intro: { angleJitterRadians: Math.PI * 0.08, circleMaxSideRatio: 0.46, circleMinSideRatio: 0.32, drawHintClass: 'draw-hint', drawHintDelayMs: 3000, durationSeconds: 4, entryJitterSideRatio: 0.035, fontScaleDown: 0.94, initialFontHeightRatio: 0.28, initialFontWidthRatio: 0.19, letterSpacingEm: 0.07, maskAlphaThreshold: 32, maskGradientThreshold: 8, maskSampleDensity: 540, maxHeightRatio: 0.25, maxWidthRatio: 0.76, minEntryJitterPx: 6, minFontSizePx: 18, minTargetJitterPx: 1, radialJitterRatio: 0.35, targetDelayDistanceMultiplier: 0.12, targetDelayMax: 0.22, targetDelayRandomMultiplier: 0.06, targetJitterSideRatio: 0.0035, title: 'Fleeting', titleColorCutLetters: [2, 5], titleRadiusMultiplier: 1.55, titleStrokeWidthMinPx: 6, titleStrokeWidthRatio: 0.11, verticalAnchor: 0.47, }, introMoveSpeedBaseMultiplier: 1.8, introMoveSpeedProgressMultiplier: 0.35, maxMirrorSegmentCount: 12, stroke: { angleJitterRadians: Math.PI * 0.7, densityMultiplier: 110, maxAgentCount: 2_400, minAgentCount: 140, }, }, storage: { audioMutedKey: 'fleeting-garden:audio-muted', vibeKey: 'fleeting-garden:vibe', }, telemetry: { enabled: false, intervalMs: 1000, }, toolbar: { eraser: { controlScaleMax: 1.34, controlScaleMin: 0.74, default: 96, max: 240, min: 24, step: 1, }, mirror: { default: 1, max: 12, min: 1, names: { 2: 'halves', 3: 'thirds', 4: 'quarters', 5: 'fifths', 6: 'sixths', 7: 'sevenths', 8: 'eighths', 9: 'ninths', 10: 'tenths', 11: 'elevenths', 12: 'twelfths', }, step: 1, }, }, tuningPane: { expandedDepth: 1, startHidden: true, title: 'Garden Config', }, vibes: { defaultVibeId, presets: vibePresets, }, } satisfies GardenAppConfig;