Skip to main content

Understanding Scripts in Bitbybit Projects

What is a script?​

A script is one program inside a project. Each is written in one editor, chosen when the script is made:

  1. Rete scripts connect nodes in a visual graph.
  2. Blockly scripts snap blocks together.
  3. TypeScript scripts are code, written in the Monaco editor with IntelliSense over the whole API.
  4. Designer scripts hold a whole design, its parts and assemblies, edited in the Designer, which is part of the Gold plan.
A cloud project's scripts, a TypeScript one and a Rete one, each with its editor, when it was edited, and Open

Who can open a script​

A script has no visibility of its own: it shares its project's. Every script of a public project is public, and every script of a private project is private. A script may have a cover image of its own, which shows what it makes.

Scripts that work together​

One project can hold scripts of every editor, so each part of the work can use the editor that suits it. The project below does that:

  1. Model the geometry (Rete). One script draws the detailed spaceship, another a simpler body for physics.
  2. Export the models. Both are exported as glTF files.
  3. Add them to the project. The glTF files are added to the project's Files.
  4. Bring them to life (TypeScript). Two scripts load the files: one animates the ship, the other drops dozens of them with physics.

These are the scripts' previews; each opens in its editor on bitbybit.dev from the link below it.


1. The visible geometry (Rete)

Bitbybit Platform

The spaceship's visible geometry, drawn in Rete

Open it in the Rete editor


2. The simplified collision body (Rete)

Bitbybit Platform

The spaceship's collision body, drawn in Rete

Open it in the Rete editor


3. The animation (TypeScript)

Bitbybit Platform

The spaceship animated in TypeScript

Open it in the TypeScript editor


4. The physics simulation (TypeScript)

Bitbybit Platform

Spaceships falling with physics, in TypeScript

Open it in the TypeScript editor

The physics script's code:

const scene = bitbybit.babylon.scene.getScene();

scene.activeCamera.position = new BABYLON.Vector3(-40, 10, -40)


const files = [
"alien-nebula-cruiser-1.glb",
"alien-nebula-collision-body-1.glb",
]

const gltfFiles = await Promise.all(files.map(fileName => bitbybit.asset.getFile({ fileName })));
const meshes = await Promise.all(gltfFiles.map(assetFile => bitbybit.babylon.io.loadAssetIntoScene({ assetFile, hidden: true })));
const meshSpaceship = meshes[0];
meshSpaceship.position = new BABYLON.Vector3(0, 50, 0);

const meshSpadceshipCollisionBody = meshes[1];
const collisionBody = meshSpadceshipCollisionBody.getChildMeshes().find((m) => m.name.includes("surface")) as BABYLON.Mesh;
collisionBody.position = new BABYLON.Vector3(0, 50, 0);
collisionBody.isVisible = false;
const groundMesh = await createBox();
const groundCollisionMesh = groundMesh.getChildMeshes().find((m) => m.name.includes("surface")) as BABYLON.Mesh;

bitbybit.babylon.scene.enablePhysics({ vector: [0, -9.81, 0] });

const size = 20;
const step = 20;
for (let x = -size; x <= size; x += step) {
for (let y = -size; y < size * 4; y += step) {
for (let z = -size; z <= size; z += step) {
const parentMesh = new BABYLON.Mesh(`${x}-${y}-${z}`, scene);
meshSpaceship.getChildMeshes().forEach((mesh: BABYLON.Mesh) => {
if (mesh.name !== "__root__") {
const inst = mesh.createInstance(`${x}-${y}-${z}-instance`);
inst.parent = parentMesh;
}
});

parentMesh.position = new BABYLON.Vector3(x, y + (size * 2), z);
const collisionBodyMesh = collisionBody.clone(`${x}-${y}-${z}-collision`);
new BABYLON.PhysicsAggregate(parentMesh, BABYLON.PhysicsShapeType.MESH, { mesh: collisionBodyMesh, mass: 3.75, restitution: 0.75 }, scene);
}
}
}

new BABYLON.PhysicsAggregate(groundMesh, BABYLON.PhysicsShapeType.MESH, { mesh: groundCollisionMesh, mass: 0, restitution: 0.75 }, scene);
meshSpaceship.getChildMeshes().forEach(m => m.isVisible = false);
const lightOpt = new Bit.Inputs.BabylonScene.DirectionalLightDto();
lightOpt.direction = [-100, -500, -100];
lightOpt.shadowGeneratorMapSize = 2056;
bitbybit.babylon.scene.drawDirectionalLight(lightOpt)

async function createBox() {

const box = await bitbybit.occt.shapes.solid.createBox({
width: 100,
length: 100,
height: 30,
center: [0, 13, 0],
})

const boxCutout = await bitbybit.occt.shapes.solid.createBox({
width: 90,
length: 90,
height: 30,
center: [0, 15, 0],
})

const diff = await bitbybit.occt.booleans.difference({
shape: box,
shapes: [boxCutout],
keepEdges: false
})

const boxDrawOptions = new Bit.Inputs.Draw.DrawOcctShapeOptions();
boxDrawOptions.precision = 0.1;
boxDrawOptions.faceColour = "#ff00ff";
const boxMesh = await bitbybit.draw.drawAnyAsync({
entity: diff,
options: boxDrawOptions
})

return boxMesh

}

Verified against the product in October 2026