Agent skill

Build Vehicle

by LunCoSim in LunCoSim/lunco-sim

How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws…

Apache-2.0Auto-check passedFrontend & Design

Install Build Vehicle

skills CLI
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/build-vehicle .claude/skills/build-vehicle && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
build-vehicle
GitHub stars
107
Token cost
~6.7k tokens
SKILL.md length
3,045 words
Files
1
Skills in repo
40
Repo updated
First seen
Licence
Apache-2.0

At a glance

How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws…

  • Works in 4 steps: terrain/course and presentation cameras; → the vehicle-specific assembly or… → the authored Modelica drive law, proved… → …
  • The user asks to make/build a rover
  • SKILL.md covers Reuse-first vehicle audit, The component library…, Minimal rover and Wheel physics: one parameter…, plus 5 more sections
  • Calls kind

What it does

Build Vehicle is an agent skill from LunCoSim/lunco-sim. How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws, and live parameter tuning. USE THIS SKILL when the user asks to "make/build a rover", "add a vehicle", "give it different wheels/tires", "swap the drivetrain", "tune wheel physics", "make the drivetrain a Modelica model", or asks why a wheel refuses to spawn. For a single reusable part use author-usd-component; for scene…

Its SKILL.md is about 6.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering Design systems and Accessibility. It works with Rust. The repository describes itself as: Collaborative Multiphysics Cosimulator For Space Missions 🌎🚀🌚. The licence is Apache-2.0.

When your agent uses it

  • The user asks to make/build a rover
  • Give it different wheels/tires
  • Swap the drivetrain
  • Tune wheel physics

Example prompts

  • “make/build a rover”
  • “add a vehicle”
  • “give it different wheels/tires”
  • “/build-vehicle”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. terrain/course and presentation cameras;
  2. the vehicle-specific assembly or rocker-bogie morphology;
  3. the authored Modelica drive law, proved by scenes/tests/modelica_drive_law.usda
  4. battery, generation, thermal, then autonomy/story behaviour.

What it can do on your machine

Read from SKILL.md and the folder at commit 43f1301. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • kind

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Build Vehicle loads about 6.7k tokens when it runs. Until then it costs about 238 tokens; SKILL.md has 3,045 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~238
When it runs · the whole SKILL.md, loaded when a task matches
~6.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from LunCoSim/lunco-sim at commit 43f1301, republished under its Apache-2.0 licence (© LunCoSim). 3,045 words, ~6,728 tokens.

Download SKILL.mdSave it as .claude/skills/build-vehicle/SKILL.md (or your agent's skills folder).
name
build-vehicle
description
How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws, and live parameter tuning. USE THIS SKILL when the user asks to "make/build a rover", "add a vehicle", "give it different wheels/tires", "swap the drivetrain", "tune wheel physics", "make the drivetrain a Modelica model", or asks why a wheel refuses to spawn. For a single reusable part use author-usd-component; for scene assembly use build-usd-scene; for GNC use authoring-vessel-controllers. Project-specific and non-obvious: wheel params are STRICT (a missing attr refuses the wheel and names everything missing), defaults live in components/mobility/wheel.usda (never in Rust), the raycast/physical split is decided per wheel by an authored PhysicsRevoluteJoint, and live edits flow ApplyUsdOp → in-place wheel resync (never a respawn).

Build a vehicle

A vehicle is a thin assembly: a kind = "assembly" Xform root that references library components and authors only its own decisions — poses, indices, scale, paint. Components own their defaults; variants choose components, they never restate them.

For script-authored assembly edits, the dynamically reloadable assets/scripting/tools/assembly_builder.rhai library provides semantic frame/shape construction, placement, Cube and composed collision alignment/clearance, referenced-part mounting, existing-mount frame realignment, and body/joint plans. A referenced assembly uses referenced_instance_plan (or its targeted form), then applies select_variants_plan only after the reference children are queryable. Parameter edits use parameter_plan and the same typed ApplyUsdOps boundary as the Editor; the planner is generic and does not know vehicle names or paths.

When iterating a referenced component in Editor, use component_editor::selected_update_context to preserve the exact preview, document, path, and generation, then use component_editor::update_plan with the component recipe from the owning Twin. Review and commit its one typed change set before checking the composed rover; do not put vehicle-specific recipes or a component registry in Rust.

Mission-specific recipes and study assets belong in the Twin that owns them, rather than in the core asset library. A Twin tool may compose these generic helpers and supply its own explicit paths and study values, but it must remain Rhai-owned and use the proposal/journal boundary. Keep component defaults in reusable USD components and author vehicle-specific choices in the Twin assembly.

When a vehicle part is already attached and a socket or plug frame moves, use assembly_builder::mount_frame_realignment_plan with the exact authored paths. The tool composes nested translate/rotateXYZ unit-scale frames, updates the part and its recorded joint anchor atomically through the review boundary, and rejects invalid topology or non-rigid frame data before any USD edit.

For an AI- or human-led vehicle build, use model_authoring::model_context before choosing parts and readiness_report after the component contracts are composed. Use port_graph to inspect the standard USD endpoint surface and wiring_plan to produce one typed, generation-checked connection plan for Modelica/Rhai/physics endpoints. Use scene_recipe for the surrounding test scene and publish_component when a validated part is ready for explicit Save-As. These are dry Rhai facades; keep wheel/rover policy and dimensions in the owning Twin and send all USD operations through the existing journal path. See scripting-guide.md for the call sequence.

Working exemplars, simplest first: assets/vessels/rovers/skid_rover.usda (4-wheel skid), ackermann_rover.usda (steering), six_wheel_rover.usda (per-wheel port wiring + driveLaw variant), six_wheel_independent.usda (fully authored per-wheel mix), rocker_bogie.usda (linkage + gear-joint differential), rucheyok/ (Z-forward, Modelica electrical).

Reuse-first vehicle audit

Before authoring a new vehicle, identify the closest shipped assembly and read its component references, variant axes, composing scene, and runtime test. Use the existing assembly as the structural template and change only the authored vehicle facts: poses, dimensions, mass properties, topology, bindings, and parameters.

Classify the request before editing:

text
existing generic mechanism -> compose/configure it
missing vehicle asset       -> author USD assembly/components
missing equation            -> extend/reuse Modelica package
missing engine behavior     -> prove with a focused fixture before Rust
missing evidence            -> add an authored test and production run

Do not infer an engine gap from the absence of a mission-specific vehicle file. Do not use a tutorial or presentation-only vehicle as the production physics contract without checking its consumer and test.

The component library (assets/components/)

PartFileOwns
Wheel hubmobility/wheel.usdadimensions, mass, brake, contact, and solved shaft boundary — THE default set every wheel composes
Tiremobility/tires/*.usdagrip (physics:dynamicFriction, physxVehicleTire:longitudinalStiffness, physxVehicleTire:lateralStiffnessGraph, physxVehicleTire:restLoad) + look (wheel.wgsl inputs: tread lugs, relief, wear) — chosen via the wheel's tire variantSet
Suspensionmobility/suspensions/*.usdacompliance (lunco:suspension:restLength, physxVehicleSuspension:*) + strut visuals — ALL suspensions carry them: standard/rocker have the animated Casing/Piston/Spring trio (lunco:suspensionVisual:role), rigid a static casing only (zero travel ⇒ no roles)
Batterypower/battery.usdareusable physical/nameplate/electrical contribution; the rover-root collection composes it with loads and synthesizes one acausal network DAE
Ideal railpower/ideal_voltage_source.usdaauthored unlimited-power source for the infinite power variant; it is still compiled into the same electrical network
Motor / reduction / shaftmobility/motor.usda, mobility/gearbox.usda, mobility/avian_shaft.usdaModelica electrical and rotational equations plus the generic Avian mechanical boundary
Motor thermalthermal/motor_thermal.usdarover-agnostic thermal PARTS (MotorHeatLoad/MotorThermalMass/MotorRadiator); each rover authors its own Scope "Thermal" with one heat load per driven motor, compiled to its own DAE separate from the rover-root network — chosen via the rover's thermal variantSet
Chassismobility/chassis/box_chassis.usdacollider + panelised hull material (rover_hull.wgsl)
Headlightlights/headlight.usdaspotlight + casing + glowing lens, self-contained
Drive lawmobility/drive_laws/modelica_{skid,ackermann,six_independent}.usdaAuthored Modelica controller and generic drive/heading outputs
Drivetrain realizationmobility/physical_drivetrain.usdathe physical variant: articulation root + per-wheel revolute joints. The raycast variant is EMPTY — a raycast wheel is the absence of a joint. Wheel MOUNTS are never authored here: the wheel prim is the axle in both realizations, so it belongs to the rover, outside the variantSet.

Minimal rover

usda
def Xform "MyRover" (
    kind = "assembly"
    prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysxRigidBodyAPI",
        "PhysicsMassAPI", "PhysxVehicleContextAPI",
        "LunCoCatalogAPI"]
)
{
    uniform bool lunco:spawnable = true
    float physics:mass = 1000.0
    float3 physics:diagonalInertia = (1028, 1354, 341)   # author it — see skid_rover

    def "Controls" ( prepend references = @lunco://vessels/control_profiles.usda@</RoverControls> ) {}

    def Cube "Chassis" ( prepend references = @lunco://components/mobility/chassis/box_chassis.usda@</Chassis> ) {}

    def Cylinder "Wheel_FL" (
        prepend apiSchemas = ["PhysxVehicleWheelAttachmentAPI", "PhysxVehicleWheelAPI"]
        prepend references = [
            @lunco://components/mobility/wheel.usda@</Wheel>,
            @lunco://components/mobility/suspensions/standard.usda@</Suspension>,
        ]
        variants = { string tire = "regolith" }
    )
    {
        double3 xformOp:translate = (-1.0, -0.15, -1.225)
        uniform token[] xformOpOrder = ["xformOp:translate"]
        int physxVehicleWheelAttachment:index = 0
    }
    # …Wheel_FR/RL/RR: index 1/2/3, mirrored translates…
}
  • PhysxVehicleContextAPI on the root ⇒ MobilityRoot + OutputPorts + authored ports; MobilityRoot identifies the vehicle and OutputPorts indexes the generic command/output surface.
  • Vehicle motion policy is authored in the composed Modelica/Rhai controller. Skid, Ackermann, crab, and independent-wheel modes are programs that publish different named outputs; they are not Rust type dispatch.
  • Wheel→port wiring is a USD connection: each wheel connects float inputs:drive.connect and, where applicable, a heading-joint input to an authored float outputs:<port> on the controller/network boundary.

Wheel physics: one parameter set, two realizations

Both wheel kinds read the SAME attributes through ONE strict reader (lunco-usd-sim-authoring/src/wheel_params.rs). Only force generation differs:

  • raycast (default): analytical spring + traction force at the hub. Requires a composed suspension.
  • physical: authored PhysicsRevoluteJoint targeting the wheel via physics:body1 ⇒ rigid body + solved shaft torque boundary. That joint IS the switch — the drivetrain variantSet on the 4-wheel rovers just references the component that authors (or omits) the joints.

One authored mechanical network, so both realizations consume the same solve. DCMotor.mo solves winding current, back-EMF, electromagnetic torque, terminal voltage/current, and heat from its authored electrical pin and measured speed. Its solved torque crosses the authored generic Torque boundary into GearRatio.mo and AvianShaft.mo. The physical wheel applies that torque across its revolute joint; the raycast wheel uses the same solved torque in its contact-plane spin equation:

F_long = clamp(k_slip · (ω · radius − v_forward), −μN, +μN)
ω̇ = (τ_motor + τ_brake − F_long · radius − c_bearing · ω) / I

Speed is therefore determined by the authored motor, gearbox, complete wheel assembly inertia, and tire load, not by a second Rust motor curve or a copied no-load-speed clamp.

The motor speed input is connected to the engine's solved wheel speed, and its torque output is connected through the generic authored boundary. Both realizations consume that same solved network; no Rust motor or second shaft state mirrors it.

Strictness: every drivetrain/tire attr is required; a wheel missing any refuses to spawn and the error names ALL missing attrs. That now includes physxVehicleWheel:dampingRate (bearing + rolling drag): it is a physical property of the hub, so it is authored, never inferred from the drive torque — drive torque is not derived from unrelated values. physxVehicleWheel:moi is the complete authored tire-and-drivetrain assembly inertia; when omitted, the documented solid-cylinder derivation ½·m·r² applies. You never author them per vehicle — composing wheel.usda + a tire + (for raycast) a suspension is the complete set. If your wheel refuses to spawn, you dropped one of those three arcs.

Tuning: all wheel params carry schema-level slider hints, so every wheel gets Inspector sliders with zero per-asset authoring (SchemaRegistry::ui_hint → produce_usd_param_view; a per-asset authored customData still overrides — see author-usd-component).

To reach one wheel: select the rover, then Alt+Shift+click the wheel — that drills the Inspector to that subpart's own PRIM (crates/lunco-luncosim-edit-ui/src/selection.rs). Plain Shift+click is the multi-select extend and retains the existing selection; it does not drill. The drill also requires the rover to already be the primary selection.

Wheel, suspension, tire, and authored vehicle-control edits go ApplyUsdOp SetAttribute → document → in-place resync. UsdSimPlugin registers the vehicle wheel owner with lunco_usd_bevy_core::live_edit::UsdLiveEditRegistry; that owner claims the wheel, suspension, tire, and authored vehicle-control attributes and refreshes the live components from the composed stage, preserving the current entities and joints. Other edits that touch a rigid body, collider, or joint promote to a stage-wide reset so external joint endpoints are retired and admitted together. The physics owner removes graph edges before joint components and collider markers; a failed reset holds the active simulation and reports the owner error. Never poke WheelRaycast/RevoluteJoint components directly; the next document change would overwrite you.

Delivery order

Author the vehicle and its test in the owning Twin. Keep generic components and engine regression scenes in the shared LunCo asset library only when they are reusable beyond one mission or presentation. A scene-specific vehicle should reference the shared components rather than make the shared library depend on a one-off scene.

Build the smallest authored-controller, raycast rover path before adding power, thermal, autonomy, or a physical drivetrain. For a lunar presentation, start with the existing skid_rover on the shared lunar_surface base: it has the complete command surface and the least moving runtime parts. The first acceptance gate is scenes/tests/drivetrain_parity.usda: its Rhai scenario settles, drives both wheel realizations, and emits the real verdict DRIVETRAIN PARITY: PASS|FAIL. A rover that merely composes, or two rovers that are both stationary, do not pass.

Only after that gate passes, add one concern at a time:

  1. terrain/course and presentation cameras;
  2. the vehicle-specific assembly or rocker-bogie morphology;
  3. the authored Modelica drive law, proved by scenes/tests/modelica_drive_law.usda (MODELICA DRIVE LAW: PASS|FAIL proves the composed output surface and motion);
  4. battery, generation, thermal, then autonomy/story behaviour.

Do not combine these stages. A failed rover with a new terrain, Modelica model, and scenario has too many owners to diagnose; restore the last passing stage before adding the next one.

Coordinate contract for mounted mechanisms

For an antenna, camera gimbal, solar head, or other rover-mounted tracker, declare one coordinate contract before tuning: world axes, rover/mount local axes, joint positive axes and order, and the physical boresight. Derive the Modelica setpoint from that contract; never copy a -Z forward formula into a component whose geometry points along another axis. Validate the target vector, setpoint, measured joint angles, and rendered boresight together after a full scene reload.

For a fixed photovoltaic deck, there is no tracker controller to tune. Reference components/power/solar_panel.usda once, author its inputs:area and placement on the rover, use the component's +Y normal unless a different face is explicit, connect its connectors:p to the battery, and include both in the rover-root CollectionAPI:components collection with the driven loads. Keep the panel's visual frame and cell surface under that same mounted component; do not add a second rigid body or a disconnected visual proxy. A horizontal deck uses the component's +Y collecting face. Verify power_out, cos_incidence, battery current and soc_out, not only that a panel prim appears in the hierarchy.

Stability before tuning

If a lunar rover tips at launch, inspect the assembled load path before changing solver settings or adding visual smoothing. High-grip contact forces applied at the wheel plane create a real pitch moment when the authored physics:centerOfMass is high. The vehicle-level acceptance test should report travel, maximum tilt, detached descendants, and fixed-step sample count. A repeatable tilt failure is a geometry/mass/traction defect; a visual jitter with the body and its labels moving together is a coordinate/transform defect and needs composed transform inspection.

Show full SKILL.md (1,287 more words)Show less

Variant axes (orthogonal, each choosing a component)

Axes are opt-in per vehicle — a rover only has the axes its file declares. What is actually authored today:

RoverdrivetraindriveLawpowerthermal
skid_rover✅✅✅—
ackermann_rover✅✅——
six_wheel_rover—✅✅✅
six_wheel_independent—✅——
rocker_bogie—✅——

(tire is per-wheel, not per-vehicle — it is declared once on components/mobility/wheel.usda and every composed wheel has it. differential_rig.usda and rucheyok/ are not driveable vehicles and have no axes.) Adding a missing axis to a rover is a few lines of variantSet copied from an exemplar — that is the intended way to extend, not a Rust change.

  • drivetrain = raycast | physical — how wheels are realized physically. Authored on skid_rover and ackermann_rover. Switching it changes fidelity and cost, NOT how fast the rover goes: both realizations self-limit at the motor/gearbox axle no-load speed · radius (see Wheel physics above).
  • tire (per wheel) = regolith | hard | cleated | worn | bald — grip+look.
  • driveLaw = modelica | rhai — how throttle/steer become final drive and heading port values. Exists on ALL driveable rovers; one authored controller program owns the mapping for its vehicle:
    • drive_laws/modelica_skid.usda (skid_rover, six_wheel_rover, rocker_bogie): RoverDrivetrain.mo integrates a per-side motor lag on the solver clock; native USD connections publish drive_left/drive_right.
    • drive_laws/modelica_ackermann.usda (ackermann_rover): RoverAckermannDrivetrain.mo publishes the front wheel heading outputs and the drive outputs consumed by the raycast or physical realization.
    • drive_laws/modelica_six_independent.usda (six_wheel_independent): the SAME RoverDrivetrain.mo (the law is per-side; fan-out is wiring, not physics) with a bridge writing drive_w0..w2 = left, drive_w3..w5 = right. Allocation ownership is the composed controller's complete authored output wiring. A partial or missing controller contract is an authoring error; it is not replaced by a second controller. The whole law is USD + .mo + .rhai — no sentinel hook or type-specific Rust path. Wheels stay port-name-agnostic throughout: each listens to its lunco:drivePort (or the index-parity default, even ⇒ drive_left / odd ⇒ drive_right); a drive law is a VEHICLE-level component that writes those ports by name.
  • power = infinite | battery — does driving cost anything. infinite is an EMPTY variant (absence of a battery = today's drive-forever default); battery references reusable battery and motor parts, authors their connector topology in the rover file, and lists the actual part paths in a standard CollectionAPI:components on the rover root. Runtime projects that collection as one acausal electrical DAE, with drive commands entering as scalar domain-boundary inputs. Brownout and current limiting are equations and therefore belong in the projected Modelica island. Production Rhai must never scale drive ports per tick.
  • thermal = none | basic — do the motors have temperatures. none is EMPTY; basic authors a Scope "Thermal" with its own CollectionAPI:components, compiled to a SEPARATE generated DAE from rover-root network. Each driven motor gets one MotorHeatLoad (from thermal/motor_thermal.usda); the motor's solved outputs:heat crosses into the thermal island as a causal inputs:motor_heat_* boundary wire (a runtime SimConnection). The acausal connectors:port edges stay inside the thermal collection (heat balance per bank). This compiles and publishes motor_temp_left/motor_temp_right (K) REGARDLESS of the power variant — thermal is decoupled from electrical. See docs/architecture/34-scenario-and-multidomain.md. Exemplar: rocker_bogie (6 motors), skid_rover (4), six_wheel_rover (6).

Looks

Colour is primvars:displayColor, always — the shader CONSUMES it. One authored attribute, in the standard USD place, whether the part renders through plain PBR or through a shader. rover_hull.wgsl declares //!@engine display_color and the engine fills it from the prim's composed primvars:displayColor (element 0 — it is a color3f[] ARRAY by schema). Restyle a rover, or a difficulty tier, by overriding that one attribute:

usda
over "Chassis" { color3f[] primvars:displayColor = [(0.30, 0.72, 0.35)] }

Shader inputs: are for what displayColor cannot say — accent_color, panel_scale, wear, and dust_amount where the owning shader defines it. Authoring inputs:display_color explicitly still wins over the engine fill, but you rarely want that; it hides the colour from every other tool that reads USD.

Tire look lives on the tire component (wheel.wgsl inputs tread_lugs, lug_depth, wear) — a tire that grips differently should LOOK different in the same file. Tires author their colours as shader inputs: deliberately; that is unchanged.

Verify

For iterative modeling, keep one luncosim process running with an explicit --api PORT and use that API. Edit a component through the focused Editor preview with assembly_edit/assembly_builder; the document owner journals the change and the dependency-scoped projection refreshes mounted references in place, preserving the current camera and selection. Wait for the matching projected generation, query the affected composed paths, capture the focused view, and re-run the Rhai observer with RunScenario before saving.

RestartScene is reserved for an explicit scene-lifecycle test or a Rust binary rebuild. Never use it as the normal response to a component edit, and never emulate refresh by manually respawning a visual subtree. If a referenced component fails to refresh, inspect the document/preview generations and the projection diagnostics; report the dependency or capability error instead of adding a second writer or a restart fallback.

1. Pre-flight, before launching anything — composes the whole reference closure and runs the same strict wheel reader the spawner uses, so a missing attribute is named in seconds rather than at spawn time (validate-assets):

bash
"$LUNCOSIM_BIN" --validate assets/vessels/rovers/my_rover.usda

2. Drivetrain parity regression — the guard that the two realizations stay matched. assets/scenes/tests/drivetrain_parity.usda instantiates skid_rover twice side by side (drivetrain = "raycast" at x = −25, "physical" at x = +25) and auto-runs assets/scenarios/tests/drivetrain_parity.rhai: settle 3 s → full throttle straight 12 s → throttle + steer 6 s.

bash
"$LUNCOSIM_BIN" --api 4101 --scene scenes/tests/drivetrain_parity.usda 2>&1 | tee target/parity.log
grep -E 'DRIVETRAIN PARITY|PARITY FAIL' target/parity.log

It asserts terminal speed ±15 %, peak speed ±15 %, distance ±20 %, yaw magnitude ±35 % with a strict sign check, and that both land in [2.4, 6.0] m/s — the absolute band around the authored ω_max · r ≈ 4.8. Both-near-zero is a FAIL, not a pass. It emits no exit code — the verdict is the last stdout line DRIVETRAIN PARITY: PASS|FAIL, so grep for it; a green-looking run that never printed the line means the scenario never reached its verdict.

Run this after ANY change to wheel params, the authored motor network, or wheel.usda defaults — it is the only thing that catches the two realizations drifting apart.

3. Interactive — spawn from the palette (folder = category; needs lunco:spawnable on the defaultPrim, see use-asset-library), possess, drive (test-via-api): throttle ⇒ position delta; steer ⇒ heading change; both drivetrain variants. QueryEntity a wheel prim ⇒ canonical attrs resolved. Watch the log: wheel refusals and resyncs are loud by design. For a raycast wheel that rests on the chassis, inspect QueryPhysicsState on its MobilityRoot: the wheel_contacts entries report the actual hit, owner, ray origin, and distance. Carrier resolution uses the same stage path and instance root while excluding UsdPreviewOnly descendants; same-path preview entities must never own a mounted wheel's support ray.

Anti-patterns

  • ❌ Duplicating motor/gearbox torque or speed on a wheel — tune the composed motor and gearbox parts; wheel-local lunco: fields are only for wheel mechanics such as steering axis and drive damping.
  • ❌ Restating component defaults in the assembly (radius 0.4, axis "X", displayColor) — delete; composition provides them.
  • ❌ A variant that inlines prims instead of referencing a component.
  • ❌ Editing wheel components in ECS/Rust for "live tuning" — the document is the only writer; use the Inspector sliders or ApplyUsdOp.
  • ❌ Hand-writing a wheel PhysicsRevoluteJoint outside a drivetrain component — that joint is the raycast/physical discriminator; keep wheel hinges in the variant arc. Generic revolute mechanisms (antenna, solar tracker, arm) are allowed: their body1 is not a PhysxVehicleWheelAPI, so they must not alter drivetrain admission or articulation classification. A generic mechanism owns its own hinges and is composed as a root overlay onto the vehicle body; do not re-author its hinge in the rover file.
  • ❌ Expecting plain Shift+click to drill into a wheel — it extends the multi-selection. Alt+Shift+click drills.
  • ❌ Adding a second name for a quantity that already exists — one authoritative motor/gearbox reduction, one reader, one place to change it.
  • ❌ Overriding a shader inputs: to repaint a rover — author primvars:displayColor; rover_hull.wgsl consumes it via //!@engine display_color (use-asset-library).
  • ❌ Changing wheel physics without re-running the drivetrain parity scene — the two realizations drift silently otherwise.
  • ❌ Assuming every rover has every variant axis — check the table above; most have only driveLaw.
  • ❌ Creating a new rover assembly before reading the nearest shipped exemplar, its composing scene, and its behavior test.

© LunCoSim, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/build-vehicle of LunCoSim/lunco-sim.

Open the folder on GitHubat commit 43f1301

Compare with similar skills

Build Vehicle next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Build Vehicle compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Build Vehicle this skillLunCoSim/lunco-sim107—~6.7kAutomated safety check: PassApache-2.0
UI/UX Design System AdvisorGalaxy-Dawn/claude-scholar5.7k1 repos~1.1kAutomated safety check: PassMIT
Extract DesignManavarya09/design-extract4.2k—~786Automated safety check: NotesMIT
Color Auditrome-os/rome748—~2.7kAutomated safety check: PassMIT
Material Design 3 UI/UX Guideskydashnet/material-design-3-ui-skill138—~3kAutomated safety check: PassMIT
Worklog Designregisx001/Worklog261—~3.3kAutomated safety check: PassMIT

Similar skills

  • UI/UX Design System Advisor

    Galaxy-Dawn/claude-scholar

    Turns a vague UI request into a concrete design system with style, palette, typography and layout guidance from a search script, plus stack-specific implementation advice.

    5.7k GitHub starsUsed in 1 repo~1.1k tokens
    Frontend & DesignAuto-check passed
  • Extract Design

    Manavarya09/design-extract

    Extract the full design language from any website URL. An agent skill from Manavarya09/design-extract.

    4.2k GitHub stars~786 tokensUpdated 2 days ago
    Frontend & DesignAuto-check: notes
  • Color Audit

    rome-os/rome

    Audit a design system's color palette against measurable color-science disciplines — WCAG/APCA contrast of declared token pairs, perceptual (OKLCH) ramp uniformity, color-blindness safety of…

    748 GitHub stars~2.7k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Material Design 3 UI/UX Guide

    skydashnet/material-design-3-ui-skill

    Guides designing, reviewing or implementing interfaces that follow Google's Material Design 3 system: semantic tokens, component states, adaptive layout and accessibility.

    138 GitHub stars~3k tokensUpdated 10 days ago
    Frontend & DesignAuto-check passed
  • Worklog Design

    regisx001/Worklog

    Design and UI skill for the Worklog desktop project manager.

    261 GitHub stars~3.3k tokensUpdated 1 mo ago
    Frontend & DesignAuto-check passed
  • UI Component Spec Designer

    plugin87/ux-ui-agent-skills

    Writes a complete UI component spec with anatomy, variants, sizes, eight interaction states, design-token mapping and accessibility notes before or alongside code.

    1.6k GitHub stars~2.8k tokensUpdated today
    Frontend & DesignAuto-check passed

More from LunCoSim/lunco-sim

All 40 skills in this repo
  • Nightly Changelog

    LunCoSim/lunco-sim

    Generate concise LunCoSim nightly GitHub release notes with platform downloads, installation guidance, an AI-agent mission prompt, and a changelog link.

    107 GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Build or repair a reusable scene component through a live LunCoSim Editor session.

    107 GitHub stars~4.4k tokensUpdated today
    Auto-check passed
  • Assembly Quality

    LunCoSim/lunco-sim

    Build or review a componentized LunCoSim USD assembly with a realistic, dimensionally checkable presentation.

    107 GitHub stars~1.6k tokensUpdated today
    Auto-check passed
  • Author Rhai Tests

    LunCoSim/lunco-sim

    Author and review LunCoSim behavioral, asset-backed, component, mission, visual, and requirements-verification tests.

    107 GitHub stars~3.5k tokensUpdated today
    Auto-check passed
  • Author Rhai Tool

    LunCoSim/lunco-sim

    Create, extend, register, or debug a reusable LunCoSim Rhai tool library for live USD authoring, component linting, inspection, or test support.

    107 GitHub stars~5.2k tokensUpdated today
    Auto-check passed
  • Author Tutorial

    LunCoSim/lunco-sim

    Author an interactive tutorial, guided lesson, onboarding flow, coach-mark tour, or objectives checklist in LunCoSim.

    107 GitHub stars~1.4k tokensUpdated today
    Auto-check passed

Works with

Questions about Build Vehicle

What does Build Vehicle do?

How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws…. Build Vehicle is an agent skill from LunCoSim/lunco-sim. How to BUILD A VEHICLE (rover, hauler, wheeled anything) for LunCoSim out of the mobility component library — assembly root, wheels, tires, suspensions, chassis, lights, variant axes, drive laws, and live parameter tuning.

When should I use Build Vehicle?

Build Vehicle fits situations like: the user asks to make/build a rover; give it different wheels/tires; swap the drivetrain; tune wheel physics.

How do I install Build Vehicle in Claude Code?

Run `npx skills add LunCoSim/lunco-sim --skill build-vehicle -a claude-code`. Or copy the skill folder (skills/build-vehicle in LunCoSim/lunco-sim) into .claude/skills/build-vehicle in your project. Claude Code loads it when a task matches its description.

How do I install Build Vehicle in Codex?

Run `npx skills add LunCoSim/lunco-sim --skill build-vehicle -a codex`. Or copy the skill folder (skills/build-vehicle in LunCoSim/lunco-sim) into .agents/skills/build-vehicle in your project. Codex loads it when a task matches its description.

Can I use Build Vehicle in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add LunCoSim/lunco-sim --skill build-vehicle -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/build-vehicle, .gemini/skills/build-vehicle, .github/skills/build-vehicle and .opencode/skills/build-vehicle in your project.

What does Build Vehicle need to run?

Going by SKILL.md and its folder, Build Vehicle needs the command-line tools its instructions call (kind).

Does Build Vehicle access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Build Vehicle safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Build Vehicle use?

Build Vehicle is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Build Vehicle use?

About 6.7k tokens (SKILL.md is roughly 27k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Build Vehicle?

Skills that share tags, products or a category with Build Vehicle: UI/UX Design System Advisor (Galaxy-Dawn/claude-scholar, 5.7k stars), Extract Design (Manavarya09/design-extract, 4.2k stars), Color Audit (rome-os/rome, 748 stars) and Material Design 3 UI/UX Guide (skydashnet/material-design-3-ui-skill, 138 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Build Vehicle?

LunCoSim (a GitHub organization) maintains it in LunCoSim/lunco-sim, which has 107 GitHub stars. The repository holds 40 skills in this directory. The repository was last updated on October 10, 2026.

Source: LunCoSim/lunco-sim on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.