A text view of your model — perfect for assignments, transferring models, or working with AI.
Give an AI the format guide and a plain-language description of the truss you want, and it hands back JSON you can drop straight into Truzme.
Example prompt:
Use this format guide: https://www.truzme.com/project-code-llms.txt Design a Warren truss for me. 10 m wide, 2 m tall. 10 kN nodal loads pointing downward on the top chord.
To write your own prompt, start it with the format guide's link:
You can also hand the AI a truss you've already built, instead of designing from scratch: click Copy on the Project code panel, paste it into the chat alongside the format guide, and describe what you want changed — e.g. "redesign this truss so no member buckles under the given load". Copy its reply back into the panel and click Apply, same as above.
Project code also works with no AI involved at all — it's just your model as text, so it's a simple way for a teacher to hand every student the same starting truss through whatever Learning Management System (Canvas, Moodle, Google Classroom, …) the class already uses.
Setting up an assignment (teacher). Build the starting truss in Truzme — or just set up the materials and sections you want students to use, with no members yet — open the Project code panel, click Copy, and paste the result into the assignment you post for your class.
Loading an assignment (student). Copy the code from your assignment, open Truzme's Project code panel — the code icon in the top-right corner — clear the existing text with the trash icon, paste the code with the clipboard icon (or Ctrl+V), and click Apply. Your assignment's starting truss appears on the canvas exactly as your teacher set it up.
Both use cases above rely on the same underlying idea. Project code is a plain-text, JSON view of your model. Open it from the code icon in the top-right corner. It only shows the parts that describe the structure itself — nodes, members, supports, loads, materials, sections — using small integer ids you can read and edit by hand. Display settings, background images, and asset files stay out of it, so what you see is just the structure and nothing else.
Copy the text out to edit by hand, hand it to an AI, or paste in a code someone else gave you, then press Apply. Truzme validates it, converts it back into the model, and re-renders.
Truzme checks the pasted text before touching your model. If something's wrong — a typo, a reference to a node that doesn't exist — Apply stays disabled and the problem is shown under the text in plain language, e.g. "member 3 references node 9, which doesn't exist".
The document is one JSON object with these keys: units, nodes, members, supports, nodalLoads, materials,
sections, and an optional dimensions. Nothing else is allowed — Truzme keeps more than this behind the scenes
(view settings, background images, uploaded assets), but none of that appears here.
Writing AI prompts with your own instructions, for a course or a research study? Link the format itself. Unlike the format guide above, it has no instructions for the AI — only a description of every field below:
idEvery entity has a small integer id. Anything that points to another entity — a member's endpoints, a support's or
load's node, the section and material assigned to a member — does so with that id. Ids only need to be unique
within their own array, so a node id: 1 and a section id: 1 don't collide.
unitsEvery category the document uses, all required:
length — node coordinates: m, cm, mm, ft, insectionLength — section dimensions: mm, cm, inforce — loads: kN, N, kg, kip, lbfmaterialStrength — modulus and strength: MPa, N/mm², GPa, ksi, psiarea — section area and, indirectly, its moment of inertia: mm², cm², in², ft²density — material density: kg/m³, lb/ft³This block is authoritative on import: Apply reads the units declared here — not whatever Truzme is currently
displaying — and converts every number accordingly. length and sectionLength are different categories on
purpose: a node coordinate and a section dimension are rarely the same scale.
nodes{ id, x, y } — x/y are coordinates in units.length. x increases to the right, y increases upward —
the standard math convention, not screen coordinates. A node above and to the right of the origin has positive x
and positive y.
members{ id, from, to, section, material } — from/to are node ids for the member's two ends; section/material are
ids into the sections/materials arrays.
supports{ id, node, x, y } — node is the restrained node's id; x/y are booleans, true meaning translation is fixed
in that direction.
nodalLoads{ id, node, x, y, mode } — node is the id of the loaded node; x/y are signed force components in
units.force. mode is optional and only changes how the arrow is drawn, not the analysis. Leave it out for "push",
where the arrow points at the node. Use "pull" for a load hanging from the truss, e.g. on a bottom chord node: the
arrow then starts at the node and points away, so it isn't drawn across the members.
materials{ id, name, EModulus, fMax, density, color } — modulus and max stress, both in units.materialStrength; density in
units.density. color is optional (a hex string, e.g. "#1D4ED8") — leave it out and an existing material keeps
its current color, a new one gets a default. Include it to set or change a material's color.
materials and sections can't be empty arrays — every model needs at least one of each, even one with no members
yet. Apply rejects a paste that has none of either.
sections — a union of five shapesEvery section has id, name, sectionType (which decides which other fields are required), and an optional
color — same rule as a material's color: leave it out to keep whatever a matching id already has, include it to
set one.
solid_round — d (diameter)pipe — outerDiameter, thicknessrectangle — w, hhollow_rectangle — w, h, thicknesscustom — area, Imin (nothing to derive these from, so they're given directly)All dimensions are in units.sectionLength; area and Imin on a custom section are in units.area and its
matching inertia unit (mm² area → mm⁴ inertia, in² → in⁴, and so on).
For the four standard shapes, Truzme computes area and Imin on import from the input dimensions — you only ever
provide those dimensions, never the derived values, so there's one source of truth. The exported text doesn't show
computed area or inertia for standard shapes; check the Utilization panel in Truzme for those.
dimensions — optionalThe measurement lines you draw with the Dimension tool (not to be confused with a section's own w/h/d
dimensions above). It's optional because most edits have nothing to do with dimension lines — leaving the whole key
out means "don't touch them," so a document that was never written with dimension lines in mind can't accidentally
erase the ones you already placed.
{ id, from, to, kind, anchor } — from/to are node ids, same convention as a member's from/to. kind is
"horizontal", "vertical", or "angle". anchor is a point ({ x, y }, in units.length) the line is drawn
through — it's the point you click when placing a dimension with the tool.
Leaving dimensions out of the document keeps your existing dimension lines untouched. Including it — even as an
empty array — replaces them with whatever's listed, matched by id like every other entity. When you ask an AI for
a design with a specific span or height, it's worth asking it to add a dimension line confirming that measurement —
the format guide tells it to do this on its own whenever a prompt states one.
Your display preferences (not to be confused with the units block above, which is part of the public document),
background images, uploaded asset files, and Truzme's internal bookkeeping don't appear here — none of it describes
the structure, so none of it needs to go through an AI.
A three-node, three-member truss: a pin support and a roller, one downward load at the apex, a custom color on the material and section, and a dimension line confirming the 4 m base span.
{
"units": {
"length": "m",
"sectionLength": "mm",
"force": "kN",
"materialStrength": "MPa",
"area": "mm²",
"density": "kg/m³"
},
"nodes": [
{ "id": 1, "x": 0, "y": 0 },
{ "id": 2, "x": 4, "y": 0 },
{ "id": 3, "x": 2, "y": 3 }
],
"members": [
{ "id": 1, "from": 1, "to": 2, "section": 1, "material": 1 },
{ "id": 2, "from": 1, "to": 3, "section": 1, "material": 1 },
{ "id": 3, "from": 2, "to": 3, "section": 1, "material": 1 }
],
"supports": [
{ "id": 1, "node": 1, "x": true, "y": true },
{ "id": 2, "node": 2, "x": false, "y": true }
],
"nodalLoads": [{ "id": 1, "node": 3, "x": 0, "y": -10 }],
"materials": [{ "id": 1, "name": "Steel", "EModulus": 210000, "fMax": 235, "density": 7850, "color": "#1D4ED8" }],
"sections": [
{
"id": 1,
"name": "40×40×3",
"sectionType": "hollow_rectangle",
"w": 40,
"h": 40,
"thickness": 3,
"color": "#7C3AED"
}
],
"dimensions": [{ "id": 1, "from": 1, "to": 2, "kind": "horizontal", "anchor": { "x": 2, "y": -0.75 } }]
}color and dimensions are both optional — see the schema reference above if you want to leave them out.
Ask an AI to move node 3, add a fourth node, or swap the section on member 2 — it only has to keep ids consistent and never invent an id that isn't defined.
Validation. Every Apply is checked against the schema first. An invalid document leaves your model and the text untouched — nothing is applied halfway, and the errors below the text say exactly what's wrong.
Apply replaces the structure. Apply always replaces nodes, members, supports, nodalLoads, materials,
and sections with whatever's in the pasted document. dimensions is the one exception, because it's optional:
leave the key out and your existing dimension lines are left exactly as they are; include it — even as [] — and
they're replaced along with everything else. Your current view settings, background images, and asset files are
always left exactly as they were.
Ids are matched, not reassigned. An id that already existed in your model keeps the same entity across the round-trip — its place in undo history, its selection state, and its color unless the pasted entity sets a new one. Only ids you didn't have before get created as new entities. This is why an AI editing your project code should keep existing ids stable and only introduce new ones for things it's actually adding.
Units convert automatically. The numbers you paste are read in whatever units the pasted units block declares,
then converted to Truzme's internal representation — you don't need to match your current display units before
pasting.
Project code was developed in collaboration with a research team at Penn State University, USA, who needed a text format an AI could read and write — so a truss design could be generated and revised in a chat and then loaded straight back into Truzme.
See Who uses Truzme for more about their work with Truzme.
Thanks to Ali Tarlani Beris for starting the conversation.