Nipah.ClaySharp.Raylib
0.1.2
dotnet add package Nipah.ClaySharp.Raylib --version 0.1.2
NuGet\Install-Package Nipah.ClaySharp.Raylib -Version 0.1.2
<PackageReference Include="Nipah.ClaySharp.Raylib" Version="0.1.2" />
<PackageVersion Include="Nipah.ClaySharp.Raylib" Version="0.1.2" />
<PackageReference Include="Nipah.ClaySharp.Raylib" />
paket add Nipah.ClaySharp.Raylib --version 0.1.2
#r "nuget: Nipah.ClaySharp.Raylib, 0.1.2"
#:package Nipah.ClaySharp.Raylib@0.1.2
#addin nuget:?package=Nipah.ClaySharp.Raylib&version=0.1.2
#tool nuget:?package=Nipah.ClaySharp.Raylib&version=0.1.2
ClaySharp
ClaySharp is an immediate-mode UI layout library for .NET. It builds a layout tree each frame, resolves sizes and positions, then emits a flat span of renderer-agnostic render commands for rectangles, borders, text, images, clipping, overlays, and custom payloads.
<p align="center"> <img src="snapshots/demo.png" alt="ClaySharp light theme demo showing clipped panels, counters, and renderer notes" width="49%" /> <img src="snapshots/demo_dark.png" alt="ClaySharp dark theme widget gallery showing color swatches, toggles, progress, and typography" width="49%" /> </p>
<p align="center"> <sub>Lightweight layout primitives, renderer-neutral commands, and a Raylib-backed interactive widget layer.</sub> </p>
The repository currently ships two packages:
ClaySharp: core layout engine and render command model.ClaySharp.Raylib: Raylib-cs text measurement, rendering, font assets, and a retained-state GUI helper layer.
ClaySharp.Run is a sample app, and ClaySharp.Tests is the test project. They are intentionally not packable.
Install
dotnet add package Nipah.ClaySharp
dotnet add package Nipah.ClaySharp.Raylib
Install only Nipah.ClaySharp if you want to provide your own renderer and ITextMeasurer implementation.
Core Usage
using System.Numerics;
using ClaySharp;
using var context = new ClayContext();
context.BeginLayout(new Vector2(1280, 720), textMeasurer);
using (context.Element(ElementStyle.Container(
ElementSizing.Grow(),
padding: Thickness.All(24),
gap: 12,
background: ClayColor.Rgba(24, 26, 32))))
{
context.Text(
"Hello from ClaySharp",
new TextElementStyle(
ElementStyle.Leaf(ElementSizing.Fit()),
new TextStyle(24, ClayColor.White, wrap: false)));
}
context.EndLayout();
foreach (ref readonly var command in context.RenderCommands)
{
// Draw with your renderer of choice.
}
Raylib Usage
using ClaySharp;
using ClaySharp.Raylib;
using Raylib_cs;
Raylib.InitWindow(1280, 720, "ClaySharp");
using var context = new ClayContext();
using var measurer = new RaylibTextMeasurer(_ => Raylib.GetFontDefault());
using var renderer = new ClayRaylibRenderer(_ => Raylib.GetFontDefault());
var gui = new ClayGui(context, measurer, renderer);
while (!Raylib.WindowShouldClose())
{
gui.Begin();
using (gui.Element()
.Grow()
.Padding(24)
.Gap(12)
.VerticalLayout())
{
gui.Text("Hello from Raylib");
}
gui.End();
Raylib.BeginDrawing();
Raylib.ClearBackground(Color.Black);
renderer.Render(gui.RenderCommands);
Raylib.EndDrawing();
}
Raylib.CloseWindow();
Raylib GPU assets such as custom fonts, shaders, and texture-backed font atlases should be disposed before Raylib.CloseWindow().
SDF Fonts
ClaySharp.Raylib ships an SDF font helper so text stays sharp at any scale. Load a TTF after Raylib.InitWindow(...) and pass the resulting RaylibFontFace into the measurer and renderer:
using var fontAsset = RaylibFontAsset.LoadSdf(
"OpenSans-Regular.ttf",
baseSize: 48,
codepoints: RaylibFontAsset.CreateCodepointRange(32, 255));
using var measurer = new RaylibTextMeasurer(_ => fontAsset.Face);
using var renderer = new ClayRaylibRenderer(_ => fontAsset.Face);
LoadSdf builds the glyph atlas with FontType.Sdf, uploads it as a bilinear-filtered texture, and compiles the matching SDF fragment shader. ClayRaylibRenderer automatically wraps DrawTextEx in BeginShaderMode / EndShaderMode whenever the resolved RaylibFontFace carries a shader, so regular Font instances keep working unchanged via RaylibFontAsset.Wrap(font) or the existing Func<int, Font> overloads.
Dispose RaylibFontAsset before Raylib.CloseWindow() so the SDF texture and shader are unloaded while the GL context is still alive.
Development
dotnet restore ClaySharp.slnx
dotnet build ClaySharp.slnx
dotnet test ClaySharp.Tests/ClaySharp.Tests.csproj --no-build
Create local NuGet packages with:
dotnet pack ClaySharp/ClaySharp.csproj -c Release -o artifacts/packages
dotnet pack ClaySharp.Raylib/ClaySharp.Raylib.csproj -c Release -o artifacts/packages
Package metadata is centralized in Directory.Build.props. Update its Version value before publishing a new release.
Cool Stuff
My inspiration to build this library using the techniques he described in his video. I find the idea extremely cool and I was always very amused by immediate mode GUI libraries.
Like, since I started programming 10+ years ago, one of the things I found the most bewildering was the synchrony problem between code and display. I never growed to like retained mode UIs... well kinda, I know why they exist and all, but I'm still not satisfied with them.
So this is really cool, I hope this is useful to someone.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Nipah.ClaySharp (>= 0.1.2)
- Raylib-cs (>= 7.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.