Streaming, Programming, Learning, and Bravery (date, time TBA)


So I was watching @Galapagoose’s stream the other day and I found it very demystifying regarding the entire development process! I realized I’ve always wanted to see someone write the kinds of things we use around here, but I really have never had the experience!

I’m also (hopefully) beginning to transition from beginner to intermediate with my Norns-fu/Lua-fu, and I would love to find a nice way to contribute some of my learning back so that others may have a leg up in their beginnings! Here’s the synthesis:


The Bravery Stream

  • 2 hour stream with a preset list of goals
  • I do my best, get roasted, learn
  • VODs will be up for further roasting
  • intended ‘goal’ for generated content is threefold:
    • streams serve as a documentation of process. Learn from my mistakes! Delight in happy accidents :slight_smile:
    • I would love for the feedback to be reminiscent of an amazing high school english teacher who said sm like -> “hey, you’re good. If you can handle really honest criticism, I can give you real, actual feedback.”
    • it’s all an attempt to target a big social anxiety block that keeps many of us from learning, especially while isolated. * If other people like the concept, they’re welcome to do a Bravery Stream! If not, maybe just say hey in chat so I do this more than once :smiley: it won’t be all that different from my solo learning process, just more fun!
  • everything is explicitly and very intentionally worded to make sure it doesnt read as mean

It’s gonna take me some time to get my streaming setup going (I’m moving), but I’m going to do some text posts mean time.


* to be quite honest...

I’m not thriving, but I’m in my element to a certain extent – I can handle isolation and turn it in to discipline, given time!

29 Likes

I love the sound of this, really enjoyed Trent’s stream myself even though I don’t have a crow right now, and would happily watch someone make norns mistakes/general lua mistakes as I try to figure what that’s all about (once my norns-board gets out of covid captivity on another side of the world i will be at whatever stage comes before your beginner stage :stuck_out_tongue: ).

I tried my first stream today—it was a modular performance so a bit different than what you’re talking about but well outside of my comfort zone—not sure anyone really watched for long or anything, but it’s still a vulnerable feeling that I personally find really useful for improvement! Not to mention with something like programming, there’s an element of crowdsourcing that can be done with the chat and whatnot when you encounter a problem that can’t be solved :slight_smile: Looking forward to this!

1 Like

Looking forward to this!

For a while @zebra was doing some live norns hack-alongs on youtube and they were super fun and illustrative. It’s always interesting to see how others work. We all have our blindspots and so much to offer each other :slight_smile:

Please keep us up to date in this endeavor.

4 Likes

First post here in the main thread, and it’s a safe one, if I’m being honest. If someone can figure out a better way to do fast, pixel based rendering on the Norns, feel free to ruin me.

The Problem

Norns drawing be slow af (when it comes to game and/or pixel stuff) :confused: but why?

  • right now we do all our drawing from Lua, which means our drawing lives in the single threaded event queue with everything else Lua on Norns.
  • the norns platform still isn’t ready for easy, user-defined C behavior, but once we are there I’m hoping there will be a way to implement something low level for pixel stuff! There’s all sorts of fun stuff to be had with doing stuff like storing most of the background statically and doing a small amount of dynamic drawing to simulate lighting. I also think that the IRL non-linear effect of pixel brightness (a 15 outshines a 12 way more than a 6 outshines a 3) will allow for some clever collapsing of draw levels: think sprite pallette sets but even more primitive! Smooth animation for things like stars and waterfalls could be had with simple draws and pallette swaps! I should add support for storing/recalling zeroes cleverly so that we can have hidden pixels separate from nil pixels that can be switched on via a pallette swap.

The Solution

  1. don’t render everything as pixels! I already have some ideas for this, mostly around replacing “particle effects” with some rotating and scaling of drawing shapes. Pretty confident I can find some patterns that work and don’t clog up the Lua queue just to look good.
  2. use drawtables that sort pixel positions into groups based on brightness. This changes your drawing code from, at worst, number of pixels * 3 separate calls to screen functions (level, pixel, fill for each pixel) to only number of levels * (pixels at that level + 2) calls (level, pixel_1… pixel_n, fill for each level). Below is the code to do the pixel array -> drawtable conversion and I recommend you use that! Pixel arrays (a table containing width // tilesize tables of height // tilesize numbers from 1-15, which represent the drawing levels) are still way more readable in the source than drawtables, so I would recommend just doing your conversions on the first load or init or something… Directly declared draw tables are really hard to parse back into an image in your head, at least for me!
  3. Right now I’m messing around with some drawing coroutines, but it’s probably going to work out being more of a head start on wrapping my head around solid world-drawing code in C. I can’t wait until there’s something robust for saying: “here is a simple representation of the world, please do the drawing thank you.” There’s also probably room for separating rendering backend+assets from game logic so that games could be ported to desktop platforms with a little Cairo surface at some point!

Some Code

woodplank-pixels = {
    {5,3,3,5,3,5,5,3},
    {1,1,1,1,1,1,1,1},
    {5,3,3,5,5,3,2,3},
    {1,1,1,1,1,1,1,1},
    {5,3,5,3,5,3,3,3},
    {1,1,1,1,1,1,1,1},
    {5,3,3,5,3,3,5,5},
    {1,1,1,1,1,1,2,1}
} -- see the crude woodgrain and knots?


function px_to_drawtable(p)
    local t = {}
    for j = 1,8 do
        for k = 1,8 do
            local z = p[j][k]
            if t[z] == nil then t[z] = {} end
            -- there are smarter ways to do the insert
            --     than in nested loops, 
            --     but this function is only called once per tile
            table.insert(t[z],vector(j,k)) 
        end
    end
    return t
end

local x,y = 1,2 -- for coordinate addressing; in reality I use a vector module
function draw_tile(self)
    local ox,oy = self.coords.x,self.coords.y
    local dtab = self.dtab
    for level,coords in pairs(dtab) do
        screen.level(level)
        for _,v in ipairs(coords) screen.pixel(x+ox-2,y+oy-2) end
        screen.fill()
    end
end

function init()
    my_tile = {
        coords = {64,64},
        dtab = px_to_drawtable(woodplank-pixels),
        draw = draw_tile
    }
end

function redraw()
    screen.clear()
    my_tile:draw()
    screen.update()
end
        
2 Likes

Bravery Stream Docket WIP – Feedback Appreciated!

  • Computery
    • Play around with oczor to generate code for some handy functions and algorithms. I think it’d be fun to define a few things, generate Lua and then slightly modify it for use in my own code. That way if I wanna learn another language, I can generate some basic examples? It’s an old, dead alpha project, but it looks solid for my limited purposes.
    • Function Composition for good and evil – there’s a cool thread about this that gives me some ideas re: drawing functions. – update: bingo see note below
    • i wanna try to make a monochrome sprite designer with javidx9’s pixel game engine 2.0. A tool to visualize animations that I can send to artists and then incorporate directly into my projects would be sooo cooool.
  • Process
    • outros – lil nuggets that keep em hooked
  • Music
    • my new releases and some prep details :slight_smile:
    • a little info on my collab with mwami and yoshii swxdn
yahtzee

from: Ierusalimschy R.: First-Class Functions in an Imperative World

An important property of load is that it compiles any chunk of code as thebody of an anonymous function, with all functions defined by the chunk nestedinside it. Therefore, a chunk can declare local variables, which are equivalent tostatic variables in C: they are visible only inside the chunk, they are visible toall functions inside the chunk, and they preserve their values between successivecalls to these functions.

new band
Public Mistakes

8 Likes

That’s just 100gecs and I love them for it <3

1 Like

(bump) I’ve filled out the first stream docket with enough for one stream (and some). Maybe it’l be one big rolling docket?

Got a date picked out! AT&T is sending out a tech next Thursday (fingers crossed) as the biggest hurdle is now just moving my dang computer to a new house! Cheers!

I am a fool! Postponed until next week while I squash these new house setup bugs.