Skip to content

Packaging a problem#

This walkthrough covers the full process of packaging a problem for a judge system, from profiling time limits all the way to uploading the final package. We'll use BOCA as our target judge, but the overall workflow applies to any supported format.

We assume you already have a working problem -- tests build, solutions run, and expected outcomes match. If you're starting from scratch, follow the First steps walkthrough first.

Overview#

Packaging a problem involves three main stages:

  1. Profiling -- Measure solution timings and decide on a time limit appropriate for the target judge's hardware.
  2. Packaging -- Build the problem into a format the judge system understands.
  3. Uploading -- Get the package into the judge, either manually or automatically.

Step 1: Profile the time limit#

Different judge systems run on different hardware. A time limit that works on your laptop may be too tight -- or too generous -- on the actual judging machine. rbx solves this with limits profiles: named sets of time/memory limits stored in the .limits/ directory of your problem.

Info

For a complete reference on profiling, formulas, and profiles, see the Profiling guide.

Create a profile for BOCA#

The BOCA packager requires a limits profile named boca to exist. You create it with the time command. Preferrably, log in to your judge machine, clone your contest's repository and run the command there.

rbx time -p boca

This launches an interactive session that:

  1. Shows the current profile (if one already exists).
  2. Asks you to choose a strategy for deciding the time limit.
  3. Runs all accepted solutions with no time limit enforced, measuring their true execution times.
  4. Applies a formula to the timings and writes the result to .limits/boca.yml.

Tip

If you want to skip the interactive prompts and use the default formula, add the --auto flag:

rbx time -p boca --auto

Choose a strategy#

When prompted, you'll see four strategies:

Strategy When to use
Estimate (recommended) Let rbx measure your solutions and apply a formula. Best default.
Inherit from package Mirror whatever timeLimit and memoryLimit are set in problem.rbx.yml.
Estimate with custom formula Like Estimate, but you provide your own formula.
Custom time limit You already know the exact time limit you want.

The default formula is:

step_up(max(fastest * 3, slowest * 1.5), 100)

This takes the maximum of 3x the fastest accepted solution and 1.5x the slowest, then rounds up to the nearest 100 ms. You can customize this formula in env.rbx.yml -- see the Profiling docs for details.

Review the resulting profile#

After the estimation finishes, the profile is saved to .limits/boca.yml. It looks something like this:

# .limits/boca.yml
inheritFromPackage: false
timeLimit: 2000
memoryLimit: 256
formula: "step_up(max(fastest * 3, slowest * 1.5), 100)"

You can also add per-language overrides if your contest accepts solutions in multiple languages with different performance characteristics:

modifiers:
  py:
    time: 6000          # Python gets a higher time limit (ms)
  java:
    timeMultiplier: 2.0 # Java gets 2x the base time limit

Tip

When rbx time detects accepted solutions in multiple languages, it will automatically prompt you to set per-language limits. You can also edit the profile manually or through the TUI (rbx ui > Edit limits profiles).

Verify with the profile active#

Once your profile is ready, you can run your solutions under the BOCA limits to make sure everything still passes:

rbx -p boca run

The -p (or --profile) flag is a global flag that tells rbx to use the specified limits profile for the run.

Working with multiple profiles#

You can create as many profiles as you need -- one per target judge:

rbx time -p boca
rbx time -p polygon
rbx time -p local    # the default profile

Each profile is independent, so you can tune limits for each judge's hardware separately.

Persisting the profile#

Now, since the profile is saved into .limits, you can push it into your contest's repository, and access it from any machine. Feel free to follow the next steps in any machine of your choice, as long as you've pushed the profile into the repository.

Step 2: Build the package#

With the boca limits profile in place, you can now build the BOCA package:

rbx package boca

This command performs the following steps automatically:

  1. Loads the boca limits profile from .limits/boca.yml.
  2. Builds all testcases -- generators are run, inputs are validated, outputs are generated using the main solution.
  3. Verifies all solutions -- every solution is run against the testcases and its outcome is checked.
  4. Builds statements -- the problem statement is compiled into a PDF.
  5. Produces a .zip file in the BOCA format, ready for upload.

The resulting .zip is saved in the problem's build/ directory.

Verification levels#

By default, packaging runs at verification level 4 (the maximum), which runs all solutions and checks their expected outcomes. You can lower this to speed things up during development:

rbx package boca -v0  # Only generate tests, no validation
rbx package boca -v1  # Generate tests and validate inputs
rbx package boca -v2  # Also run accepted solutions
rbx package boca -v3  # Also run non-TLE solutions
rbx package boca -v4  # Run all solutions (default)

See the Packaging overview for the full verification level table.

Packaging an entire contest#

If you're working in a contest directory, you can package all problems at once:

rbx each package boca

Or target specific problems by letter:

rbx on A package boca       # Only problem A
rbx on A-C package boca     # Problems A through C
rbx on A,C package boca     # Problems A and C

Step 3: Upload to BOCA#

Once you have your .zip package, you need to get it into the BOCA server. There are two ways to do this: automated upload via rbx and manual upload through the BOCA web interface.

Option A: Automated upload with -u#

The easiest approach is to use the --upload (or -u) flag, which builds the package and uploads it in a single step:

rbx package boca -u

Set up BOCA credentials#

For the upload to work, rbx needs to know how to connect to your BOCA server. Set the following environment variables, either in your shell or in a .env / .env.local file at the root of your contest:

.env
BOCA_BASE_URL="https://your.boca.com/boca"
BOCA_USERNAME="admin_username"
BOCA_PASSWORD="admin_password"

If you're using a judge account instead of an admin account:

.env
BOCA_BASE_URL="https://your.boca.com/boca"
BOCA_JUDGE_USERNAME="judge_username"
BOCA_JUDGE_PASSWORD="judge_password"

Warning

The configured user must be an admin of the contest in BOCA, otherwise the upload will fail. Also make sure the correct contest is activated on the BOCA server before running the command.

Upload an entire contest#

You can combine the upload flag with the contest-level commands:

# Upload all problems
rbx each package boca -u

# Upload only problem A
rbx on A package boca -u

# Upload problems A through C
rbx on A-C package boca -u

Option B: Manual upload#

If you prefer not to configure credentials, or if your BOCA instance isn't reachable from your machine, you can upload the package manually:

  1. Build the package without the -u flag:

    rbx package boca
    
  2. Locate the .zip file in the build/ directory of your problem.

  3. Log in to the BOCA web interface as a contest admin.

  4. Navigate to the Problems tab and upload the .zip file for the corresponding problem letter.

Tip

If you run into issues with BOCA packaging or uploading, check the BOCA troubleshooting section for common problems and solutions.

Next steps#

  • Fine-tune your limits


    Learn about custom formulas, per-language modifiers, and the TUI limits editor.

    Profiling

  • Explore other formats


    Package for Polygon, or other formats supported by rbx.

    Packaging

  • Build statements


    Create PDF statements using rbxTeX, LaTeX, and Jinja.

    Statements

  • Full CLI reference


    See all available flags and commands.

    CLI reference