Docs Get Started

Install

Add Synapse to your FTC Gradle project — one dependency, no token.

Install

Synapse is distributed as a Maven artifact, com.aaravlabs:synapse:0.4.0, published to Maven Central. Maven Central needs no authentication — if your project already has mavenCentral() in its repositories (the FTC template does), you can add the dependency and you’re done:

dependencies {
    implementation 'com.aaravlabs:synapse:0.4.0'
}

Prefer GitHub Packages? Synapse is also mirrored on GitHub Packages at maven.pkg.github.com/IamCoder18/synapse. That mirror requires a GitHub token with the read:packages scope even for public packages — a GitHub restriction, not a Synapse one. See the advanced section at the bottom of this page for the full walkthrough.

Prerequisites

  • An FTC project built on the standard FtcRobotController template (uses build.dependencies.gradle).
  • Android Studio with the FTC project already syncing.

Step 1 — Add the dependency

Open build.dependencies.gradle in your FTC project and add the dependency:

dependencies {
    implementation 'com.aaravlabs:synapse:0.4.0'
    // ... your other FTC deps
}

No repository block needed? Correct — the FtcRobotController template ships with mavenCentral() and google() in its repositories {}. If your project removed them, re-add mavenCentral() next to google().

Using a version catalog or a newer SDK? The Maven coordinates stay the same (com.aaravlabs:synapse) — only the surrounding syntax changes:

dependencies {
    implementation("com.aaravlabs:synapse:0.4.0")
}

Step 2 — Sync and verify

Sync Gradle (the Sync Now banner, or the Gradle elephant in Android Studio), then confirm the JAR landed:

./gradlew dependencies --configuration debugRuntimeClasspath | grep synapse

You should see com.aaravlabs:synapse:0.4.0 in the output.

Sync fails with “Could not resolve com.aaravlabs:synapse”? Make sure the dependency is in the project-level dependencies {} of build.dependencies.gradle (not buildscript), and that mavenCentral() is present in that file’s repositories {}.

R8 / minification

Synapse ships its ProGuard keep rules inside the JAR at META-INF/proguard/synapse.pro, so minifyEnabled builds work with no extra configuration. The keep rules are exercised in CI by running the full test suite through R8 minification.

What you get

A ~40 KB JAR with zero runtime dependencies, containing:

  • Orchestrator — the pub/sub bus and thread owner.
  • The four annotations: @SubscribedTo, @RunPeriodically, @RunnableAction, @OnHardwareThread.
  • The FTC layer: SafeOpMode, HardwareActions, SafeDevice, SafeHardwareMap, GamepadAdaptor.

Advanced: GitHub Packages mirror

Everything above is the recommended path. Synapse is additionally mirrored on GitHub Packages at maven.pkg.github.com/IamCoder18/synapse. Use the mirror if your team already authenticates against GitHub — for example because your organization proxies GitHub repositories, or your build pipeline signs in with a GitHub App. If in doubt, stay on Maven Central: it needs no credentials.

GitHub Packages requires authentication for downloads even though the package is public. This is a GitHub restriction, not a Synapse one.

1 — Configure a GitHub token

Create a personal access token (classic) with the read:packages scope — fine-grained tokens are not accepted by GitHub Packages — then put it in ~/.gradle/gradle.properties (never commit this file):

githubUser=<your-github-username>
githubToken=<your-token>

Why a token at all? GitHub Packages requires authenticated downloads even when the package is public. The token lives in your local gradle.properties and is only transmitted to maven.pkg.github.com over HTTPS when Gradle resolves the dependency; it has no scopes beyond package reads.

In a GitHub Actions workflow? Use the workflow’s built-in GITHUB_TOKEN with packages: read permission instead of a personal token — the snippets below already fall back to the GITHUB_TOKEN environment variable.

If you are on a team, each member (and the driver station’s build environment) needs their own token in their own gradle.properties.

2 — Add the repository and dependency

Open build.dependencies.gradle in your FTC project and add the mirror repository and the dependency.

Groovy DSL (the default FTC template):

repositories {
    mavenCentral()
    google()
    maven {
        url = uri("https://maven.pkg.github.com/IamCoder18/synapse")
        credentials {
            username = findProperty("githubUser") ?: System.getenv("GITHUB_USER") ?: System.getenv("GITHUB_ACTOR")
            password = findProperty("githubToken") ?: System.getenv("GITHUB_TOKEN")
        }
    }
}

dependencies {
    implementation 'com.aaravlabs:synapse:0.4.0'
}

Kotlin DSL (if your project uses build.dependencies.gradle.kts):

repositories {
    mavenCentral()
    google()
    maven {
        url = uri("https://maven.pkg.github.com/IamCoder18/synapse")
        credentials {
            username = (findProperty("githubUser") as String?)
                ?: System.getenv("GITHUB_USER")
                ?: System.getenv("GITHUB_ACTOR")
            password = (findProperty("githubToken") as String?)
                ?: System.getenv("GITHUB_TOKEN")
        }
    }
}

dependencies {
    implementation("com.aaravlabs:synapse:0.4.0")
}

Using a version catalog or a newer SDK? The coordinates stay the same — only the surrounding syntax changes. Keep the maven { ... } block as-is.

3 — Sync and verify

Sync Gradle, then confirm the JAR landed:

./gradlew dependencies --configuration debugRuntimeClasspath | grep synapse

You should see com.aaravlabs:synapse:0.4.0 in the output.

Sync fails with 401 Unauthorized?

  1. Check that githubUser and githubToken are spelled exactly like that in ~/.gradle/gradle.properties.
  2. Check that the token has read:packages.
  3. Run ./gradlew --refresh-dependencies once to force re-authentication.
  4. If you copied the token with surrounding whitespace, remove it.

Sync fails with “Could not resolve com.aaravlabs:synapse”? Make sure the maven { ... } block is inside repositories { } (not buildscript), and that the credentials block uses findProperty exactly as shown.

Next steps