This repository acts as the dynamic backend for OpenRocket's thrust curve data.
This repository utilizes GitHub Pages to act as a static Content Delivery Network (CDN) for the compiled motor data. This ensures high availability and fast downloads for OpenRocket users without requiring a dedicated backend server.
- Source: ThrustCurve.org API (thanks a lot for this incredible resource!).
- Automation: GitHub Actions runs weekly.
- Process:
- Checks for new motors.
- Downloads raw
.engand.rsefiles todata/. - Compiles them into a SQLite database (
motors.db). - GZips and hashes the database.
- Distribution: The resulting
motors.db.gzandmetadata.jsonare published to GitHub Pages.
The deployment process follows a split-branch strategy:
mainbranch: Contains the source code, scripts, and the raw text cache (.eng/.rsefiles).gh-pagesbranch: Contains only the build artifacts (motors.db.gzandmetadata.json).
Every time the Update Workflow runs (scheduled weekly), it commits the new raw data to main, compiles the database, and force-pushes the binary artifacts to gh-pages.
The OpenRocket client (and other interested 3rd parties) can access the live data at the following URLs:
| File | URL | Description |
|---|---|---|
| Manifest | https://openrocket.info/motor-database/metadata.json |
Lightweight JSON file. Contains the database_version, timestamp, and sha256 checksum. Checked by the client on startup. |
| Database | https://openrocket.info/motor-database/motors.db.gz |
GZipped SQLite database. Downloaded by the client only if the manifest version differs from the local cache. |
The metadata.json structure is defined as follows:
database_version is a sortable timestamp in YYYYMMDDHHMMSS format.
{
"schema_version": 1,
"database_version": 20251225140000,
"generated_at": "2025-12-25T14:00:00.000000",
"motor_count": 1033,
"sha256": "a1b2c3d4e5f6...",
"download_url": "https://openrocket.info/motor-database/motors.db.gz"
}The SQLite schema lives in schema/V1__initial_schema.sql and is optimized for fast client lookups. Foreign keys are enabled with cascade deletes.
manufacturers motors thrust_curves thrust_data
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ id (PK) │◄─────│ mfr_id (FK) │ │ id (PK) │◄───────│ curve_id(FK) │
│ name │ 1:N │ id (PK) │◄────│ motor_id(FK) │ 1:N │ id (PK) │
│ abbrev │ │ tc_motor_id │ 1:N │ tc_simfile_id│ │ time_seconds │
└──────────────┘ │ designation │ │ source │ │ force_newtons│
│ impulse_class│ │ format │ └──────────────┘
│ ... │ │ ... │
└──────────────┘ └──────────────┘
- manufacturers → motors: One manufacturer has many motors
- motors → thrust_curves: One motor can have multiple thrust curves (different sources/measurements)
- thrust_curves → thrust_data: One curve has many time/thrust data points
meta
| Column | Type | Notes |
|---|---|---|
| key | TEXT | Primary key |
| value | TEXT | Required |
Keys stored: schema_version, database_version, generated_at, motor_count.
manufacturers
| Column | Type | Notes |
|---|---|---|
| id | INTEGER | Primary key, autoincrement |
| name | TEXT | Required, unique (e.g. "AeroTech") |
| abbrev | TEXT | Short name (e.g. "AT") |
motors
| Column | Type | Notes |
|---|---|---|
| id | INTEGER | Primary key, autoincrement |
| manufacturer_id | INTEGER | FK to manufacturers.id |
| tc_motor_id | TEXT | ThrustCurve.org motor ID |
| designation | TEXT | Required (e.g. "H128W") |
| common_name | TEXT | Display name (e.g. "H128") |
| impulse_class | TEXT | Letter class: A, B, C, ... O |
| diameter | REAL | Motor diameter in mm |
| length | REAL | Motor length in mm |
| total_impulse | REAL | Total impulse in Ns |
| avg_thrust | REAL | Average thrust in N |
| max_thrust | REAL | Maximum thrust in N |
| burn_time | REAL | Burn time in seconds |
| propellant_weight | REAL | Propellant weight in grams |
| total_weight | REAL | Total weight in grams |
| type | TEXT | "SU" (single-use), "reload", "hybrid" |
| delays | TEXT | Available delays, e.g. "0,6,10,14" |
| case_info | TEXT | Case info, e.g. "RMS 38/360" |
| prop_info | TEXT | Propellant info, e.g. "White Lightning" |
| sparky | INTEGER | 1 if sparky motor, 0 otherwise |
| info_url | TEXT | URL to motor info page |
| data_files | INTEGER | Number of data files on ThrustCurve |
| updated_on | TEXT | Last update date from ThrustCurve |
thrust_curves
Each motor can have multiple thrust curves from different sources (certification, manufacturer, user submissions).
| Column | Type | Notes |
|---|---|---|
| id | INTEGER | Primary key, autoincrement |
| motor_id | INTEGER | FK to motors.id, cascade delete |
| tc_simfile_id | TEXT | ThrustCurve.org simfile ID |
| source | TEXT | "cert", "mfr", or "user" |
| format | TEXT | "RASP" or "RSE" |
| license | TEXT | "PD", "free", or other |
| info_url | TEXT | URL to simfile info page |
| data_url | TEXT | URL to download simfile |
| total_impulse | REAL | Calculated total impulse (Ns) |
| avg_thrust | REAL | Calculated average thrust (N) |
| max_thrust | REAL | Calculated max thrust (N) |
| burn_time | REAL | Calculated burn time (s) |
thrust_data
Time/thrust data points for each thrust curve.
| Column | Type | Notes |
|---|---|---|
| id | INTEGER | Primary key, autoincrement |
| curve_id | INTEGER | FK to thrust_curves.id, cascade delete |
| time_seconds | REAL | Time in seconds |
| force_newtons | REAL | Thrust force in Newtons |
| Index | Table | Columns | Purpose |
|---|---|---|---|
| idx_motor_mfr | motors | manufacturer_id | Filter by manufacturer |
| idx_motor_diameter | motors | diameter | Filter by size |
| idx_motor_impulse | motors | total_impulse | Filter by impulse |
| idx_motor_impulse_class | motors | impulse_class | Filter by class (A-O) |
| idx_motor_tc_id | motors | tc_motor_id | Lookup by ThrustCurve ID |
| idx_curve_motor | thrust_curves | motor_id | Get curves for a motor |
| idx_curve_simfile | thrust_curves | tc_simfile_id | Lookup by simfile ID |
| idx_thrust_curve | thrust_data | curve_id | Get data for a curve |
pip install -r scripts/requirements.txtpython scripts/fetch_updates.py(Downloads new files)python scripts/build_database.py(Generates DB)
The motor data in this repository is cached from ThrustCurve.org.
- Source: ThrustCurve.org (maintained by John Coker).
- Copyright: The data files (
.eng,.rse) retain their original internal copyright headers. - Usage: This data is intended for use within OpenRocket. If you wish to use this data for other projects, please use the ThrustCurve.org API directly to ensure you are respecting the latest updates and restrictions.