👀 Are you curious how we develop semio? Then you might want to check out our Discord server 👥
🧩 Design-Information-Modeling for Kit-of-Parts Architecture 🏘️
You want to 🧩 the next 🏘️🏛️🏢🏭🏫🏨⛪🕌 with 🤖? But 📐🔢🗣️👥🖱️⌨️ takes all your ⌚? Then try to 🧠 the 🧬 and let semio 💉🖥️✒️🖨️🪄🚀.
Note
Are you a user of semio? Then you probably want to visit our docs 👀
Glad to see you!
Let me walk you through 🚶
🛍️ Products ↑
Do you wonder how semio is interopable? The reason are shared specification, ecosystems and components 🪢
✏️ sketchpad ↑
sketchpad is a simple-to-use, accessible and browser-based user interface for semio🖱️
👀 studio ↑
A studio is a synchronous collaboriation environment for teams to work together in semio 🤝
☁️ cloud ↑
Use any file-hosting platform as an asynchronous Common-Data-Environment 📁
🤖 assistant ↑
The assistant helps you on every step in the design process with semio ✍️
A batteries-included Grasshopper plugin for semio ⚡
🦏 semio.3dm ↑
A Grasshopper-based integration of Rhino and semio 🔀
🐝 semio.wasp ↑
A Grasshopper-based integration of Wasp and semio 🔀
🦌 semio.monoceros ↑
A Grasshopper-based integration of Monoceros and semio 🔀
🐞 semio.ladybug ↑
A Grasshopper-based integration of Ladybug and semio 🔀
📄 Specs ↑
📦 Kit ↑
A kit
is a collection of types
and designs
📦
A kit
is either static (a special .zip
file) or dynamic (bound to a runtime) 📦
A static kit
contains a reserved .semio
folder that contains a kit.db
sqlite file 💾
The SQL-schema of kit.db
is found in ./sqlite/schema.sql
📄
For Inter-Process-Communication (IPC) the JSON-schema in ./jsonschema/kit.json
is used 📄
🏙️ Design ↑
A design
is an undirected graph of pieces
(nodes) and connections
(edges) 📐
A flat design
has no connections
and all pieces
are fixed ◳
The pieces
are placed hierarchically (breadth-first) for every cluster 🌿
Additional connections
which where not used in the placement can be used to validate the computed planes
🛂
🔗 Connection ↑
A connection
is a 3D-Link between two pieces
with the translation parameters gap (offset in y-direction), shift (offset in x-direction) and raise (offset in z-direction), and the rotation parameters rotation (rotation around y-axis), turn (rotation around z-axis) and tilt (rotation around x-axis) 🪢
The translation is applied first, then the rotation 🥈
The two pieces
are called connected and connecting but there is no difference between them 🔄
The direction of a connection
goes from the lower hierarchy to the higher hierarchy of the pieces
➡️
⭕ Piece ↑
A piece
is an instance of either a type
or a design
📐
A piece
is either fixed (with a plane
) or linked (with a connection
) 📐
A group of connected pieces
is called a cluster 🌿
The hierachy of a piece
is the length of the shortest path to the next fixed piece
👣
💾 Representation ↑
A representation
is a tagged
url
to a resource with an optional description 📄
No tags
means the default representation 🔑
The similarity of representations
is determined by the jaccard index of their tags
🔄
📏 Quality ↑
A quality
is metadata with a name, an optional value, an optional unit and an optional definition (url
or text) 🔤
The name is kebab-cased and with .
-separated string similar to toml keys 🔑
No value is equivalent to the boolean true where the name is the category of the quality 🔑
The unit is a unit identifier 🔢
mm
for millimeter,cm
for centimeter,dm
for decimeter,m
for meter,km
for kilometerm²
for square meter,m³
for cubic meter,m⁴
for quartic meter°
for degree,rad
for radianN
for newton,kN
for kilonewton,MN
for meganewton°C
for degree Celsius,°F
for degree FahrenheitW
for watt,kW
for kilowatt,MW
for megawatt,GW
for gigawattWh
for watt-hour,kWh
for kilowatt-hour,MWh
for megawatt-hour,GWh
for gigawatt-hourJ
for joule,kJ
for kilojoule,kcal
for kilocaloriekWh/m²a
for kilowatt-hour per square meter per yearm/s
for meter per second,m²/s
for square meter per second,m³/s
for cubic meter per secondPa
for pascal,kPa
for kilopascal,MPa
for megapascal- …
🏷️ Tag ↑
A tag
is a kebab-cased name 🔤
◳ Plane ↑
A plane
is a location (origin) and orientation (x-axis, y-axis and derived z-axis) in 3D space
The coordinate system is left-handed where the thumb points up into the direction of the z-axis, the index-finger forwards into the direction of the y-axis and the middle-finger points to the right into the direction of the x-axis 👈
🔗 Url ↑
A url
is either relative (to the root of the .zip
file) or remote (http, https, ftp, …) string🌐
A relative url
is a /
-normalized path to a file in the .zip
file and is not prefixed with with .
, ./
, /
, …
This git repo has everything that exists in the open semio ecosystem 🤯
⚖️ Principles ↑
Let's start with the rule of thumbs that this codebase was built with 🫰
💾 If something can be written in a single file, then it probably should ✅
I know, the urge to tidy up or separate things is big 🗃️
But try to withstand it 🫥
Out of my experience, it makes development slower, not faster 🐌
A single file is easier for humans and computers to understand 💡
You will be surprised
- by the awesome fill-in-the-middle suggestions of your copilot 🤖
- by the hassle-free context selection for your ai agent 🖱️
- by the smooth refactor experience by just going top-to-bottom ⬇️
- by the beautiful diff for your next code review 🔍
- by the clean git-history when you try to find a certain change 🔁
📁 If a folder doesn't make your life dramatically easier, don't create it ❌
We all know this ./src/**
folder that has made it into a lot of starters 🚀
Other than feeling cool about using hacky abbreviations, does it really help you to understand the project faster and work more efficient on it?
If your project contains hundreds of config file and other project folders at the root, maybe 🤔
But most likely not ❌
📦 Parts that belong together should be close in the source code ✅
The default code organization is to group kind of structurally similar parts together 📂
All models next to each other, all controllers next to each other, all errors next to each other, …
While this pattern supports structural refactoring, it makes plain extensions harder because you have to search through all the files 🔍
Most changes are plain extensions and not structural refactors 🔄
Further it has the advantage that every LLM-agent only has to predict one big block of code instead of plenty of small ones 🤖
That's why frameworks like React exist or vendoring such as with shadcn is more flexible than dependcenies such as with bootstrap
Cutting components vertically (a bit of logic with a bit of UI) instead of horizontally (all logic, all ui) requires more effort but enhances reusability 🔮
📑 If multiple people work longterm on the same part, then one file for each part should be created ✅
Trust me, it will make collaboration much easier 🔀
🔮 If you don't need an interface because something is not likely to be extended soon, don't create it ❌
The main question is the interface productive or not?
The pay-off of abstraction happens in the future 🛣️
Every extension profits from a clean interface 🚀
Most things are not extended 🪨
If you change your architecture, just design proper interfaces for something concrete not something potential and reactor it ✍️
🤏 Repeating code is ok if it the repeated code is close in the source code ✅
We are past the time where we copy code for no reason 📃
Actually repeated code can improve the quality of your copilots suggestion 🤯
The main question is how can your application grow?
If a change requires exponentially more duplication then you'll probably have to fix it 🛠️
If not, then you are probably good 👌
🤨 Wait, no high-level advice and only plain numbers, files, folders or close line of codes?
In our understanding, rule-of-thumbs are most useful when they are concrete 🔨
Besides that we are sure you know about KISS (Keep-It-Simple-Stupid), DRY (Dont-Repeat-Yourself), YAGNI (You-Aren't-Gonna-Need-It), SoC (Separation-of-Concerns), Avoid Premature Optimization, Law of Demeter, LCHC (Low-Coupling-High-Cohesion), SOLID (Single Responsibility (SR), Open/Closed (OC), Liskov's Substitution (LS), Interface Segregation (IS), Dependency Inversion (DI)), …
But as always, the devil is in the details 😈
Even if 95% of the codebase follows those principles, there are good reasons for the other 5% ⚖️
🚩 Don't worry, you'll figure out the possibilities and make the right choice for the specific problems ✅
🧑💻 Development ↑
Different components need different tools 🧰
For a complete setup you need:
- Windows 10 or 11
- Visual Studio Code
- Visual Studio 2022 Community
- Rhino 8
- Python 3.13
- Poetry
- Node
If you do not have Python installed, I recommend to install it over the Microsoft Store 🏪
Afterwards you can install poetry with this Powershell command:
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -
In the console you will see a warning that the poetry.exe
is not installed in the requested location 📁
Then copy the actual path
...\AppData\Local\Packages\PythonSoftwareFoundation...\Roaming\pypoetry\venv\Scripts
and add it to your environmental path variable ➕
Then you can build.ps1
in the Powershell and add your full path LOCAL_PATH\dotnet\Semio.Grasshopper\Debug\net48
to your GrasshopperDeveloperSettings ⚙️
If you have never executed local Powershell before then you have to first Set-ExecutionPolicy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine
🪄 AI ↑
Most of our codebase is heavily optimized for AI agents 🤖
We use Cursor as general editor mostly with Tab ➡️
For brain-heavy tasks we prepare good tickets and use Gemini 2.5 Pro ⚡
We parllely work on two tasks that are unrelated to each other in order switch between them during waiting times ⌛
✈️ Copilot ↑
For monkey-tasks we use the free Copilot with GPT-4.1 🚀
📢 Release ↑
Every release contains a set of matching specs, components, examples and docs 📦
The release notes follow this format:
SYMBOL TITLE
COMPONENT
- SYMBOL SUMMARY [CONTRIBUTOR]
…
Title symbols:
- 🏗️ Foundational work
- 🛠️ Heavy work
- 🪛 Minor work
- 🐛 Major Bug fix
Description symbols:
- 🌱 Started [not yet ready]
- ➕ Added [ready]
- ⬆️ Updated
- 🔄️ Renamed
- 🔁 Refactored
- 🐛 Bug fix
Before every release the repo is archived and then all branches are merged and squashed into a single commit 📦
🏷️ Tag ↑
We have two different types of tags:
rYY.MM-V
for releases (e.gr21.06-1
,r23.07-2
,r24.12-1
,r25.07-1
, …)COMPONENT-vMAJOR.MINOR.PATCH
for components which follow the semver versioning scheme (e.gengine-v4.0.2
,sketchpad-v1.0.0
,grasshopper-v5.4.0-beta
, …)
🌿 Branch ↑
The main
branch is the default archive branch 🔒
The dev
branch is the default general-purpose development branch 🛠️
Other branches are created for components, specific features or bug fixes 🐛
Usually one person works on one feature at a time and hence the -NAME
suffix 📛
🗃️ Commit ↑
📦 Commit as much as you like ✅
Are you worried about committing all those binary application files (.zip
, .gh
, .blend
, .glb
, .3dm
, …) or the intermediate versions between your ai edits?
Well, normally you should be 💾
But as we archive and squash all commits on every release nothing is lost or polluted 💯
⌛ Push around once an hour ✅
Pushing regularly keeps you extra safe from losing your work 🛟
There are a few services (like Discord) that are automatically updating to what happens in the repo 🔄️
To keep our inbox notifications low, we try to push not more than once an hour ⬆️
♻️ Ecosystems ↑
You might have noticed that the individual components can be closely related such as sketchpad, Grasshopper and engine but they are in totally different folders 📂
The reason for this is that the repo is not disected according content but according technology stack ✂️
This is less intuitive but more tool-friendly and everything that is easier for our tools is less pain to develop 🧑💻
🟨 JavaScript ↑
🔗 Useful links:
A .NET core for semio 🥜
Warning
Rhino still runs on .NET 7.0 7️⃣ Be careful to not update packages to a higher version, that might break the compatibility 🚨
Currently only engine but in the future it might grow and then the .venv
will be centralized, …
📦 Components ↑
A component is a piece of software which is packaged independently 🏝️
🔗 Useful links:
The core which is shared in the semio JavaScript ecosystem 🥜
An electron-based desktop app primarly working for with local kits 💾🔗 Useful links:
Mostly a Large Language Model-based assistant 🧰
📚 @semio/docs ↑
A playground for sketchpad 🎮
🟪 @semio/net ↑
🔗 Useful links:
The core which is shared in the semio .NET ecosystem 🥜
🔗 Useful links:
A full-blown Grasshopper Plugin that has (almost) everything 💯
Analogous to our principles for text-based code, we follow a similar logic for script-based code 🔄
💻 Optimize your definitions for rectangular space ✅
Every inch of wasted screen space, means a loss of productivity because you need longer for navigation 🖱️
It is harder to understand something far away compared to something close 🔍
I know, the triangular layout where you place the next component always vertically in the middle of the inputs looks cleaner due to the better wire display 🧹
But you waste a lot of space for nothing 💸
📛 Don't name things unless it is the output of a group or cluster ❌
We know that there are only two hard things in Computer Science: Cache invalidation and naming things 🥈
Visual programming languages solve the naming problem by using wires to overcome the neeed of names ⬆️
That is a big gain in productivity because you can focus on the logic instead of the names 🚀
Wait, but how I am supposed to understand what is happening in the code if I don't use names?
Most things in Grasshopper are visual and the green Only draw preview of selected components
button on the top left is your best friend 🔍
📦 If you don't absolutely need a cluster, don't create it ❌
Clusters are a good way to make code reusable and hide complexity 🥸
But hiding complexity means a slower development speed because you have to navigate through more files 🐌
Did you know that Grasshopper behaves different inside a cluster when outside?
E.g. when you feed an empty branch into a cluster the input inside it its magically pruned and when you leave it is there again which makes debugging much harder 🐛
I don't have to tell you about open definition tabs, updating nested clusters, recompute, performance, … right?
🤏 Minimize the amount of external parameters and take as much decisions as possible ✅
Designing means making decisions 🪨
Fewer parameters makes your design more parameteric and not less 🤯
The price for a synergizing system is the loss of flexibility 🤷♂️
If you don't know the parameters in the first place, you shouldn't create the Grasshopper script in the first place 🥈
Grasshopper is an amazing tool if you know the system that you want to create but is terrible for prototyping because of its lack of abstraction ⬇️
⚙️ @semio/engine ↑
🔗 Useful links:
A hidden fat-client which exposes shared functionality to other desktop uis 🤝
It takes care of:
- CRUDs (Create-Read-Update-Delete) for local kits 💾
- Client-Server communication
↔️
It offers two APIs to other clients:
- A simple REST OpenAPI 🥇
- A complex GraphQL Relay API 🥈
{} REST OpenAPI
If you go to http://127.0.0.1:2412/api/docs/
you find the Swagger UI:
Still a prototype ✏️
If you go to http://127.0.0.1:2412/graphql/
you find the GraphiQL UI:
🛍️ @semio/assets ↑
Each badge is created with shields.io with style flat-square
and semio colors.
- Copy the
*.shields
file of an existing badge 📄 - Open and download the
*.svg
file ⬇️
- Search font on fontsource.org 🔍
- Hit
Download
and extract zip file 📂 - Use kebaberized font name as folder name and remove everything else (such as version numbers) ➖
- Merge all types in one folder (
ttf
,webfonts
, …) - they won't collide due to different extensions 🗃️ - Remove all parts that repeat everywher (such as common name prefix, single weighted fonts, …) 💯
- Open favicongenerator.net 🔍
- Select
Circle
asBackground Shape
⏺️ - Select
Anta
asFont Family
📃 - Enter the
Code
that you find in the dictionary - Adjust the
Font Size
to the largest so that the space to the side is the same as the thickness of the stroke 🖊️ - Toggle
Enable SVG
on 🔳 - Hit
Generate Favicon
and download the zip file toassets/icons/temp/NAME.zip
whereNAME
is the lowercase name and verb of the icon 📂 - Repeat the process for all icons 🔁
- Run
build icons
in the debugger of vscode 🔨
👋 Hello semio ↑
🫀 Metabolism ↑
💯 Brand ↑
✍️ Concept ↑
✅ Do ↑
- Visual is better than text 👀
- Compact ➡️ More information ➡️ Faster to understand 🚀
❌ Dont ↑
- Rounded corners ⬜
- Shadows 🌤️
- Multiple unicode directly after each other 🥇🥈🥉
🌈 Colors ↑
🥇 Primary ↑
🥈 Secondary ↑
🥉 Tertiary ↑
⚫ Dark ↑
⚪ Light ↑
🩶 Grey ↑
Are you curious how a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and 11 colored gradient can come together for an invertible theme in a semantically meaningfull way? Well, here is how you achieve it with 33 colors 🤯
📄 Typography ↑
Note
Try to place notes either in the beginning or the end of a section
- Be consistent with your language ♻️
- When things are analogical use the same sentence structure for it 🔄
- One symbol after every sentance 💯
- One symbol at a time 🥇
- A symbol is preferably an emoji or otherwise unicode ⚖️
- 📝 One symbol to summarize a title
- 💡 One symbol to summarize a title description and one to think about in the end 🤔
.
are forbidden ⛔- All components in
semio
(sketchpad
,studio
, …) start with a small letter 🔡 - Did you know that
…
is just one character?
Tip
In the end of a section you can give the curious reader a summarizing question to think about the consequences and a link to more resources 🤔
🔡 Typesetting ↑
- Sans serif: Anta 🖨️
- Serif: Kelly Slab ✍️
- Monospaced: Shart Tech Mono 🖥️
- Emoji: Noto Emoji ⚫
👀 Visual elements ↑
- Sharp corners 📐
- Borders □
- Basic geometric shapes ⚪
![]() Ueli Saluz 🟨 🟪 🐍 🦗 ✏️ ⚙️ 🤖 🎛️ 📚 🛍️ 💯 🦏 🐝 🦌 🐞 🫀 👋 🚀 |
![]() KinanSarak 📚 👋 🦗 |
![]() Christian Hödtke 🦗 |
![]() drymuzzle 🦗 🐞 |
![]() kaatzjo ⚙️ |
![]() pizzadizza 🤖 |