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.
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…
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ 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-srcUse ~/.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/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .claude/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicleType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/build-vehicle .agents/skills/build-vehicle && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .agents/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/build-vehicle .cursor/skills/build-vehicle && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .cursor/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/LunCoSim/lunco-sim.git --path skills/build-vehicle--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/build-vehicle .gemini/skills/build-vehicle && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .gemini/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install LunCoSim/lunco-sim build-vehicleInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/build-vehicle .github/skills/build-vehicle && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .github/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add LunCoSim/lunco-sim --skill build-vehicle -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install LunCoSim/lunco-sim build-vehicle --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LunCoSim/lunco-sim.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/build-vehicle .opencode/skills/build-vehicle && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "build-vehicle" agent skill from https://github.com/LunCoSim/lunco-sim/tree/main/skills/build-vehicle into .opencode/skills/build-vehicle/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "build-vehicle", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
build-vehicleHow 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. 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.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 43f1301. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
kindFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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.
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.
The full file from LunCoSim/lunco-sim at commit 43f1301, republished under its Apache-2.0 licence (© LunCoSim). 3,045 words, ~6,728 tokens.
.claude/skills/build-vehicle/SKILL.md (or your agent's skills folder).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).
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:
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 runDo 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.
assets/components/)| Part | File | Owns |
|---|---|---|
| Wheel hub | mobility/wheel.usda | dimensions, mass, brake, contact, and solved shaft boundary — THE default set every wheel composes |
| Tire | mobility/tires/*.usda | grip (physics:dynamicFriction, physxVehicleTire:longitudinalStiffness, physxVehicleTire:lateralStiffnessGraph, physxVehicleTire:restLoad) + look (wheel.wgsl inputs: tread lugs, relief, wear) — chosen via the wheel's tire variantSet |
| Suspension | mobility/suspensions/*.usda | compliance (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) |
| Battery | power/battery.usda | reusable physical/nameplate/electrical contribution; the rover-root collection composes it with loads and synthesizes one acausal network DAE |
| Ideal rail | power/ideal_voltage_source.usda | authored unlimited-power source for the infinite power variant; it is still compiled into the same electrical network |
| Motor / reduction / shaft | mobility/motor.usda, mobility/gearbox.usda, mobility/avian_shaft.usda | Modelica electrical and rotational equations plus the generic Avian mechanical boundary |
| Motor thermal | thermal/motor_thermal.usda | rover-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 |
| Chassis | mobility/chassis/box_chassis.usda | collider + panelised hull material (rover_hull.wgsl) |
| Headlight | lights/headlight.usda | spotlight + casing + glowing lens, self-contained |
| Drive law | mobility/drive_laws/modelica_{skid,ackermann,six_independent}.usda | Authored Modelica controller and generic drive/heading outputs |
| Drivetrain realization | mobility/physical_drivetrain.usda | the 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. |
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.float inputs:drive.connect and, where applicable, a heading-joint input to
an authored float outputs:<port> on the controller/network boundary.Both wheel kinds read the SAME attributes through ONE strict reader
(lunco-usd-sim-authoring/src/wheel_params.rs). Only force generation differs:
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 · ω) / ISpeed 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.
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:
scenes/tests/modelica_drive_law.usda
(MODELICA DRIVE LAW: PASS|FAIL proves the composed output surface and motion);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.
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.
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.
Axes are opt-in per vehicle — a rover only has the axes its file declares. What is actually authored today:
| Rover | drivetrain | driveLaw | power | thermal |
|---|---|---|---|---|
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).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:
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.
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):
"$LUNCOSIM_BIN" --validate assets/vessels/rovers/my_rover.usda2. 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.
"$LUNCOSIM_BIN" --api 4101 --scene scenes/tests/drivetrain_parity.usda 2>&1 | tee target/parity.log
grep -E 'DRIVETRAIN PARITY|PARITY FAIL' target/parity.logIt 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.
lunco: fields are only for wheel
mechanics such as steering axis and drive damping.ApplyUsdOp.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.inputs: to repaint a rover — author
primvars:displayColor; rover_hull.wgsl consumes it via //!@engine display_color (use-asset-library).driveLaw.© 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
Just SKILL.md in skills/build-vehicle of LunCoSim/lunco-sim.
Open the folder on GitHubat commit 43f1301
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Build Vehicle this skillLunCoSim/lunco-sim | 107 | — | ~6.7k | Automated safety check: Pass | Apache-2.0 | |
| UI/UX Design System AdvisorGalaxy-Dawn/claude-scholar | 5.7k | 1 repos | ~1.1k | Automated safety check: Pass | MIT | |
| Extract DesignManavarya09/design-extract | 4.2k | — | ~786 | Automated safety check: Notes | MIT | |
| Color Auditrome-os/rome | 748 | — | ~2.7k | Automated safety check: Pass | MIT | |
| Material Design 3 UI/UX Guideskydashnet/material-design-3-ui-skill | 138 | — | ~3k | Automated safety check: Pass | MIT | |
| Worklog Designregisx001/Worklog | 261 | — | ~3.3k | Automated safety check: Pass | MIT |
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.
Manavarya09/design-extract
Extract the full design language from any website URL. An agent skill from Manavarya09/design-extract.
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…
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.
regisx001/Worklog
Design and UI skill for the Worklog desktop project manager.
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.
LunCoSim/lunco-sim
Generate concise LunCoSim nightly GitHub release notes with platform downloads, installation guidance, an AI-agent mission prompt, and a changelog link.
LunCoSim/lunco-sim
Build or repair a reusable scene component through a live LunCoSim Editor session.
LunCoSim/lunco-sim
Build or review a componentized LunCoSim USD assembly with a realistic, dimensionally checkable presentation.
LunCoSim/lunco-sim
Author and review LunCoSim behavioral, asset-backed, component, mission, visual, and requirements-verification tests.
LunCoSim/lunco-sim
Create, extend, register, or debug a reusable LunCoSim Rhai tool library for live USD authoring, component linting, inspection, or test support.
LunCoSim/lunco-sim
Author an interactive tutorial, guided lesson, onboarding flow, coach-mark tour, or objectives checklist in LunCoSim.
Works with
Categories
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.
Build Vehicle fits situations like: the user asks to make/build a rover; give it different wheels/tires; swap the drivetrain; tune wheel physics.
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.
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.
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.
Going by SKILL.md and its folder, Build Vehicle needs the command-line tools its instructions call (kind).
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.
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.
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.
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.
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.
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.