# nightshade (Go)
Go bindings for the nightshade engine, cgo over the C ABI.
```go
package main
import nightshade "github.com/matthewjberger/nightshade/bindings/go"
func main() {
nightshade.Run(func(app *nightshade.App) {
cube := app.SpawnCube([3]float64{0, 0.5, 0})
app.SetColor(cube, [4]float64{0.2, 0.6, 1, 1})
for app.Frame() {
app.Rotate(cube, [3]float64{0, 1, 0}, app.DeltaTime())
}
})
}
```
## How it works
cgo calls the typed C functions in `../c`, one per command, so nothing marshals
to json on the typed path. `App`'s methods (`SpawnCube`, `SetColor`, `Rotate`,
`KeyDown`, `ClickedEntity`, ...) pass vectors as `[N]float64` and entities as an
`Entity`, and return the reply as a Go value. The command enums come through as
Go types (`Shape`, `ScreenAnchor`, and `Body`/`Background` constructors). `Submit`
/ `SubmitBatch` keep the raw command surface as `map[string]any`. Entities come
back as `Entity` handles and pass straight back into commands.
`Run` locks the calling goroutine to its OS thread, because the engine requires
all of a window's calls on one thread. Call it from `main`. On macOS also lock
the main thread from an `init` function.
## Build
Needs a Rust toolchain, a C compiler for cgo (gcc or clang), and Go. The C ABI
must be built first, the Go package links its dll.
```
just build # build the C dll, then go build ./...
just example # build and run the spinning cube
just vet # go vet
```
The example links the dll directly (`-l:nightshade_c.dll`) and copies it beside
the built exe so the loader finds it at run time. A window needs a display and a
GPU.
The C ABI it sits on (`crates/nightshade-api/bindings/c`) is MSVC built on
Windows, and the C calling convention matches, so a mingw or clang cgo program
calls it cleanly over the C ABI.
## Not bound yet
The participant event stream is not exposed. The command stream above is the
whole surface.