Skip to content

ValleyLib

ValleyLib is a modern, command-based robotics library for FIRST Tech Challenge (FTC), heavily inspired by WPILib and FTCLib. It brings the proven command-based programming paradigm from FRC to FTC, with first-class support for Pedro Pathing, the Panels dashboard, and desktop simulation.

If you have written FRC code with WPILib — or FTC code with FTCLib — you will feel at home immediately. If you haven't, the Quickstart walks you through everything from scratch.

Season note

2.0.0 is the first ValleyLib release for BIOBUZZ, the 2026-2027 FTC season — it targets FTC SDK 12 and Pedro Pathing 3. Teams still on DECODE should stay on 1.0.8; see the Changelog for what changed and the Pedro migration guide for how to move.

Why command-based?

Traditional FTC OpModes tend to grow into giant loop() methods full of if statements and state machines. Command-based programming replaces that with two simple building blocks:

  • Subsystems represent your hardware (drivetrain, intake, lift, ...). They expose high-level actions and own their motors and sensors.
  • Commands represent behavior (drive forward, run the intake for 2 seconds, follow a path, ...). They have a well-defined lifecycle and can be composed like Lego bricks.

A central CommandScheduler runs everything, enforces that two commands never fight over the same subsystem, and runs default commands (like joystick driving) whenever a subsystem is idle.

// An entire autonomous routine, readable top to bottom:
driveCommand
    .until(robot::atTarget)
    .andThen(intakeCommand.withTimeout(1.0))
    .finallyDo(() -> drive.stop());

The two modules

Module Contents Platform
valleyLib-core The command framework: Command, CommandScheduler, Subsystem, command groups, decorators, and the AutoDsl autonomous builder. Pure Java — runs on desktop for tests and simulation.
valleyLib-ftc Everything FTC-specific: CommandOpMode, gamepad/trigger bindings, motor wrappers, PID/feedforward controllers, telemetry, and Pedro Pathing integration. Android (FTC SDK).

This separation means your command logic can be unit-tested and simulated on your laptop without a robot — see Desktop Simulation & Testing.

Feature overview

  • Fluent Command API — every command supports decorators like withTimeout, until, unless, andThen, alongWith, raceWith, deadlineWith, repeatedly, and more. → Decorators

  • Command groups & factories — sequential, parallel, race, deadline, and conditional groups, plus the Commands factory class for quick one-liners. → Command Groups

  • Automatic scheduling — subsystem requirements, default commands, lifecycle listeners, safe interruption, and requirement-carrying subsystem factories (drive.run(...), intake.startEnd(...)), all handled by one scheduler. → Scheduler / Subsystems

  • Gamepad triggers — WPILib-style Trigger bindings (onTrue, whileTrue, toggleOnTrue, ...) that auto-register with the loop poller, with Xbox and PlayStation naming, deadbands, and response curves. → Gamepads / Triggers

  • Hardware wrappers — FTCLib-style Motor, MotorEx, and MotorGroup with built-in encoders, velocity/position control, and GoBILDA presets. → Hardware

  • Control theory toolbox — a full PIDFController family plus WPILib's SimpleMotorFeedforward. → Control

  • Pedro Pathing, command-based — PedroSubsystem, FollowPathCommand, and a path-first autonomous DSL that replaces state machines entirely. → Pedro Pathing

  • Telemetry & logging — one FtcTelemetryBus that mirrors data to the Driver Station and the Panels dashboard, plus automatic command lifecycle logging. → Telemetry

  • Autonomous DSLs — declarative builders (AutoDsl, PedroAutoDsl) with markers, waits, conditionals, and parallel actions. → AutoDsl

  • Finite state machines — a first-class StateMachine command: enum states, per-state commands, enter/exit hooks, condition/finish/timeout/global transitions, and terminal states — replaces switch(pathState) loops entirely. → State Machines

  • Desktop simulation — simulationPeriodic() hooks and a simulation mode on the scheduler for hardware-free iteration. → Simulation

At a glance: a complete TeleOp

@TeleOp(name = "My TeleOp")
public class MainTeleOp extends CommandOpMode {

    private DriveSubsystem drive;
    private IntakeSubsystem intake;
    private CommandGamepad driver;

    @Override
    protected void initialize() {
        drive = new DriveSubsystem(hardwareMap);
        intake = new IntakeSubsystem(hardwareMap);
        driver = CommandGamepad.forLogitechF310(gamepad1);
    }

    @Override
    protected void configureBindings() {
        // Joystick driving whenever nothing else uses the drivetrain
        drive.setDefaultCommand(drive.run(() ->
                drive.tankDrive(driver.leftY(), driver.rightY())));

        // Hold A to intake, hold B to eject — bindings register themselves
        driver.a().whileTrue(intake.startEnd(intake::in, intake::stop));
        driver.b().whileTrue(intake.startEnd(intake::out, intake::stop));
    }

    @Override
    protected void run() {
        telemetryBus.put("Drive", "active");
    }
}

That's the whole OpMode. No manual follower.update(), no telemetry bookkeeping, no state machine — CommandOpMode handles the loop.

Where to go next

  1. Installation — add ValleyLib to your TeamCode project via JitPack.
  2. Quickstart — build your first subsystem, robot container, and OpMode.
  3. Commands — learn the core abstraction everything else builds on.
  4. Finite State Machines — how to express cycles, loops, and overrides as a StateMachine command.
  5. API Summary — a one-page index of every public class in the library.