shado: a Lua compositing and sprite library for grid and arc devices on norns


A compositing and sprite library for grid and arc devices attached to the monome norns

I first built shado in Java 13 years ago for the non-greyscale grids, if the age of that video is to be believed. Now it’s been ported to Lua, supports greyscale and runs nicely on norns. A new video should probably be forthcoming,

I still need to port the arc renderer - I have an original arc-4 and a newer arc-2 and will do the work when I’m next in the same country as they are (January 2022). Grid support in shado is all in place.


norns, grid. The examples drive a greyscale 128 in landscape mode.


Documentation (LDoc) here: There’s a link to the main README which describes the system here:


v1.0.0 (2021-12-30) -

GitHub: GitHub - cassiel/shado: shado: monome grid/arc renderer in Lua for the Norns

Unpack as ~/dust/code/shado on norns, then load shado as a script to access the examples.


Lol i don’t even have a grid but seeing the vibe on the video now makes me want to get one because i love the energy!

Glad to be of service. At some stage I should port the animation setup shown in the video; it’s a mass of Python-atop-Java, but no reason why it shouldn’t run purely in Lua on norns.

welcome back @cassiel!!!

this is so exciting


That is amazing! I absolutely love how the music went with it too. I’m looking greatly forward to your new video and playing with this soon.

I had the biggest grin on my face the whole demo.

Well done!!


Me too! Took me back to the days of playing Wipeout on the PlayStation. Loved the Designers Republic graphics and this video had that aesthetic in spades.


If you want to try out the demos on norns and have a grid 128, this works fine typed in via maiden:


Then just load the top-level shado script. If you do, please let me know how it goes - it will be useful to have a potential user community of size greater than one.


This worked fine for me; I’m using midigrid with 2x Launchpads Mini MK3 rather than a Grid proper, but adding

local grid = include(“midigrid/lib/mg_128”)

at line 46 of shado.lua got everything responding as it should.

Wonderful - thanks. Would love to see photo or footage of that…

1 Like

hey @cassiel welcome back! spent a couple hours reading through all the stuff and trying ‘shado’ last night, got the demo apps working awesomely on my old varibright 256 :raised_hands: , have so many ideas for future apps, but right now, was hoping to integrate shado within an app already in progress which i’m almost finished with but just need to build a grid-interface… last night, i just couldn’t figure out how i could copy the ‘lib’ folder or possibly rename the ‘shado’ folder itself and build my app straight into it as the sole app i’d distribute(without shado demos…)… i guess realizing this isn’t designed for this use, am thinking maybe now i should ask you first if i can use it like that? is it supposed to be used more like we build all shado-based apps within the ‘shado’ repository? or can i break it out to use the library within an app that i would distribute on its own somehow? (if so, apologies, i might not have had the knowledge to do so… and also, of course, if this was possible would prioritize giving you credits with full url and all in the loading screen of my own app)

i guess at this stage, also wondering what’s the easiest for my future ‘shado’ based ideas/apps: is there a way to keep apps separate and include the shado functionality? or should i just build apps within the shado folder, and then distribute to others by github ‘branch’?

and DON’T WORRY! You will definitely NOT have a user community size of only one :joy:
This is the best thing for norns+grids, EVER!
:metal: :muscle: :fire: :heart:

1 Like

Thanks for the kind words and the welcome back - I’ve been in and out of this effort for a long-g-g time, but many other things got in the way last year and this year, as for everyone.

I’m pretty sure that when I started working on this port, it was possible to start a new norns project and then wheel in the shado stuff so long as the latter was installed at dust/code/shado as per the spec. - in fact, all you need is what’s in shado/lib. I’ll look at that again and report back - that was certainly the intention, shado is intended as a library, so you should be able to refer to it easily and not have to alter it.

I’m also interested in discussions about the library and techniques for using it. Hopefully it won’t need any serious breaking changes, but it would be interesting to see how people might use it, and for what. And how its use brings about different ways of thinking compared to the built-in core grid library. Pointers to any holes in the documentation also welcome.

1 Like

you should be able to refer to it easily and not have to alter it

ah sweet, i must’ve made a mistake somewhere… i think i should probably try again actually(…i’ll post back with more descriptive errors, too…)

also interested in discussions about the library and techniques for using it

so far, excited to have button presses tracked in a dynamic way(really great for making animated interfaces feel like games).
plus, because shado helps think more in terms of entire layers of matrices and masks(i like the organization you have by blocks, frames, masks, and layers), helps us imagine future grid-interfaces in terms of ‘moving textures’ :fireworks:

Pointers to any holes in the documentation also welcome.

only found a small one so far in the readme here:

in “Usage”, i think this might not be clear enough:

On norns, download this repository into /home/we/dust

(should add “/code” to the end of that :point_up: )
it actually makes sense later when i read the “Unit Testing” section, gets covered:

From the directory containing shado (on the norns that would be /home/we/dust/code)

but just mentioning, since the ‘usage’ section install instructions are what comes first in reading order.

and then the only other thing… i think it might also be possible to type directly into Maiden:


but nothing major so far, everything actually quite clear :+1:

thanks again! (will try again and post back with more descriptive errors from Maiden).

I’ll have go at building an independent project outside the shado directory - as I said, I’m pretty sure I’ve done that already at some stage, and it was always the usage intention.

Matching up button presses and releases seemed pretty crucial for any display system where things can move around. It might end up being shado's killer feature. There is some subtlety with multiple presses to the same component location, which can happen if the component moves.

Not sure what you mean by masks or layers altering layers beneath them…?

OK, wrong path in the docs… fixed, and I’ve also tidied up the notes about fetching from GitHub.

I should probably remove the “internal” functions from the API docs - I’m not quite sure why I decided to promote those comments, they’re not germane to usage of the library. For press handling you just need to implement press(self, x, y, how) in components, either by subclassing or monkey-patching. (I think I’ve monkey-patched so far, I should do some subclassing examples.) Then instantiate a PressManager over the object hierarchy.

1 Like

Hey again, deleted my last post as it was just me realizing a stupid mistake…

but now i’ve built a small thing…
it works like a game of whack-a-mole, when you catch the spinny with a press and hold, it sends the sounds through reverb:

42 lines of Lua, 53 lines of SuperCollider available here:

one suggestion i wanted to make is that it’d be great if they could include this in the standard norns API: reference | monome/docs … (then we could just type something like “shado = require(“shado”)”?)… i think whenever it’s ready(probably even ready now), could just write to to ask how that’s done… and in the meantime, i’d put something like a comment at the top of all the lib files, i put this when i copied them to my own repo:

– from the ‘shado’ library by
– Nick Rothwell,

just so people who take the option to copy files over from the lib, will keep the proper credit.
Anyways, promise not to take up anymore space in this thread. Just wanted to say thanks… still just learning, but it’s making perfect sense now.
Thank You So Much @cassiel :pray:


In terms of loading the libraries, I think you’re making far too much work for yourself. I just did a quick test with a brand new script loading shado from its standard installation location using

local types = include("shado/lib/types")
local blocks = include("shado/lib/blocks")
local frames = include("shado/lib/frames")
local renderers = include("shado/lib/renderers")
local manager = include("shado/lib/manager")

and it seems to work fine. include does the magic search into the code directory; within shado itself, require seems to work fine for lib-local files.

Here’s the “nugget” example as a standalone: