From a3dfd8cb094122c9ed63931b893a4a2ff986eb5a Mon Sep 17 00:00:00 2001 From: s-ol Date: Sat, 24 Nov 2018 16:42:28 +1100 Subject: add blog post assets --- root/blog/automating_my_rice/akira/image$png.png | Bin 0 -> 430507 bytes root/blog/automating_my_rice/bwcube/image$png.png | Bin 0 -> 777315 bytes .../blog/automating_my_rice/cavetree/image$png.png | Bin 0 -> 356388 bytes root/blog/automating_my_rice/dark/image$png.png | Bin 0 -> 208683 bytes root/blog/automating_my_rice/hotline/image$png.png | Bin 0 -> 474347 bytes root/blog/automating_my_rice/laying/image$png.png | Bin 0 -> 412845 bytes .../automating_my_rice/mmm$tpl -> text$markdown.md | 61 ++++ root/blog/automating_my_rice/polar/image$png.png | Bin 0 -> 465144 bytes root/blog/automating_my_rice/polysun/image$png.png | Bin 0 -> 454325 bytes root/blog/automating_my_rice/psych/image$png.png | Bin 0 -> 675085 bytes root/blog/automating_my_rice/sexy/image$png.png | Bin 0 -> 424396 bytes .../blog/automating_my_rice/sidewalk/image$png.png | Bin 0 -> 463621 bytes .../blog/automating_my_rice/tattooed/image$png.png | Bin 0 -> 514156 bytes root/blog/automating_my_rice/text$markdown.md | 61 ---- .../blog/automating_my_rice/touching/image$png.png | Bin 0 -> 346835 bytes root/blog/automating_my_rice/trippy/image$png.png | Bin 0 -> 493667 bytes .../automating_my_rice/twostripe/image$png.png | Bin 0 -> 208673 bytes .../challenging_myself/mmm$tpl -> text$markdown.md | 25 ++ root/blog/challenging_myself/text$markdown.md | 25 -- .../clocks_triggers_gates/metronome/image$jpeg.jpg | Bin 0 -> 76904 bytes .../mmm$tpl -> text$markdown.md | 147 +++++++++ root/blog/clocks_triggers_gates/text$markdown.md | 149 --------- .../clocks_triggers_gates/threshold/image$jpeg.jpg | Bin 0 -> 239410 bytes .../humane_filesystems/mmm$tpl -> text$markdown.md | 73 +++++ root/blog/humane_filesystems/text$markdown.md | 73 ----- .../animating/video$mp4.mp4 | Bin 0 -> 6217225 bytes .../final/video$mp4.mp4 | Bin 0 -> 345405 bytes .../mmm$tpl -> text$markdown.md | 340 +++++++++++++++++++++ .../outside1/image$jpeg.jpg | Bin 0 -> 110413 bytes .../sheet/video$mp4.mp4 | Bin 0 -> 957272 bytes .../love_lua_photoshop_and_games/text$markdown.md | 340 --------------------- .../mmm$tpl -> text$markdown.md | 96 ++++++ .../ludum_dare_33_postmortem/smert/image$png.png | Bin 0 -> 253657 bytes .../ludum_dare_33_postmortem/split/image$png.png | Bin 0 -> 91714 bytes .../blog/ludum_dare_33_postmortem/text$markdown.md | 96 ------ .../stencils_101/balistencil_final/image$jpeg.jpg | Bin 0 -> 1472604 bytes .../stencils_101/killbill_final/image$jpeg.jpg | Bin 0 -> 1809213 bytes .../stencils_101/killbill_progress/image$jpeg.jpg | Bin 0 -> 1941103 bytes .../stencils_101/killbillstencil/image$png.png | Bin 0 -> 186880 bytes root/blog/stencils_101/mmm$tpl -> text$markdown.md | 95 ++++++ root/blog/stencils_101/poster/image$jpeg.jpg | Bin 0 -> 161341 bytes root/blog/stencils_101/suits_final/image$jpeg.jpg | Bin 0 -> 334515 bytes .../stencils_101/technofist_final/image$jpeg.jpg | Bin 0 -> 1815381 bytes root/blog/stencils_101/text$markdown.md | 95 ------ root/blog/stretching_gates/case/image$jpeg.jpg | Bin 0 -> 2199138 bytes root/blog/stretching_gates/crude/image$png.png | Bin 0 -> 6241 bytes .../stretching_gates/mmm$tpl -> text$markdown.md | 92 ++++++ .../blog/stretching_gates/schematic/image$jpeg.jpg | Bin 0 -> 1599989 bytes .../stretching_gates/stripboard/image$jpeg.jpg | Bin 0 -> 2631391 bytes root/blog/stretching_gates/text$markdown.md | 94 ------ .../ich_bin_holz/image$jpeg.jpg | Bin 0 -> 92346 bytes root/blog/video_synth_research/mine/image$jpeg.jpg | Bin 0 -> 762592 bytes .../mmm$tpl -> text$markdown.md | 124 ++++++++ .../video_synth_research/schematic/image$png.png | Bin 0 -> 390337 bytes root/blog/video_synth_research/text$markdown.md | 124 -------- 55 files changed, 1053 insertions(+), 1057 deletions(-) create mode 100644 root/blog/automating_my_rice/akira/image$png.png create mode 100644 root/blog/automating_my_rice/bwcube/image$png.png create mode 100644 root/blog/automating_my_rice/cavetree/image$png.png create mode 100644 root/blog/automating_my_rice/dark/image$png.png create mode 100644 root/blog/automating_my_rice/hotline/image$png.png create mode 100644 root/blog/automating_my_rice/laying/image$png.png create mode 100644 root/blog/automating_my_rice/mmm$tpl -> text$markdown.md create mode 100644 root/blog/automating_my_rice/polar/image$png.png create mode 100644 root/blog/automating_my_rice/polysun/image$png.png create mode 100644 root/blog/automating_my_rice/psych/image$png.png create mode 100644 root/blog/automating_my_rice/sexy/image$png.png create mode 100644 root/blog/automating_my_rice/sidewalk/image$png.png create mode 100644 root/blog/automating_my_rice/tattooed/image$png.png delete mode 100644 root/blog/automating_my_rice/text$markdown.md create mode 100644 root/blog/automating_my_rice/touching/image$png.png create mode 100644 root/blog/automating_my_rice/trippy/image$png.png create mode 100644 root/blog/automating_my_rice/twostripe/image$png.png create mode 100644 root/blog/challenging_myself/mmm$tpl -> text$markdown.md delete mode 100644 root/blog/challenging_myself/text$markdown.md create mode 100644 root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg create mode 100644 root/blog/clocks_triggers_gates/mmm$tpl -> text$markdown.md delete mode 100644 root/blog/clocks_triggers_gates/text$markdown.md create mode 100644 root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg create mode 100644 root/blog/humane_filesystems/mmm$tpl -> text$markdown.md delete mode 100644 root/blog/humane_filesystems/text$markdown.md create mode 100755 root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 create mode 100755 root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 create mode 100644 root/blog/love_lua_photoshop_and_games/mmm$tpl -> text$markdown.md create mode 100755 root/blog/love_lua_photoshop_and_games/outside1/image$jpeg.jpg create mode 100755 root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 delete mode 100644 root/blog/love_lua_photoshop_and_games/text$markdown.md create mode 100644 root/blog/ludum_dare_33_postmortem/mmm$tpl -> text$markdown.md create mode 100755 root/blog/ludum_dare_33_postmortem/smert/image$png.png create mode 100755 root/blog/ludum_dare_33_postmortem/split/image$png.png delete mode 100644 root/blog/ludum_dare_33_postmortem/text$markdown.md create mode 100755 root/blog/stencils_101/balistencil_final/image$jpeg.jpg create mode 100755 root/blog/stencils_101/killbill_final/image$jpeg.jpg create mode 100755 root/blog/stencils_101/killbill_progress/image$jpeg.jpg create mode 100755 root/blog/stencils_101/killbillstencil/image$png.png create mode 100644 root/blog/stencils_101/mmm$tpl -> text$markdown.md create mode 100755 root/blog/stencils_101/poster/image$jpeg.jpg create mode 100755 root/blog/stencils_101/suits_final/image$jpeg.jpg create mode 100755 root/blog/stencils_101/technofist_final/image$jpeg.jpg delete mode 100644 root/blog/stencils_101/text$markdown.md create mode 100644 root/blog/stretching_gates/case/image$jpeg.jpg create mode 100644 root/blog/stretching_gates/crude/image$png.png create mode 100644 root/blog/stretching_gates/mmm$tpl -> text$markdown.md create mode 100644 root/blog/stretching_gates/schematic/image$jpeg.jpg create mode 100644 root/blog/stretching_gates/stripboard/image$jpeg.jpg delete mode 100644 root/blog/stretching_gates/text$markdown.md create mode 100644 root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg create mode 100644 root/blog/video_synth_research/mine/image$jpeg.jpg create mode 100644 root/blog/video_synth_research/mmm$tpl -> text$markdown.md create mode 100644 root/blog/video_synth_research/schematic/image$png.png delete mode 100644 root/blog/video_synth_research/text$markdown.md (limited to 'root') diff --git a/root/blog/automating_my_rice/akira/image$png.png b/root/blog/automating_my_rice/akira/image$png.png new file mode 100644 index 0000000..e0b095d Binary files /dev/null and b/root/blog/automating_my_rice/akira/image$png.png differ diff --git a/root/blog/automating_my_rice/bwcube/image$png.png b/root/blog/automating_my_rice/bwcube/image$png.png new file mode 100644 index 0000000..0470a3a Binary files /dev/null and b/root/blog/automating_my_rice/bwcube/image$png.png differ diff --git a/root/blog/automating_my_rice/cavetree/image$png.png b/root/blog/automating_my_rice/cavetree/image$png.png new file mode 100644 index 0000000..9dda817 Binary files /dev/null and b/root/blog/automating_my_rice/cavetree/image$png.png differ diff --git a/root/blog/automating_my_rice/dark/image$png.png b/root/blog/automating_my_rice/dark/image$png.png new file mode 100644 index 0000000..8386f69 Binary files /dev/null and b/root/blog/automating_my_rice/dark/image$png.png differ diff --git a/root/blog/automating_my_rice/hotline/image$png.png b/root/blog/automating_my_rice/hotline/image$png.png new file mode 100644 index 0000000..1d9cf2f Binary files /dev/null and b/root/blog/automating_my_rice/hotline/image$png.png differ diff --git a/root/blog/automating_my_rice/laying/image$png.png b/root/blog/automating_my_rice/laying/image$png.png new file mode 100644 index 0000000..4b7bc5f Binary files /dev/null and b/root/blog/automating_my_rice/laying/image$png.png differ diff --git a/root/blog/automating_my_rice/mmm$tpl -> text$markdown.md b/root/blog/automating_my_rice/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..16083ff --- /dev/null +++ b/root/blog/automating_my_rice/mmm$tpl -> text$markdown.md @@ -0,0 +1,61 @@ +I spent the bigger part of today writing a small script that cylces through all my [Themer][themer] themes, +opens a dmenu, prints the theme name with figlet and shows screenfetch before taking a picture. +The script is pretty straightforward: + + #!/usr/bin/bash + + for theme in $(themer list); do + themer activate $theme + sleep 20 # wait for bar :/ + dmenu -p "Launch:" $(~/.i3/dmenuconf) < ~/.cache/dmenu_run & + dmenupid=$! + clear + screenfetch + echo + toilet --gay $theme + echo;echo;echo;echo;echo;echo;echo + themer current + + sleep 1 + scrot $theme.png + kill $dmenupid + done + +So here are all my current themes (click to view seperately):: + +[![cavetree][cavetree]][cavetree] +[![akira][akira]][akira] +[![sidewalk][sidewalk]][sidewalk] +[![hotline][hotline]][hotline] +[![polar][polar]][polar] +[![polysun][polysun]][polysun] +[![psych][psych]][psych] +[![trippy][trippy]][trippy] +[![twostripe][twostripe]][twostripe] +[![bwcube][bwcube]][bwcube] + +The wallpaper for the last one is intended to be tiled, not stretched, but that currently requries a manual change in my i3 config: +[![dark][dark]][dark] + +I am thinking about implementing this as a Themer feature, but it will require it's own *presentation* plugin type so everyone can choose their own commands, bars, and waiting time, + +You can find more information about [Themer on the github page][themer], along with all my [config files][dotfiles]. + +[themer]: https://github.com/s-ol/themer +[dotfiles]: https://github.com/s-ol/dotfiles + +[akira]: {{akira+URL -> image/png}} +[bwcube]: {{bwcube+URL -> image/png}} +[cavetree]: {{cavetree+URL -> image/png}} +[dark]: {{dark+URL -> image/png}} +[hotline]: {{hotline+URL -> image/png}} +[laying]: {{laying+URL -> image/png}} +[polar]: {{polar+URL -> image/png}} +[polysun]: {{polysun+URL -> image/png}} +[psych]: {{psych+URL -> image/png}} +[sexy]: {{sexy+URL -> image/png}} +[sidewalk]: {{sidewalk+URL -> image/png}} +[tattooed]: {{tattooed+URL -> image/png}} +[touching]: {{touching+URL -> image/png}} +[trippy]: {{trippy+URL -> image/png}} +[twostripe]: {{twostripe+URL -> image/png}} diff --git a/root/blog/automating_my_rice/polar/image$png.png b/root/blog/automating_my_rice/polar/image$png.png new file mode 100644 index 0000000..113b0de Binary files /dev/null and b/root/blog/automating_my_rice/polar/image$png.png differ diff --git a/root/blog/automating_my_rice/polysun/image$png.png b/root/blog/automating_my_rice/polysun/image$png.png new file mode 100644 index 0000000..8fef054 Binary files /dev/null and b/root/blog/automating_my_rice/polysun/image$png.png differ diff --git a/root/blog/automating_my_rice/psych/image$png.png b/root/blog/automating_my_rice/psych/image$png.png new file mode 100644 index 0000000..93628f6 Binary files /dev/null and b/root/blog/automating_my_rice/psych/image$png.png differ diff --git a/root/blog/automating_my_rice/sexy/image$png.png b/root/blog/automating_my_rice/sexy/image$png.png new file mode 100644 index 0000000..00cb65d Binary files /dev/null and b/root/blog/automating_my_rice/sexy/image$png.png differ diff --git a/root/blog/automating_my_rice/sidewalk/image$png.png b/root/blog/automating_my_rice/sidewalk/image$png.png new file mode 100644 index 0000000..3d53ff2 Binary files /dev/null and b/root/blog/automating_my_rice/sidewalk/image$png.png differ diff --git a/root/blog/automating_my_rice/tattooed/image$png.png b/root/blog/automating_my_rice/tattooed/image$png.png new file mode 100644 index 0000000..7ed2f33 Binary files /dev/null and b/root/blog/automating_my_rice/tattooed/image$png.png differ diff --git a/root/blog/automating_my_rice/text$markdown.md b/root/blog/automating_my_rice/text$markdown.md deleted file mode 100644 index f20623d..0000000 --- a/root/blog/automating_my_rice/text$markdown.md +++ /dev/null @@ -1,61 +0,0 @@ -I spent the bigger part of today writing a small script that cylces through all my [Themer][themer] themes, -opens a dmenu, prints the theme name with figlet and shows screenfetch before taking a picture. -The script is pretty straightforward: - - #!/usr/bin/bash - - for theme in $(themer list); do - themer activate $theme - sleep 20 # wait for bar :/ - dmenu -p "Launch:" $(~/.i3/dmenuconf) < ~/.cache/dmenu_run & - dmenupid=$! - clear - screenfetch - echo - toilet --gay $theme - echo;echo;echo;echo;echo;echo;echo - themer current - - sleep 1 - scrot $theme.png - kill $dmenupid - done - -So here are all my current themes (click to view seperately):: - -[![cavetree][cavetree]][cavetree] -[![akira][akira]][akira] -[![sidewalk][sidewalk]][sidewalk] -[![hotline][hotline]][hotline] -[![polar][polar]][polar] -[![polysun][polysun]][polysun] -[![psych][psych]][psych] -[![trippy][trippy]][trippy] -[![twostripe][twostripe]][twostripe] -[![bwcube][bwcube]][bwcube] - -The wallpaper for the last one is intended to be tiled, not stretched, but that currently requries a manual change in my i3 config: -[![dark][dark]][dark] - -I am thinking about implementing this as a Themer feature, but it will require it's own *presentation* plugin type so everyone can choose their own commands, bars, and waiting time, - -You can find more information about [Themer on the github page][themer], along with all my [config files][dotfiles]. - -[themer]: https://github.com/s-ol/themer -[dotfiles]: https://github.com/s-ol/dotfiles - -[akira]: {{site.url}}/assets/{{page.imgid}}/akira.png -[bwcube]: {{site.url}}/assets/{{page.imgid}}/bwcube.png -[cavetree]: {{site.url}}/assets/{{page.imgid}}/cavetree.png -[dark]: {{site.url}}/assets/{{page.imgid}}/dark.png -[hotline]: {{site.url}}/assets/{{page.imgid}}/hotline.png -[laying]: {{site.url}}/assets/{{page.imgid}}/laying.png -[polar]: {{site.url}}/assets/{{page.imgid}}/polar.png -[polysun]: {{site.url}}/assets/{{page.imgid}}/polysun.png -[psych]: {{site.url}}/assets/{{page.imgid}}/psych.png -[sexy]: {{site.url}}/assets/{{page.imgid}}/sexy.png -[sidewalk]: {{site.url}}/assets/{{page.imgid}}/sidewalk.png -[tattooed]: {{site.url}}/assets/{{page.imgid}}/tattooed.png -[touching]: {{site.url}}/assets/{{page.imgid}}/touching.png -[trippy]: {{site.url}}/assets/{{page.imgid}}/trippy.png -[twostripe]: {{site.url}}/assets/{{page.imgid}}/twostripe.png diff --git a/root/blog/automating_my_rice/touching/image$png.png b/root/blog/automating_my_rice/touching/image$png.png new file mode 100644 index 0000000..01d1520 Binary files /dev/null and b/root/blog/automating_my_rice/touching/image$png.png differ diff --git a/root/blog/automating_my_rice/trippy/image$png.png b/root/blog/automating_my_rice/trippy/image$png.png new file mode 100644 index 0000000..7cb4354 Binary files /dev/null and b/root/blog/automating_my_rice/trippy/image$png.png differ diff --git a/root/blog/automating_my_rice/twostripe/image$png.png b/root/blog/automating_my_rice/twostripe/image$png.png new file mode 100644 index 0000000..a935968 Binary files /dev/null and b/root/blog/automating_my_rice/twostripe/image$png.png differ diff --git a/root/blog/challenging_myself/mmm$tpl -> text$markdown.md b/root/blog/challenging_myself/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..aaddf08 --- /dev/null +++ b/root/blog/challenging_myself/mmm$tpl -> text$markdown.md @@ -0,0 +1,25 @@ +# Yay, a first post! A blank blog! + +I am starting to blog now as part of an... experiment of sorts. +I have a lot of time on my hands at the moment and I choose to spend it all boring myself. +I re-discovered [streak.club][streak.club] a few days ago and so I decided to give it a shot and try a few new things. + +If you never heard of **streak.club**, you should definetely check it out. +It is a small social network built by [leafo](https://twitter.com/moonscript) where people can get together and participate in *Streaks*. +Once you join a streak, you submit an entry every day or every week (depending on the Streak's settings). +People can then like and comment on your entries and give you feedback for your creations. +If you miss a day, nothing bad happens, but yout streak counter gets reset. + +One of the streaks I joined is the [*Blog every week*][blogeweek] streak, which I will submit this first post to when I am done. +I also created my own streak, [*Daily Stencil Art*][stencils]. So, for the next month, I will try to design and/or paint one stencil per day. +The [first stencil](https://streak.club/p/7129/kill-bill-the-bride-stencil-by-s0lll0s) I did for the streak turned out really nice, so I will continue to design some in that art style (gold background with black shadow pieces on top and a small piece in an accent color). + +As for the future of this blog, I am not quite sure where this will go. +I think I am going to cover my stencil creation process in a post soon (maybe today, maybe next week, who knows?) and also blog about programming/development of games and other stuff I might write. +Maybe I will also port some of the tutorials I have written so far to markdown and put them here aswell. + +I hope that **streak.club** will work as well long-term as it does right now, motivation is still probably my number one enemy and streak.club is an excellent way for me to focus on new things and get away from the computer some more aswell. + +[streak.club]: https://streak.club +[stencils]: https://streak.club/s/614/daily-stencil-art +[blogeweek]: https://streak.club/s/103/blog-every-week diff --git a/root/blog/challenging_myself/text$markdown.md b/root/blog/challenging_myself/text$markdown.md deleted file mode 100644 index aaddf08..0000000 --- a/root/blog/challenging_myself/text$markdown.md +++ /dev/null @@ -1,25 +0,0 @@ -# Yay, a first post! A blank blog! - -I am starting to blog now as part of an... experiment of sorts. -I have a lot of time on my hands at the moment and I choose to spend it all boring myself. -I re-discovered [streak.club][streak.club] a few days ago and so I decided to give it a shot and try a few new things. - -If you never heard of **streak.club**, you should definetely check it out. -It is a small social network built by [leafo](https://twitter.com/moonscript) where people can get together and participate in *Streaks*. -Once you join a streak, you submit an entry every day or every week (depending on the Streak's settings). -People can then like and comment on your entries and give you feedback for your creations. -If you miss a day, nothing bad happens, but yout streak counter gets reset. - -One of the streaks I joined is the [*Blog every week*][blogeweek] streak, which I will submit this first post to when I am done. -I also created my own streak, [*Daily Stencil Art*][stencils]. So, for the next month, I will try to design and/or paint one stencil per day. -The [first stencil](https://streak.club/p/7129/kill-bill-the-bride-stencil-by-s0lll0s) I did for the streak turned out really nice, so I will continue to design some in that art style (gold background with black shadow pieces on top and a small piece in an accent color). - -As for the future of this blog, I am not quite sure where this will go. -I think I am going to cover my stencil creation process in a post soon (maybe today, maybe next week, who knows?) and also blog about programming/development of games and other stuff I might write. -Maybe I will also port some of the tutorials I have written so far to markdown and put them here aswell. - -I hope that **streak.club** will work as well long-term as it does right now, motivation is still probably my number one enemy and streak.club is an excellent way for me to focus on new things and get away from the computer some more aswell. - -[streak.club]: https://streak.club -[stencils]: https://streak.club/s/614/daily-stencil-art -[blogeweek]: https://streak.club/s/103/blog-every-week diff --git a/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg b/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg new file mode 100644 index 0000000..70fedb5 Binary files /dev/null and b/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg differ diff --git a/root/blog/clocks_triggers_gates/mmm$tpl -> text$markdown.md b/root/blog/clocks_triggers_gates/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..e04d3f9 --- /dev/null +++ b/root/blog/clocks_triggers_gates/mmm$tpl -> text$markdown.md @@ -0,0 +1,147 @@ +A classic module in modular synthesisers is a sequencer. It allows you to create rhythms and +melodies by letting you set a sequence of values to output over some time. +For example a drum machine usually contains a step-sequencer where for every *step* in the +*sequence* you can select whether to play, or not play, a drum. + +*CV Sequencers* haver a dial in place of that on/off switch, where you can set a value for the +*Control_Voltage* to be output. +That signal can then be fed into another module to do something interesting, like control the +pitch of an oscillator, the cut-off point of a filter or the gain of an amplifier. + +Sequencers usually have an internal clock, with a dial to set the speed, but also an external clock +input, where you can feed in a square wave signal. +Every time the square wave goes from low (0V) to high (usually anything over 5V) the sequencer steps +to the next beat. + +Since we have a multitude of sound-generators that we want to use in interesing rhythms, multiple +sequencers sound natural and a central clock could certainly help. + +## hit it +However a digital, steady clock is pretty boring, so I came up with an idea. +I remembered the old wooden metronome that my grandma had at her piano and how I used to play with +it as a child. If we had a real metronome tick away, we could hold the needle in place, +tap it to add an extra beat where there wasn't supposed to be one and more. + +![a wittner metronome][metronome.jpg] + +Analog metronomes like this are actually pretty interesting little devices. +They are purely mechanical and contain a spring that you have to wind up to give it power. +On the front there is a needle with a weight at the top and the bottom. +By moving the top weight up and down the speed of the needle, +and thereby the ticking-rate can be set. +Every time the needle centers (like it is on the image below), a mechanism in the back makes a small +metal pin slam against a metal plate glued to the case, making a loud clicking noise. + +With this idea, we were on the lookout for a metronome on our trip to the fleamarket +but couldn't find one, so I ended up buying the tiny one above (the size is pretty nice anyway). + +The idea was (and it worked out that way!) to pick up the clicks somehow and use them to trigger +sequencers. +Originally I thought about putting a light dependant resistor (LDR) somewhere under the +counterweight, and measure the shadow as a signal. +In the time until I got the Metronome, I discussed this with Sam Battle, who runs the awesome +youtube channel [LOOK MUM NO COMPUTER][no-computer] and he proposed to use a piezo crystal +(sometimes referred to as *Contact Mic*) instead. + +As it turns out, the metronome has plenty of space to glue the piezo right next to the metal plate +that the metronome hits with the metal pin, where it can pick up all that very nicely. +The 1/4" (6.3mm) audio jack also fit very well behind the panel, where there is a rather large +empty compartment, I guess to amplifiy the ticking sound. +I just drilled a hole in the back, screwed the jack in and soldered two wires; done! + +
+ First Test +
+ +In this first test you can see the Piezo work as a microphone amplifying the ticking noise on my +speakers. + +## signal shapes +That was a first success, but the signal we get from the metronome is not very clean. +Not only does it pick up random noises from the environment (sometimes intentionally), +the click is no square wave since it resonates through the plastic material. + +To clean up the signal initially I took a look on it on the Oscilloscope. +It looks pretty much like what you would expect, swinging up and down a few times, +each with a drastic drop in amplitude. + +The first attempt was to just use a comparator. +The output from the metronome goes to the non-inverting-input, meaning that when it is higher than +the other (inverting) input, the output of the comparator swings high. +This is what I wanted since sequencers trigger on the rising edge. +The inverting input is wired to a potentiometers center pin, with the other two pins at the supply +voltage and ground (0 and 9V) to form a voltage divider that lets me tune the threshold to any +any voltage in that range. +The output signal is now what you would call a *Trigger* signal; it is usually low and sometimes +jumps up to 9V for a *very short* duration (while the tick clips over the threshold on it's first +and loudest swing). I didn't measure the pulse length, but it's probably under 10ms long. + +To test the circuit, I fed the output to a (CD)4017 counter. +This IC can be used to build sequencers or clock dividers rather easily (more on that later). +I just set it up to light up 4 LEDs in sequence, so that I could see whether the circuit was fine. +After an hour or so of figuring out stupid wiring mistakes and learning about open-drain outputs +it was working: + +
+ analog metronome +
+(this tweet is mislabeled, Juan's sequencer is in the next video). + +[Juan][juan] had an Akai Tomcat drum machine on hand, and we were stoked to try it out. +As usual at first, it didn't work at all. +Pretty soon we figured out that the signal was just too quiet coming off our 9V supply, +so we put an amplifier in between (alongside a whole mess of cables) and behold: + +
+ analog metronome +
+ +This worked pretty well, surprisingly! +With the potentiometer set *just right*, it rarely triggered twice, and ran for some time before the +spring weakened and the sound became a tiny bit more quiet and failed to trigger every beat. +This is also a really nice effect actually and transforms rather simple beats into nice wacky ones: + +
+ analog metronome +
+ +The schematic at this point is very simple: + +![threshold schematic][threshold.jpg] + +I used an LM393 dual comparator and tied the unused half to ground, as the datasheet recommends. + +## dividing time +While this was working very well already, I had an idea for improving it using the universal 555 +timer IC. However, I didn't have any 555s on hand (or rather, I wasn't aware [Ludonaut][ludonaut] +had a 556 in his box next to me) so I kept that in mind but went on with other things +(more on this in the upcoming post). + +Reading up on synthesizer modules, I found *Clock Dividers* rather often. In the beginning I wasn't +quite sure what they were, but it turns out they are pretty simple: basically they just slow down a +clock (signal) by counting beats and only producing one of their own every N beats in the incoming +signal. I thought this would be very useful for us, since using clock dividers with non-multiple +divisons such as /3, /4 and /5 can create nice polyrhythms. + +My plan is to build this right into the same box as the clock threshold circuitry. +In the videos above you can already see it working with /2, /3, /4 and /6 outputs. +The schematic is largely copied from [Ken Stone's amazing synthesizer project, CGS][cgs]. +He has a nice collection of synth module circuits, and here I am using the pulse divider part of the +[CGS36 Pulse Divider and Boolean Logic][cgs36] module: + +[![CGS36 Pulse Divider][cgs36-schematic.gif]][cgs36] + +For now I left out the /7, /8 and /5 parts, but I think the /5 would be useful since it introduces +another prime division that is not much faster or slower than the /3 and /4 we already have. +The /8 would be almost 'for free' since it doesn't require a new 4017, but I'm not sure whether I +should put it in with the /7 missing. I guess it could be useful for a slow melody sequencer. + +[no-computer]: https://www.youtube.com/watch?v=fO1nbHoEZMw +[juan]: https://twitter.com/juanorloz +[ludonaut]: https://twitter.com/ludonaut +[cgs]: http://www.cgs.synth.net/modules/ +[cgs36]: http://www.elby-designs.com/webtek/cgs/cgs36/cgs36_pulse_divider.html + +[cgs36-schematic.gif]: http://www.elby-designs.com/webtek/cgs/cgs36/schem_cgs36v14_pulse_divider.gif +[metronome.jpg]: {{metronome+URL -> image/jpeg}} +[threshold.jpg]: {{threshold+URL -> image/jpeg}} diff --git a/root/blog/clocks_triggers_gates/text$markdown.md b/root/blog/clocks_triggers_gates/text$markdown.md deleted file mode 100644 index 42fb0c7..0000000 --- a/root/blog/clocks_triggers_gates/text$markdown.md +++ /dev/null @@ -1,149 +0,0 @@ -A classic module in modular synthesisers is a sequencer. It allows you to create rhythms and -melodies by letting you set a sequence of values to output over some time. -For example a drum machine usually contains a step-sequencer where for every *step* in the -*sequence* you can select whether to play, or not play, a drum. - -*CV Sequencers* haver a dial in place of that on/off switch, where you can set a value for the -*Control_Voltage* to be output. -That signal can then be fed into another module to do something interesting, like control the -pitch of an oscillator, the cut-off point of a filter or the gain of an amplifier. - -Sequencers usually have an internal clock, with a dial to set the speed, but also an external clock -input, where you can feed in a square wave signal. -Every time the square wave goes from low (0V) to high (usually anything over 5V) the sequencer steps -to the next beat. - -Since we have a multitude of sound-generators that we want to use in interesing rhythms, multiple -sequencers sound natural and a central clock could certainly help. - -## hit it -However a digital, steady clock is pretty boring, so I came up with an idea. -I remembered the old wooden metronome that my grandma had at her piano and how I used to play with -it as a child. If we had a real metronome tick away, we could hold the needle in place, -tap it to add an extra beat where there wasn't supposed to be one and more. - -![a wittner metronome][metronome.jpg] - -Analog metronomes like this are actually pretty interesting little devices. -They are purely mechanical and contain a spring that you have to wind up to give it power. -On the front there is a needle with a weight at the top and the bottom. -By moving the top weight up and down the speed of the needle, -and thereby the ticking-rate can be set. -Every time the needle centers (like it is on the image below), a mechanism in the back makes a small -metal pin slam against a metal plate glued to the case, making a loud clicking noise. - -With this idea, we were on the lookout for a metronome on our trip to the fleamarket -but couldn't find one, so I ended up buying the tiny one above (the size is pretty nice anyway). - -The idea was (and it worked out that way!) to pick up the clicks somehow and use them to trigger -sequencers. -Originally I thought about putting a light dependant resistor (LDR) somewhere under the -counterweight, and measure the shadow as a signal. -In the time until I got the Metronome, I discussed this with Sam Battle, who runs the awesome -youtube channel [LOOK MUM NO COMPUTER][no-computer] and he proposed to use a piezo crystal -(sometimes referred to as *Contact Mic*) instead. - -As it turns out, the metronome has plenty of space to glue the piezo right next to the metal plate -that the metronome hits with the metal pin, where it can pick up all that very nicely. -The 1/4" (6.3mm) audio jack also fit very well behind the panel, where there is a rather large -empty compartment, I guess to amplifiy the ticking sound. -I just drilled a hole in the back, screwed the jack in and soldered two wires; done! - -
- First Test -
- -In this first test you can see the Piezo work as a microphone amplifying the ticking noise on my -speakers. - -## signal shapes -That was a first success, but the signal we get from the metronome is not very clean. -Not only does it pick up random noises from the environment (sometimes intentionally), -the click is no square wave since it resonates through the plastic material. - -To clean up the signal initially I took a look on it on the Oscilloscope. -It looks pretty much like what you would expect, swinging up and down a few times, -each with a drastic drop in amplitude. - -The first attempt was to just use a comparator. -The output from the metronome goes to the non-inverting-input, meaning that when it is higher than -the other (inverting) input, the output of the comparator swings high. -This is what I wanted since sequencers trigger on the rising edge. -The inverting input is wired to a potentiometers center pin, with the other two pins at the supply -voltage and ground (0 and 9V) to form a voltage divider that lets me tune the threshold to any -any voltage in that range. -The output signal is now what you would call a *Trigger* signal; it is usually low and sometimes -jumps up to 9V for a *very short* duration (while the tick clips over the threshold on it's first -and loudest swing). I didn't measure the pulse length, but it's probably under 10ms long. - -To test the circuit, I fed the output to a (CD)4017 counter. -This IC can be used to build sequencers or clock dividers rather easily (more on that later). -I just set it up to light up 4 LEDs in sequence, so that I could see whether the circuit was fine. -After an hour or so of figuring out stupid wiring mistakes and learning about open-drain outputs -it was working: - -
- analog metronome -
-(this tweet is mislabeled, Juan's sequencer is in the next video). - -[Juan][juan] had an Akai Tomcat drum machine on hand, and we were stoked to try it out. -As usual at first, it didn't work at all. -Pretty soon we figured out that the signal was just too quiet coming off our 9V supply, -so we put an amplifier in between (alongside a whole mess of cables) and behold: - -
- analog metronome -
- -This worked pretty well, surprisingly! -With the potentiometer set *just right*, it rarely triggered twice, and ran for some time before the -spring weakened and the sound became a tiny bit more quiet and failed to trigger every beat. -This is also a really nice effect actually and transforms rather simple beats into nice wacky ones: - -
- analog metronome -
- -The schematic at this point is very simple: - -![threshold schematic][threshold.jpg] - -I used an LM393 dual comparator and tied the unused half to ground, as the datasheet recommends. - -## dividing time -While this was working very well already, I had an idea for improving it using the universal 555 -timer IC. However, I didn't have any 555s on hand (or rather, I wasn't aware [Ludonaut][ludonaut] -had a 556 in his box next to me) so I kept that in mind but went on with other things -(more on this in the upcoming post). - -Reading up on synthesizer modules, I found *Clock Dividers* rather often. In the beginning I wasn't -quite sure what they were, but it turns out they are pretty simple: basically they just slow down a -clock (signal) by counting beats and only producing one of their own every N beats in the incoming -signal. I thought this would be very useful for us, since using clock dividers with non-multiple -divisons such as /3, /4 and /5 can create nice polyrhythms. - -My plan is to build this right into the same box as the clock threshold circuitry. -In the videos above you can already see it working with /2, /3, /4 and /6 outputs. -The schematic is largely copied from [Ken Stone's amazing synthesizer project, CGS][cgs]. -He has a nice collection of synth module circuits, and here I am using the pulse divider part of the -[CGS36 Pulse Divider and Boolean Logic][cgs36] module: - -[![CGS36 Pulse Divider][cgs36-schematic.gif]][cgs36] - -For now I left out the /7, /8 and /5 parts, but I think the /5 would be useful since it introduces -another prime division that is not much faster or slower than the /3 and /4 we already have. -The /8 would be almost 'for free' since it doesn't require a new 4017, but I'm not sure whether I -should put it in with the /7 missing. I guess it could be useful for a slow melody sequencer. - -[no-computer]: https://www.youtube.com/watch?v=fO1nbHoEZMw -[juan]: https://twitter.com/juanorloz -[ludonaut]: https://twitter.com/ludonaut -[cgs]: http://www.cgs.synth.net/modules/ -[cgs36]: http://www.cgs.synth.net/modules/cgs36_pulse_divider.html - -[cgs36-schematic.gif]: http://www.cgs.synth.net/modules/pic/schem_cgs36v14_pulse_divider.gif -[metronome.jpg]: {{site.url}}/assets/{{page.imgid}}/metronome.jpg -[threshold.jpg]: {{site.url}}/assets/{{page.imgid}}/threshold.jpg - - diff --git a/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg b/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg new file mode 100644 index 0000000..509cd5b Binary files /dev/null and b/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg differ diff --git a/root/blog/humane_filesystems/mmm$tpl -> text$markdown.md b/root/blog/humane_filesystems/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..1f8ab79 --- /dev/null +++ b/root/blog/humane_filesystems/mmm$tpl -> text$markdown.md @@ -0,0 +1,73 @@ +Lately I've been thinking about note-taking tools. + +I use a few different systems for taking notes almost daily: +- multiple paper notebooks and sheets of paper as available +- random freeform text files spread around my (various) PCs +- google keep + +I like taking paper notes because it's easy to switch to doodle and sketch and layout everything together. +I also find that it stimulates my thinking a bit more that typing text; I'm not quite sure why that is. + +Anyway, I was looking for solutions to replace google keep, mostly because I like to self-host my services. + +## file system use cases +- retrieve a file i know exists + - either file i know 100% + - or looking for a file based on content, guessing where and how it might be +- show related files to what i am looking for +- allow exploring content + +### tags and search don't solve anything +Many proposals in [FileSystemAlternatives][c2-fsalt] and [LimitsOfHierarchies][c2-loh] are to generalize up from Hierarchies to Set Theory. +This in effect means exchanging the any-to-one association between 'containers' (folders/tags) and 'contents' (files) for a any-to-any association. +Files are then no longer identified by their chain of parents, but rather by their belonging and not-belonging to all the existant tags. +Generally the proposal is to query these tag-based filesystems using combinatory logic such as `a AND (b OR NOT(C))` and so on. + +My main problem with this approach is that sooner or later you end up with a huge list of tags that is just unmanageable. +It's obvious that this won't scale as the amount of tag increases with the amount of different data, +especially in a collaborative, professional or otherwise networked context. + +Since the tags are all stored flatly in a bag of stuff, they also cannot meaningfully express relationships between each other. +This is clearly evident in any software that uses tags as the only option of organizing large amounts of data, +especially when multiple users have access. +Here is an example of a typical list of defined tags for issue tracking on github: + +![github tags][github-tags] + +As can be seen easily, users are shoehorning more information into the label name string than the label is made to store. +As this extra data is only available to humans interpreting the text, it cannot be used to create good UI: +Instead of seeing a drop-down for *Tech Complexity*, users need to go through the label list. +Even the simplest logical constraints cannot be documented and enforced with this system. + +-> need for *dynamically changeable* data schemas + +/* +But even organizing and finding files with this paradigm is not a very nice experience; take these UI designs for example: + +![set picker from tablizer][tablizer-tagging] +![search dialog from tablizer][tablizer-search] + +Granted, it's not particularily fair to take these designs from 2002, but this paradigm is all around us today and the UX hasn't gotten a lot better. +Here's the same set picker functionality as seen on google keep, today: + +![labelling UI in google keep][keep-label] + +And for the search, they didn't even try. There's just a list + +A very thorough proposal for a file system can be found in [*A Novel, Tag-Based File System*][tag-based-fs]. + +This approach +*/ + +### is there more? +- the file system as a note-taking app + +[tiddlywiki]: https://tiddlywiki.com/ +[tablizer-search]: http://www.reocities.com/tablizer/setscrn1.gif +[tablizer-tagging]: http://www.reocities.com/tablizer/setpicker.gif +[tablizer-src]: http://www.reocities.com/tablizer/sets1.htm +[tag-based-fs]: http://digitalcommons.macalester.edu/cgi/viewcontent.cgi?article=1036&context=mathcs_honors +[finder-column-view]: http://cdn.osxdaily.com/wp-content/uploads/2010/03/set-column-view-size-default-mac-os-x-finder-610x307.jpg +[finder-column-view-src]: http://osxdaily.com/2010/03/25/setting-the-default-column-size-in-mac-os-x-finder-windows/ +[finder-list-view]: http://cdn.osxdaily.com/wp-content/uploads/2014/12/messages-attachments-folder-mac-osx.jpg +[finder-list-view-src]: http://osxdaily.com/2014/12/03/access-attachments-messages-mac-os-x/ diff --git a/root/blog/humane_filesystems/text$markdown.md b/root/blog/humane_filesystems/text$markdown.md deleted file mode 100644 index 1f8ab79..0000000 --- a/root/blog/humane_filesystems/text$markdown.md +++ /dev/null @@ -1,73 +0,0 @@ -Lately I've been thinking about note-taking tools. - -I use a few different systems for taking notes almost daily: -- multiple paper notebooks and sheets of paper as available -- random freeform text files spread around my (various) PCs -- google keep - -I like taking paper notes because it's easy to switch to doodle and sketch and layout everything together. -I also find that it stimulates my thinking a bit more that typing text; I'm not quite sure why that is. - -Anyway, I was looking for solutions to replace google keep, mostly because I like to self-host my services. - -## file system use cases -- retrieve a file i know exists - - either file i know 100% - - or looking for a file based on content, guessing where and how it might be -- show related files to what i am looking for -- allow exploring content - -### tags and search don't solve anything -Many proposals in [FileSystemAlternatives][c2-fsalt] and [LimitsOfHierarchies][c2-loh] are to generalize up from Hierarchies to Set Theory. -This in effect means exchanging the any-to-one association between 'containers' (folders/tags) and 'contents' (files) for a any-to-any association. -Files are then no longer identified by their chain of parents, but rather by their belonging and not-belonging to all the existant tags. -Generally the proposal is to query these tag-based filesystems using combinatory logic such as `a AND (b OR NOT(C))` and so on. - -My main problem with this approach is that sooner or later you end up with a huge list of tags that is just unmanageable. -It's obvious that this won't scale as the amount of tag increases with the amount of different data, -especially in a collaborative, professional or otherwise networked context. - -Since the tags are all stored flatly in a bag of stuff, they also cannot meaningfully express relationships between each other. -This is clearly evident in any software that uses tags as the only option of organizing large amounts of data, -especially when multiple users have access. -Here is an example of a typical list of defined tags for issue tracking on github: - -![github tags][github-tags] - -As can be seen easily, users are shoehorning more information into the label name string than the label is made to store. -As this extra data is only available to humans interpreting the text, it cannot be used to create good UI: -Instead of seeing a drop-down for *Tech Complexity*, users need to go through the label list. -Even the simplest logical constraints cannot be documented and enforced with this system. - --> need for *dynamically changeable* data schemas - -/* -But even organizing and finding files with this paradigm is not a very nice experience; take these UI designs for example: - -![set picker from tablizer][tablizer-tagging] -![search dialog from tablizer][tablizer-search] - -Granted, it's not particularily fair to take these designs from 2002, but this paradigm is all around us today and the UX hasn't gotten a lot better. -Here's the same set picker functionality as seen on google keep, today: - -![labelling UI in google keep][keep-label] - -And for the search, they didn't even try. There's just a list - -A very thorough proposal for a file system can be found in [*A Novel, Tag-Based File System*][tag-based-fs]. - -This approach -*/ - -### is there more? -- the file system as a note-taking app - -[tiddlywiki]: https://tiddlywiki.com/ -[tablizer-search]: http://www.reocities.com/tablizer/setscrn1.gif -[tablizer-tagging]: http://www.reocities.com/tablizer/setpicker.gif -[tablizer-src]: http://www.reocities.com/tablizer/sets1.htm -[tag-based-fs]: http://digitalcommons.macalester.edu/cgi/viewcontent.cgi?article=1036&context=mathcs_honors -[finder-column-view]: http://cdn.osxdaily.com/wp-content/uploads/2010/03/set-column-view-size-default-mac-os-x-finder-610x307.jpg -[finder-column-view-src]: http://osxdaily.com/2010/03/25/setting-the-default-column-size-in-mac-os-x-finder-windows/ -[finder-list-view]: http://cdn.osxdaily.com/wp-content/uploads/2014/12/messages-attachments-folder-mac-osx.jpg -[finder-list-view-src]: http://osxdaily.com/2014/12/03/access-attachments-messages-mac-os-x/ diff --git a/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 new file mode 100755 index 0000000..4b752b5 Binary files /dev/null and b/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 differ diff --git a/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 new file mode 100755 index 0000000..faa42bb Binary files /dev/null and b/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 differ diff --git a/root/blog/love_lua_photoshop_and_games/mmm$tpl -> text$markdown.md b/root/blog/love_lua_photoshop_and_games/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..e49db99 --- /dev/null +++ b/root/blog/love_lua_photoshop_and_games/mmm$tpl -> text$markdown.md @@ -0,0 +1,340 @@ +Recently I've been building a 2d game engine for my semester project at [CGL](http://colognegamelab.de). +Below, I'll copy and paste two blog posts from my internal documentation blog: + +--- + +After nailing down the basic narrative and gameplay idea in a lengthy group discussion on the first day, +we each set goals for the next few days in order to kickstart the project. + +As we decided on a pixel art art approach and point-and-click gameplay, as the programmer I decided to write a custom engine in +[LÖVE](https://love2d.org) instead of using a bulky engine like Unity that we wouldn't really profit from anyway and that would be less specific, +and therefore less fitting, than what I could come up with. +Following this, my goal as an engine programmer was then to reduce any effort needed to put content into the engine to a minimum. +I remembered iteration speeds and how most things I did as a programmer last time I built a pixel art project in Unity really weren't programming but replacing assets; adding states in an animation state machine that I could've easily coded by hand in a fraction of the time; and generally wrestling with the development environment, and I wanted to instead create a working environment that would make my job as the gameplay programmer and the job of the artist(s) a lot easier. + +Because creating my own engine is not a minor task and obviously a very crucial one for the project, +the decision to go ahead and not use a prebuilt Engine was to be thought out thoroughly, +if I am to write my own engine it needs to work _at least_ as good as a prebuilt one or it will harm the project. +To test whether I could actually improve workflow and build something my team can profit from, without degrading the project work during the time I need to actually put it together, I set myself a three-day deadline to try and go as far as I can and see whether writing the engine myself seemed realistic. +The other goal of this trial phase was to show my team members why the switch could be worthwhile for them also. + +Therefore my main starting point was to build a feature that they would see as useful and that was central to what the engine was going to do later: **rendering and scene management.** + +Specifically, I started writing something that loads a .PSD directly and animates the sublayers. +I also added code that detects file changes and reloads them automatically. +At the end of the second project day, I had this: + + + +The code for this isn't much, but it took a few iterations to make the file- reload-watching reuseable and work on Linux and Windows alike (and efficient). +I used a 3rd party library for loading the photoshop files, but I had to patch it a lot. +Here's the main part for the animated-layer-loading: + + artal = require "lib.artal.artal" + + ALL_SHEETS = setmetatable {}, __mode: 'v' + RECHECK = 0.3 + + class PSDSheet + new: (@filename, @frametime=.1) => + @time = 0 + @frame = 1 + + @reload! + + if WATCHER + WATCHER\register @filename, @ + + reload: => + print "reloading #{@filename}..." + + + @frames = {} + target = @frames + local group + + psd = artal.newPSD @filename + for layer in *psd + if layer.type == "open" + if not group + layer.image = love.graphics.newCanvas psd.width, psd.height + love.graphics.setCanvas layer.image + table.insert target, layer + group = layer.name + elseif layer.type == "close" + if layer.name == group + love.graphics.setCanvas! + group = nil + else + if not group + table.insert target, layer + else + love.graphics.draw layer.image, -layer.ox, -layer.oy if layer.image + + update: (dt) => + @time += dt + + @frame = 1 + (math.floor(@time/@frametime) % #@frames) + + draw: (x, y, rot) => + {:image, :ox, :oy} = @frames[@frame] + love.graphics.draw image, x, y, rot, nil, nil, ox, oy if image + + { + :PSDSheet, + } + + +--- + +After being able to load simple animations from photoshop without even closing the game was working, I tried loading the scene İlke had created meanwhile: + +![outside1]({{outside1+URL -> image/jpeg}}) + +Naturally, this failed at first. +He was using clipping masks and blend modes, neither of which were implemented at the time, +but after I made a few changes to hide the affected layers for the time being, it looked fine. + +My overall engine goal was to be able to build something like 90% of the level right in photoshop - including animations, hit areas, player spawns etc. +Basically I wanted to use Photoshop as a full level editor and only write gameplay scripts and engine code outside of it. + +This meant that there would be very different types of information inside a level .psd that we would need to be accessible to the engine. + +To load information and behaviours into the level structure that is loaded from the PSD I created a layer naming conventions; +layers can specify a _Directive_ afte their name. + +The most important Directive (so far) is _load_: it loads a lua/moonscript _mixin_ via it's name and passes arguments to it . +For example there is a 'common' (shared between different scenes/levels) module called _subanim_ that treat's a group inside a bigger, +non-animated photoshop document as an animation (like what I did in the first post, but inside a complex scene). +The _subanim _module has one parameter, the frame-duration (in seconds). +To turn a group into a _subanim_, you have to append 'load:subanim,0.2' to it's name for example. + +Another Directive is _tag_, it stores the layer under a name so other scripts can access it specifically and consistently. +Because this could also be done by a mixin, i am thinking about abolishing the _Directive_ concept and only using mixins (so that the _load_ could be removed also). +You can see the system working in this clip: + + + +_making an animation out of the single rain layer_ + +Moreover, I added a directory structure for mixins; to load a mixin called _name _for a scene called _scene_, it first looks in the scene specific directories: + + - game/_scene_/_name_.moon + - game/_scene.moon_ (this file can return multiple mixins) + +if neither of these exist, it checks for _common_ mixins of this name in the common directory and files: + + - games/common/_name.moon_ + - games/common.moon (this file can return multiple mixins) + +This allows to share mixins between scenes (like click-area mixins maybe, or the _subanim_ mentioned above) +but still keep a clean directory structure for specific elements (like the dialogue of a certain scene, +or the tram in the background of the scene we are working on currently). + +Mixin code can modify the scene node / layer object and overwrite the default "draw" and "update" hooks/methods. +This allows for nearly everything I can think of right now, but most mixins are still very short and concise. +As examples, you can take a look at the code that animates the tram in the background or the subanim source: + +game/first_encounter/tram.moon: + + import wrapping_, Mixin from require "util" + + wrapping_ class SubAnim extends Mixin + SPEED = 440 + new: (scene) => + super! + + @pos = 0 + + update: (dt) => + @pos = (@pos + SPEED*dt) % (WIDTH*2) + + draw: (recursive_draw) => + love.graphics.draw @image, @pos/4 - @ox - 140, -@oy + + +game/common/subanim.moon: + + import wrapping_, Mixin from require "util" + + wrapping_ class SubAnim extends Mixin + new: (scene, @frametime=0.1) => + super! + + @time = 0 + @frame = 1 + + update: (dt) => + @time += dt + + @frame = 1 + (math.floor(@time/@frametime) % #@) + + draw: (recursive_draw) => + recursive_draw {@[@frame]} + + +_wrapping_ is a small helper that allows a moonscript class to wrap an existing lua table +(= object, in this case the layer objects produced by the psd parsing phase) and Mixin is a class that handles mixin live-reloading +(yep, that works with mixins too!) and might contain utility functions to write better mixins in the future. +Here's the code for both: + + wrapping_ = (klass) -> + getmetatable(klass).__call = (cls, self, ...) -> + setmetatable self, cls.__base + cls.__init self, ... + + klass + + class Mixin + new: => + info = debug.getinfo 2 + file = string.match info.source, "@%.?[/\\]?(.*)" + + @module = info.source\match "@%.?[/\\]?(.*)%.%a+" + @module = @module\gsub "/", "." + + if WATCHER + WATCHER\register file, @ + + reload: (filename) => + print "reloading #{@module}..." + + package.loaded[@module] = nil + new = require @module + + setmetatable @, new.__base + + find_tag: => + layer = @ + while not layer.tag + layer = layer.parent + + if not layer + return nil + + layer.tag + + { + :wrapping_, + :Mixin + } + + +By the end of the three day "test phase". +This is how the first scene looked in-game: + + + +Here's _psdscene.moon_, wrapping most things mentioned in this article: + + artal = require "lib.artal.artal" + + class PSDScene + new: (@scene) => + @reload! + + if WATCHER + WATCHER\register "assets/#{@scene}.psd", @ + + load: (name, ...) => + _, mixin = pcall require, "game.#{@scene}.#{name}" + return mixin if _ and mixin + + _, module = pcall require, "game.#{scene}" + return module[name] if _ and module[name] + + _, mixin = pcall require, "game.common.#{name}" + return mixin if _ and mixin + + _, module = pcall require, "game.common" + return module[name] if _ and module[name] + + LOG_ERROR "couldn't find mixin '#{name}' for scene '#{@scene}'" + nil + + reload: (filename) => + filename = "assets/#{@scene}.psd" unless filename + print "reloading scene #{filename}..." + + @tree, @tags = {}, {} + target = @tree + local group + + indent = 0 + + psd = artal.newPSD filename + for layer in *psd + if layer.type == "open" + table.insert target, layer + layer.parent = target + target = layer + LOG "+ #{layer.name}", indent + indent += 1 + continue -- skip until close + elseif layer.type == "close" + layer = target + target = target.parent + indent -= 1 + else + LOG "- #{layer.name}", indent + table.insert target, layer + + cmd, params = layer.name\match "([^: ]+):(.+)" + switch cmd + when nil + "" + when "tag" + @tags[params] = tag + layer.tag = params + when "load" + params = [str for str in params\gmatch "[^,]+"] + name = table.remove params, 1 + + mixin = @load name + if mixin + LOG "loading mixin '#{@scene}/#{name}' (#{table.concat params, ", "})", indent + mixin layer, unpack params + else + LOG_ERROR "couln't find mixin for '#{@scene}/#{name}'", indent + else + LOG_ERROR "unknown cmd '#{cmd}' for layer '#{layer.name}'", indent + + update: (dt, group=@tree) => + if group == false + return + + for layer in *group + if layer.update + layer\update dt, @\update + elseif layer.type == "open" + @update dt, layer + + draw: (group=@tree) => + if group == false + return + elseif group == @tree + love.graphics.scale 4 + + for layer in *group + if layer.draw + layer\draw @\draw + elseif layer.image + {:image, :ox, :oy} = layer + love.graphics.setColor 255, 255, 255, layer.opacity or 255 + love.graphics.draw image, x, y, nil, nil, nil, ox, oy + elseif layer.type == "open" + @draw layer + + { + :PSDScene, + } + + +Seeing that everything was (and is) going very smoothly up to this point, +I decided to "end" the test phase and finalize the decision to roll out my own engine. diff --git a/root/blog/love_lua_photoshop_and_games/outside1/image$jpeg.jpg b/root/blog/love_lua_photoshop_and_games/outside1/image$jpeg.jpg new file mode 100755 index 0000000..85a29b1 Binary files /dev/null and b/root/blog/love_lua_photoshop_and_games/outside1/image$jpeg.jpg differ diff --git a/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 new file mode 100755 index 0000000..6cc4b2d Binary files /dev/null and b/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 differ diff --git a/root/blog/love_lua_photoshop_and_games/text$markdown.md b/root/blog/love_lua_photoshop_and_games/text$markdown.md deleted file mode 100644 index 68bed22..0000000 --- a/root/blog/love_lua_photoshop_and_games/text$markdown.md +++ /dev/null @@ -1,340 +0,0 @@ -Recently I've been building a 2d game engine for my semester project at [CGL](http://colognegamelab.de). -Below, I'll copy and paste two blog posts from my internal documentation blog: - ---- - -After nailing down the basic narrative and gameplay idea in a lengthy group discussion on the first day, -we each set goals for the next few days in order to kickstart the project. - -As we decided on a pixel art art approach and point-and-click gameplay, as the programmer I decided to write a custom engine in -[LÖVE](https://love2d.org) instead of using a bulky engine like Unity that we wouldn't really profit from anyway and that would be less specific, -and therefore less fitting, than what I could come up with. -Following this, my goal as an engine programmer was then to reduce any effort needed to put content into the engine to a minimum. -I remembered iteration speeds and how most things I did as a programmer last time I built a pixel art project in Unity really weren't programming but replacing assets; adding states in an animation state machine that I could've easily coded by hand in a fraction of the time; and generally wrestling with the development environment, and I wanted to instead create a working environment that would make my job as the gameplay programmer and the job of the artist(s) a lot easier. - -Because creating my own engine is not a minor task and obviously a very crucial one for the project, -the decision to go ahead and not use a prebuilt Engine was to be thought out thoroughly, -if I am to write my own engine it needs to work _at least_ as good as a prebuilt one or it will harm the project. -To test whether I could actually improve workflow and build something my team can profit from, without degrading the project work during the time I need to actually put it together, I set myself a three-day deadline to try and go as far as I can and see whether writing the engine myself seemed realistic. -The other goal of this trial phase was to show my team members why the switch could be worthwhile for them also. - -Therefore my main starting point was to build a feature that they would see as useful and that was central to what the engine was going to do later: **rendering and scene management.** - -Specifically, I started writing something that loads a .PSD directly and animates the sublayers. -I also added code that detects file changes and reloads them automatically. -At the end of the second project day, I had this: - - - -The code for this isn't much, but it took a few iterations to make the file- reload-watching reuseable and work on Linux and Windows alike (and efficient). -I used a 3rd party library for loading the photoshop files, but I had to patch it a lot. -Here's the main part for the animated-layer-loading: - - artal = require "lib.artal.artal" - - ALL_SHEETS = setmetatable {}, __mode: 'v' - RECHECK = 0.3 - - class PSDSheet - new: (@filename, @frametime=.1) => - @time = 0 - @frame = 1 - - @reload! - - if WATCHER - WATCHER\register @filename, @ - - reload: => - print "reloading #{@filename}..." - - - @frames = {} - target = @frames - local group - - psd = artal.newPSD @filename - for layer in *psd - if layer.type == "open" - if not group - layer.image = love.graphics.newCanvas psd.width, psd.height - love.graphics.setCanvas layer.image - table.insert target, layer - group = layer.name - elseif layer.type == "close" - if layer.name == group - love.graphics.setCanvas! - group = nil - else - if not group - table.insert target, layer - else - love.graphics.draw layer.image, -layer.ox, -layer.oy if layer.image - - update: (dt) => - @time += dt - - @frame = 1 + (math.floor(@time/@frametime) % #@frames) - - draw: (x, y, rot) => - {:image, :ox, :oy} = @frames[@frame] - love.graphics.draw image, x, y, rot, nil, nil, ox, oy if image - - { - :PSDSheet, - } - - ---- - -After being able to load simple animations from photoshop without even closing the game was working, I tried loading the scene İlke had created meanwhile: - -![outside1]({{site.url}}/assets/{{page.imgid}}/outside1.jpg) - -Naturally, this failed at first. -He was using clipping masks and blend modes, neither of which were implemented at the time, -but after I made a few changes to hide the affected layers for the time being, it looked fine. - -My overall engine goal was to be able to build something like 90% of the level right in photoshop - including animations, hit areas, player spawns etc. -Basically I wanted to use Photoshop as a full level editor and only write gameplay scripts and engine code outside of it. - -This meant that there would be very different types of information inside a level .psd that we would need to be accessible to the engine. - -To load information and behaviours into the level structure that is loaded from the PSD I created a layer naming conventions; -layers can specify a _Directive_ afte their name. - -The most important Directive (so far) is _load_: it loads a lua/moonscript _mixin_ via it's name and passes arguments to it . -For example there is a 'common' (shared between different scenes/levels) module called _subanim_ that treat's a group inside a bigger, -non-animated photoshop document as an animation (like what I did in the first post, but inside a complex scene). -The _subanim _module has one parameter, the frame-duration (in seconds). -To turn a group into a _subanim_, you have to append 'load:subanim,0.2' to it's name for example. - -Another Directive is _tag_, it stores the layer under a name so other scripts can access it specifically and consistently. -Because this could also be done by a mixin, i am thinking about abolishing the _Directive_ concept and only using mixins (so that the _load_ could be removed also). -You can see the system working in this clip: - - - -_making an animation out of the single rain layer_ - -Moreover, I added a directory structure for mixins; to load a mixin called _name _for a scene called _scene_, it first looks in the scene specific directories: - - - game/_scene_/_name_.moon - - game/_scene.moon_ (this file can return multiple mixins) - -if neither of these exist, it checks for _common_ mixins of this name in the common directory and files: - - - games/common/_name.moon_ - - games/common.moon (this file can return multiple mixins) - -This allows to share mixins between scenes (like click-area mixins maybe, or the _subanim_ mentioned above) -but still keep a clean directory structure for specific elements (like the dialogue of a certain scene, -or the tram in the background of the scene we are working on currently). - -Mixin code can modify the scene node / layer object and overwrite the default "draw" and "update" hooks/methods. -This allows for nearly everything I can think of right now, but most mixins are still very short and concise. -As examples, you can take a look at the code that animates the tram in the background or the subanim source: - -game/first_encounter/tram.moon: - - import wrapping_, Mixin from require "util" - - wrapping_ class SubAnim extends Mixin - SPEED = 440 - new: (scene) => - super! - - @pos = 0 - - update: (dt) => - @pos = (@pos + SPEED*dt) % (WIDTH*2) - - draw: (recursive_draw) => - love.graphics.draw @image, @pos/4 - @ox - 140, -@oy - - -game/common/subanim.moon: - - import wrapping_, Mixin from require "util" - - wrapping_ class SubAnim extends Mixin - new: (scene, @frametime=0.1) => - super! - - @time = 0 - @frame = 1 - - update: (dt) => - @time += dt - - @frame = 1 + (math.floor(@time/@frametime) % #@) - - draw: (recursive_draw) => - recursive_draw {@[@frame]} - - -_wrapping_ is a small helper that allows a moonscript class to wrap an existing lua table -(= object, in this case the layer objects produced by the psd parsing phase) and Mixin is a class that handles mixin live-reloading -(yep, that works with mixins too!) and might contain utility functions to write better mixins in the future. -Here's the code for both: - - wrapping_ = (klass) -> - getmetatable(klass).__call = (cls, self, ...) -> - setmetatable self, cls.__base - cls.__init self, ... - - klass - - class Mixin - new: => - info = debug.getinfo 2 - file = string.match info.source, "@%.?[/\\]?(.*)" - - @module = info.source\match "@%.?[/\\]?(.*)%.%a+" - @module = @module\gsub "/", "." - - if WATCHER - WATCHER\register file, @ - - reload: (filename) => - print "reloading #{@module}..." - - package.loaded[@module] = nil - new = require @module - - setmetatable @, new.__base - - find_tag: => - layer = @ - while not layer.tag - layer = layer.parent - - if not layer - return nil - - layer.tag - - { - :wrapping_, - :Mixin - } - - -By the end of the three day "test phase". -This is how the first scene looked in-game: - - - -Here's _psdscene.moon_, wrapping most things mentioned in this article: - - artal = require "lib.artal.artal" - - class PSDScene - new: (@scene) => - @reload! - - if WATCHER - WATCHER\register "assets/#{@scene}.psd", @ - - load: (name, ...) => - _, mixin = pcall require, "game.#{@scene}.#{name}" - return mixin if _ and mixin - - _, module = pcall require, "game.#{scene}" - return module[name] if _ and module[name] - - _, mixin = pcall require, "game.common.#{name}" - return mixin if _ and mixin - - _, module = pcall require, "game.common" - return module[name] if _ and module[name] - - LOG_ERROR "couldn't find mixin '#{name}' for scene '#{@scene}'" - nil - - reload: (filename) => - filename = "assets/#{@scene}.psd" unless filename - print "reloading scene #{filename}..." - - @tree, @tags = {}, {} - target = @tree - local group - - indent = 0 - - psd = artal.newPSD filename - for layer in *psd - if layer.type == "open" - table.insert target, layer - layer.parent = target - target = layer - LOG "+ #{layer.name}", indent - indent += 1 - continue -- skip until close - elseif layer.type == "close" - layer = target - target = target.parent - indent -= 1 - else - LOG "- #{layer.name}", indent - table.insert target, layer - - cmd, params = layer.name\match "([^: ]+):(.+)" - switch cmd - when nil - "" - when "tag" - @tags[params] = tag - layer.tag = params - when "load" - params = [str for str in params\gmatch "[^,]+"] - name = table.remove params, 1 - - mixin = @load name - if mixin - LOG "loading mixin '#{@scene}/#{name}' (#{table.concat params, ", "})", indent - mixin layer, unpack params - else - LOG_ERROR "couln't find mixin for '#{@scene}/#{name}'", indent - else - LOG_ERROR "unknown cmd '#{cmd}' for layer '#{layer.name}'", indent - - update: (dt, group=@tree) => - if group == false - return - - for layer in *group - if layer.update - layer\update dt, @\update - elseif layer.type == "open" - @update dt, layer - - draw: (group=@tree) => - if group == false - return - elseif group == @tree - love.graphics.scale 4 - - for layer in *group - if layer.draw - layer\draw @\draw - elseif layer.image - {:image, :ox, :oy} = layer - love.graphics.setColor 255, 255, 255, layer.opacity or 255 - love.graphics.draw image, x, y, nil, nil, nil, ox, oy - elseif layer.type == "open" - @draw layer - - { - :PSDScene, - } - - -Seeing that everything was (and is) going very smoothly up to this point, -I decided to "end" the test phase and finalize the decision to roll out my own engine. diff --git a/root/blog/ludum_dare_33_postmortem/mmm$tpl -> text$markdown.md b/root/blog/ludum_dare_33_postmortem/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..30d89af --- /dev/null +++ b/root/blog/ludum_dare_33_postmortem/mmm$tpl -> text$markdown.md @@ -0,0 +1,96 @@ +So, LD33 is over, and once again I made something: [*The Monster Within*][entry]. + +# Theme +The theme was *You are the Monster*, and I wanted to really incorporate the theme into the gameplay mechanics for once +(well yeah, [Curved Curse][curcur] did that, but the topic was very broad and there was no way but incorporate it into the gameplay itself). + +Many games I have seen took the theme quite literally and made the main character a monster: + +![Credit: @RedOshal][smert.png] +[*image by @RedOshal*][smert_src] + +Although you play a monster in *The Monster Within*, I took the theme a bit further. +The theme reminded me of an exclamated "*Look at yourself! You've become a Monster!*", something a movie wife might say to her increasingly out-of-control husband who just killed the neighbor that found out about the family's dark secret. + +The idea I came up with was the following: your main objective is to eliminate enemies from within a crowd of mostly civilians (in a generic top-down action game). However you turn into a Monster whenever you kill someone, which grants you a lot more power, but also impairs your senses; you can no longer differentiate between civilians and enemies. +As a result, I figured, people would have to decide between two playstyles, going on a rampage and killing as many people as possible, regardless of their type, or trying to play strategically by memorizing the enemies in the crowd. + +![split view][split.png] +*The Monster Within, normal and beast mode* + +To make playing in "Beast Mode" more appealing I increased the primary attack (punch) range and added a secondary lunge attack that is exclusive to that mode. This, I hope, tempts players to make use of the beast mode and facilitates players stopping to play for the original objective - eliminating enemies - and instead try to kill as many people as possible (which is an intended effect). + +To emphasize the two approaches, I introduced a dual scoring system; there is a "good" score that you can increase by eliminating enemies that is penalized whenever you kill a civilian but there is also an "evil" score that increases by the same amount regardless of the type of character you killed. +To balance the two, killing enemies yields more "good" points than "bad" ones, so both options can be viable. + +As the current comments on the [ludum dare entry page][entry] show, not everyone understood what I was trying to achieve: + +>It was fun although I didn't really like the mechanic where everyone turns into ghosts; it requires some ridiculous amount of memorization in order to get a good score, so I just ran around punching everyone indiscriminately. + +Although it seems *charliecarlo* was completely oblivious to my actual intentions with the core mechanic, which always feels a bit bad, he perfectly demonstrated that my idea worked out; his character let the *monster within* loose and went on a bloody rampage. + +>Different between beast and human score was initially confusing. Then again, that fits the theme well, a black box morality system. + +>I like the concept, the art is nice and I killed 50 innocent souls! - Cool game! + +So overall I am happy with how the mechanic turned out and was received; the three weeks of rating will hopefully yield more critique and comments. + +# Techology + +## Moonscript +Although I have been working on a networked game engine on top of [LÖVE][love] in moonscript, this is the first **complete** game that I write in [moonscript][moonscript]. +Writing aforementioned engine definetely helped me form some habits that sped up development for this game. +*The Monster Within* turned out to be an amazingly small game at 768 lines of code (excluding libraries); [Curved Curse][curcur] counted 1160. + +Every time I had to read or write Lua code (for example my older library, `st8`, which still has hiccups that I needed to iron out) the syntax seemed extremely cumbersome and restrictive. +After over a month, moonscript is still fun to write and read and I the decision to give it a shot was definetely more than worth it. Thank you leafo! + +## Steering Behaviors +A few months back I stumbled upon the [very nice series *Understanding Steering Behaviors*][steering] on *tutsplus.com*. +I used those guides, alongside the sixth chapter of *Daniel Shiffman*'s *The Nature of Code*, [*Autonomous Agents*][autonom], to implement the character AI for the enemies and civilians. + +In particular, I used the `wander`, `flee` (from the player, when he is in beast mode), `collision avoidance` and the `seperation` behaviors to make the characters move around in a more or less natural and pleasant-looking fashion. + +The implementation consists of just a few lines of vector math and the results are surprisingly lifelike for the very little effort I had to put into it. + +## Box2D +I was very unsure whether I should roll out my own simple physics system with a little Vector math, or whether I should use Box2d (which ships with LÖVE anyway). +I opted to choose `Box2D` because that would enable things like destructable environments (like houses being knocked away) and novel interactions in more carefully designed environments later down the road. + +## Optimization +I didn't really optimize anything, and if I didn't know it doesn't matter at the current level scale, I would have long added a spatial hash system, stopped simulating characters that are long out of view or at the very least culled the map. +However I worked so slowly on the first two days that there really wasn't any time left for that sort of thing, and most of the game only started working on the last day so there wasn't a lot of optimization possible before that point anyway. +If I continue working on this project, Optimization is one of the first things I will deal with. + +# Productivity +This Ludum Dare hit me entirely unprepared, I had completely forgotten about the date and only noticed a day prior. +I was initially very unsure whether to participate at all and also couldn't reach my artist from last year's game. +I put out a tweet and a post to [r/gamedev][rgamedev] and `stewartisme` contacted me as I was sleeping after looking at the theme at 3AM. +Still, I wasn't very motivated and worked slowly, procrastinated a lot and overall didn't really 'get into it'. +It amazes me that the game even turned out playable and with an acceptable look in general, but on the last day we really did work until the last minute, and as usual 90% of the perceived complete-ness were achieved in the last 10% of the time. + +# Future? +I'm not sure whether this project will continue, but I have a few ideas on how to improve the game. +In particular, I would like to add a Highscores table. +Because every *The Monster Within* run yields two scores, there are multiple options for this. +Aside from the obvious solution of two seperate high score tables, the most interesting option from a game design perspective, would be to have a single table, and to enter whichever score is higher there. +The entries could be colored white and red, denoting whether the player followed the "good" objective or let himself get carried away. +It would probably be required to fine tune the scoring system so that both playstyles are equally hard to succeed in. + +You can check out *The Monster Within* on the [Ludum Dare entry page][entry], [on itch.io][itch.io] or [view the source code on github][repo]. + +[entry]: http://ludumdare.com/compo/ludum-dare-33/?action=preview&uid=28620 +[itch.io]: http://s0lll0s.itch.io/the-monster-within +[repo]: https://github.com/s-ol/ld33 +[curcur]: http://s0lll0s.itch.io/curved-curse + +[smert_src]: http://ludumdare.com/compo/2015/08/22/what-i-imagine-most-people-are-doing-with-the-theme/ + +[love]: https://love2d.org +[moonscript]: https://moonscript.org +[steering]: http://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732 +[autonom]: http://natureofcode.com/book/chapter-6-autonomous-agents/ +[rgamedev]: https://reddit.com/r/gamedev + +[split.png]: {{split+URL -> image/png}} +[split.png]: {{smert+URL -> image/png}} diff --git a/root/blog/ludum_dare_33_postmortem/smert/image$png.png b/root/blog/ludum_dare_33_postmortem/smert/image$png.png new file mode 100755 index 0000000..612695c Binary files /dev/null and b/root/blog/ludum_dare_33_postmortem/smert/image$png.png differ diff --git a/root/blog/ludum_dare_33_postmortem/split/image$png.png b/root/blog/ludum_dare_33_postmortem/split/image$png.png new file mode 100755 index 0000000..0951620 Binary files /dev/null and b/root/blog/ludum_dare_33_postmortem/split/image$png.png differ diff --git a/root/blog/ludum_dare_33_postmortem/text$markdown.md b/root/blog/ludum_dare_33_postmortem/text$markdown.md deleted file mode 100644 index 9671f26..0000000 --- a/root/blog/ludum_dare_33_postmortem/text$markdown.md +++ /dev/null @@ -1,96 +0,0 @@ -So, LD33 is over, and once again I made something: [*The Monster Within*][entry]. - -# Theme -The theme was *You are the Monster*, and I wanted to really incorporate the theme into the gameplay mechanics for once -(well yeah, [Curved Curse][curcur] did that, but the topic was very broad and there was no way but incorporate it into the gameplay itself). - -Many games I have seen took the theme quite literally and made the main character a monster: - -![Credit: @RedOshal][smert.png] -[*image by @RedOshal*][smert_src] - -Although you play a monster in *The Monster Within*, I took the theme a bit further. -The theme reminded me of an exclamated "*Look at yourself! You've become a Monster!*", something a movie wife might say to her increasingly out-of-control husband who just killed the neighbor that found out about the family's dark secret. - -The idea I came up with was the following: your main objective is to eliminate enemies from within a crowd of mostly civilians (in a generic top-down action game). However you turn into a Monster whenever you kill someone, which grants you a lot more power, but also impairs your senses; you can no longer differentiate between civilians and enemies. -As a result, I figured, people would have to decide between two playstyles, going on a rampage and killing as many people as possible, regardless of their type, or trying to play strategically by memorizing the enemies in the crowd. - -![split view][split.png] -*The Monster Within, normal and beast mode* - -To make playing in "Beast Mode" more appealing I increased the primary attack (punch) range and added a secondary lunge attack that is exclusive to that mode. This, I hope, tempts players to make use of the beast mode and facilitates players stopping to play for the original objective - eliminating enemies - and instead try to kill as many people as possible (which is an intended effect). - -To emphasize the two approaches, I introduced a dual scoring system; there is a "good" score that you can increase by eliminating enemies that is penalized whenever you kill a civilian but there is also an "evil" score that increases by the same amount regardless of the type of character you killed. -To balance the two, killing enemies yields more "good" points than "bad" ones, so both options can be viable. - -As the current comments on the [ludum dare entry page][entry] show, not everyone understood what I was trying to achieve: - ->It was fun although I didn't really like the mechanic where everyone turns into ghosts; it requires some ridiculous amount of memorization in order to get a good score, so I just ran around punching everyone indiscriminately. - -Although it seems *charliecarlo* was completely oblivious to my actual intentions with the core mechanic, which always feels a bit bad, he perfectly demonstrated that my idea worked out; his character let the *monster within* loose and went on a bloody rampage. - ->Different between beast and human score was initially confusing. Then again, that fits the theme well, a black box morality system. - ->I like the concept, the art is nice and I killed 50 innocent souls! - Cool game! - -So overall I am happy with how the mechanic turned out and was received; the three weeks of rating will hopefully yield more critique and comments. - -# Techology - -## Moonscript -Although I have been working on a networked game engine on top of [LÖVE][love] in moonscript, this is the first **complete** game that I write in [moonscript][moonscript]. -Writing aforementioned engine definetely helped me form some habits that sped up development for this game. -*The Monster Within* turned out to be an amazingly small game at 768 lines of code (excluding libraries); [Curved Curse][curcur] counted 1160. - -Every time I had to read or write Lua code (for example my older library, `st8`, which still has hiccups that I needed to iron out) the syntax seemed extremely cumbersome and restrictive. -After over a month, moonscript is still fun to write and read and I the decision to give it a shot was definetely more than worth it. Thank you leafo! - -## Steering Behaviors -A few months back I stumbled upon the [very nice series *Understanding Steering Behaviors*][steering] on *tutsplus.com*. -I used those guides, alongside the sixth chapter of *Daniel Shiffman*'s *The Nature of Code*, [*Autonomous Agents*][autonom], to implement the character AI for the enemies and civilians. - -In particular, I used the `wander`, `flee` (from the player, when he is in beast mode), `collision avoidance` and the `seperation` behaviors to make the characters move around in a more or less natural and pleasant-looking fashion. - -The implementation consists of just a few lines of vector math and the results are surprisingly lifelike for the very little effort I had to put into it. - -## Box2D -I was very unsure whether I should roll out my own simple physics system with a little Vector math, or whether I should use Box2d (which ships with LÖVE anyway). -I opted to choose `Box2D` because that would enable things like destructable environments (like houses being knocked away) and novel interactions in more carefully designed environments later down the road. - -## Optimization -I didn't really optimize anything, and if I didn't know it doesn't matter at the current level scale, I would have long added a spatial hash system, stopped simulating characters that are long out of view or at the very least culled the map. -However I worked so slowly on the first two days that there really wasn't any time left for that sort of thing, and most of the game only started working on the last day so there wasn't a lot of optimization possible before that point anyway. -If I continue working on this project, Optimization is one of the first things I will deal with. - -# Productivity -This Ludum Dare hit me entirely unprepared, I had completely forgotten about the date and only noticed a day prior. -I was initially very unsure whether to participate at all and also couldn't reach my artist from last year's game. -I put out a tweet and a post to [r/gamedev][rgamedev] and `stewartisme` contacted me as I was sleeping after looking at the theme at 3AM. -Still, I wasn't very motivated and worked slowly, procrastinated a lot and overall didn't really 'get into it'. -It amazes me that the game even turned out playable and with an acceptable look in general, but on the last day we really did work until the last minute, and as usual 90% of the perceived complete-ness were achieved in the last 10% of the time. - -# Future? -I'm not sure whether this project will continue, but I have a few ideas on how to improve the game. -In particular, I would like to add a Highscores table. -Because every *The Monster Within* run yields two scores, there are multiple options for this. -Aside from the obvious solution of two seperate high score tables, the most interesting option from a game design perspective, would be to have a single table, and to enter whichever score is higher there. -The entries could be colored white and red, denoting whether the player followed the "good" objective or let himself get carried away. -It would probably be required to fine tune the scoring system so that both playstyles are equally hard to succeed in. - -You can check out *The Monster Within* on the [Ludum Dare entry page][entry], [on itch.io][itch.io] or [view the source code on github][repo]. - -[entry]: http://ludumdare.com/compo/ludum-dare-33/?action=preview&uid=28620 -[itch.io]: http://s0lll0s.itch.io/the-monster-within -[repo]: https://github.com/s-ol/ld33 -[curcur]: http://s0lll0s.itch.io/curved-curse - -[smert_src]: http://ludumdare.com/compo/2015/08/22/what-i-imagine-most-people-are-doing-with-the-theme/ - -[love]: https://love2d.org -[moonscript]: https://moonscript.org -[steering]: http://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732 -[autonom]: http://natureofcode.com/book/chapter-6-autonomous-agents/ -[rgamedev]: https://reddit.com/r/gamedev - -[split.png]: {{site.url}}/assets/{{page.imgid}}/split.png -[smert.png]: {{site.url}}/assets/{{page.imgid}}/smert.png diff --git a/root/blog/stencils_101/balistencil_final/image$jpeg.jpg b/root/blog/stencils_101/balistencil_final/image$jpeg.jpg new file mode 100755 index 0000000..4e1ed7b Binary files /dev/null and b/root/blog/stencils_101/balistencil_final/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/killbill_final/image$jpeg.jpg b/root/blog/stencils_101/killbill_final/image$jpeg.jpg new file mode 100755 index 0000000..5e6fd9e Binary files /dev/null and b/root/blog/stencils_101/killbill_final/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/killbill_progress/image$jpeg.jpg b/root/blog/stencils_101/killbill_progress/image$jpeg.jpg new file mode 100755 index 0000000..a8e8560 Binary files /dev/null and b/root/blog/stencils_101/killbill_progress/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/killbillstencil/image$png.png b/root/blog/stencils_101/killbillstencil/image$png.png new file mode 100755 index 0000000..21a657f Binary files /dev/null and b/root/blog/stencils_101/killbillstencil/image$png.png differ diff --git a/root/blog/stencils_101/mmm$tpl -> text$markdown.md b/root/blog/stencils_101/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..0e37596 --- /dev/null +++ b/root/blog/stencils_101/mmm$tpl -> text$markdown.md @@ -0,0 +1,95 @@ +So, for the first non-meta post (don't mind this line), I'm gonna walk you through my stencil creation process. + +# Design +Right now, I design all my stencils in photoshop (CS6, running in wine). +If I get better at hand drawing maybe one day I will sketch them up freehand right on the material but as of now I only do that for text. + +As an example, let's take the Kill Bill Stencil I did a few days ago: + +![the Bride from Kill Bill][killbillfinal.jpg] + +The first thing I did was create a new file in Photoshop, with the dimensions set to what I can print with my inkjet printer (International - A4). +For the design process the canvas size doesn't really matter anyway and I like to work on a familiar size so I can judge how fine the details should be, also I print the images via my phone and so I need to have them in A4 size to get consistent results later anyway. + +The next thing I did was look for a picture to use, after a (very) quick google images tour I settled on this image: + +![Kill Bill movie poster][movieposter.jpg] + +In order to turn this into a stencil, I used the *Threshold* Image Adjustment, but before that I cut away all the background. +With the Magic Wand and Quick Selection, I removed the black bar and yellow background. +Because I am living in constant fear of losing work, I duplicated the layer and then popped open the *Threshold* Dialog (`Image > Adjustements > Threshold`). +I played around with the slider until I got a good ratio of light and shadow and then applied the changes. + +Often some parts of the image require a different threshold setting than other parts (for example the faces often have lower contrast and require a different threshold value). +In those cases, I just duplicate the original resource layer, find the other value and then cut away the pieces that I don't need +(because I am afraid of commitment I sometimes end up masking the layers with vector masks instead). + +After this step, there will be a lot of tiny artifacts and bubbles that are way too tiny to be cut out (or impossible because they would form tiny islands). +For the Kill Bill Stencil, I went over __all__ of those by hand on another layer with the pencil tool (the brush is terrible for stencilwork because you want a hard edge to cut later, not a gradient around what you drew). +However later on I realized that there is a good way to reliably eliminate this noise; all you need to do is apply a blur (*Gaussian Blur* is very effective and configurable, `Filter > Blur > Gaussian Blur`) and then re-apply *Threshold*. +You can play around with this process a bit to get a feeling for how hard you need to blur to eliminate the noise. + +You will still need to manually touch up the stencil though, at least to look for and fix *Islands*; +In my case, I spraypaint black color onto a white background, so everything that is black gets cut out. +This means that every white part that is surrounded completely by black is going to fall out of the stencil together with the black aswell. +Larger islands may be taped to the surface you are spraying on for art, but it's best to avoid Islands wherever possible (and especially small ones). + +To visualize the final stencil, I have looked up the exact colors of the spraypaint I own at the manufacturers website and saved them as swatches in my photoshop. +I use those to put a background behind the whole image and to color layers that I want to spraypaint in color later. + +![Final Stencil in PS][killbillstencil.png] + +One problem when you like working non-destructively on many layers, as I do, is that you normally cannot remove something on a layer below by painting over it. +There are two options, either you can just draw the background color, which means you will have to flatten the image later to get the outline, or you can use the *Layer Blend Modes* to your advantage: +What I did was put all the layers in a Layer Group, and set that groups *Blend Mode* to *Screen*. +This will result in everything Black staying Black and everything White turning into transparent, so now you can just paint white on a layer above one that is black to erase the one below. + +# Printing +To print the stencil out, I apply a *Stroke* to all the seperate color's layers (`Layer Styles > Stroke`) and turn down the *Fill* value to 0%. +That way I save toner when printing and have a clear outline guide to cut at. +If one color is scattered across layers I either merge them or put them in a group, then apply the styles to that group instead. + +Because my printer's drivers are weird I print with the phone app. I save every color's outline as a seperate JPG, push them to my phone and print them. +I used to print on standard A4 paper, tape that to thicker cardboard and cut, but I realized that my printer can actually handle the thicker cardbord paper I have. +That makes cutting a lot easier. + +# Cutting +Cutting is very straightforward, I just try to get as many details as possible. +I use a standard box cutter but a scalpel / x-acto knife would probably work even better. +I have a rubber cutting mat that is specifically made for this and works very well. + +![Cutting Progress][killbillprogress.jpg] + +For small round holes I use an old screwdriver part that turned out to be a perfect hole-punching tool and hit it into the paper with a hammer (on a piece of wood). + +# Painting +To hold down the stencils I usually tape them to the surface with painters tape. +Sometimes I just hold them or press parts flat. +If there are small, flimsy pieces inside that won't stay on the surface or that would get blown to the side or up by the aerosol, I make a small loop out of the tape and stick it to the surface with that makeshift double-sided tape. + +Then I just grab the spraycans and paint the stencil with small, short strokes. +I try not to hit the same spot too often or too long so the paint doesn't flow beneath the stencil or take too long to dry. + +# Results +Here are some of my stencils: + +![The Bride][killbillfinal.jpg] +![Electronic Revolution][elerev.jpg] +![Suits][suits.jpg] +![Balisong][balifinal.jpg] + +I tweet all my daily stencils with the [hashtag #astenciladay on twitter][#astenciladay] and post them in the [*Daily Stencil Art* streak on *streak.club*][dailystencil]. + +If you want any of the `psd`s or the printable outline `jpg`s, [shoot me a tweet][twitter]! + +[#astenciladay]: https://twitter.com/hashtag/astenciladay +[dailystencil]: https://streak.club/s/614/daily-stencil-art +[twitter]: https://twitter.com/S0lll0s + +[killbillstencil.png]: {{killbillstencil+URL -> image/png}} +[killbillfinal.jpg]: {{killbill_final+URL -> image/jpeg}} +[movieposter.jpg]: {{poster+URL -> image/jpeg}} +[killbillprogress.jpg]: {{killbill_progress+URL -> image/jpeg}} +[balifinal.jpg]: {{balistencil_final+URL -> image/jpeg}} +[elerev.jpg]: {{technofist_final+URL -> image/jpeg}} +[suits.jpg]: {{suits_final+URL -> image/jpeg}} diff --git a/root/blog/stencils_101/poster/image$jpeg.jpg b/root/blog/stencils_101/poster/image$jpeg.jpg new file mode 100755 index 0000000..8192ed4 Binary files /dev/null and b/root/blog/stencils_101/poster/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/suits_final/image$jpeg.jpg b/root/blog/stencils_101/suits_final/image$jpeg.jpg new file mode 100755 index 0000000..332d7e4 Binary files /dev/null and b/root/blog/stencils_101/suits_final/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/technofist_final/image$jpeg.jpg b/root/blog/stencils_101/technofist_final/image$jpeg.jpg new file mode 100755 index 0000000..f73833b Binary files /dev/null and b/root/blog/stencils_101/technofist_final/image$jpeg.jpg differ diff --git a/root/blog/stencils_101/text$markdown.md b/root/blog/stencils_101/text$markdown.md deleted file mode 100644 index ead2a98..0000000 --- a/root/blog/stencils_101/text$markdown.md +++ /dev/null @@ -1,95 +0,0 @@ -So, for the first non-meta post (don't mind this line), I'm gonna walk you through my stencil creation process. - -# Design -Right now, I design all my stencils in photoshop (CS6, running in wine). -If I get better at hand drawing maybe one day I will sketch them up freehand right on the material but as of now I only do that for text. - -As an example, let's take the Kill Bill Stencil I did a few days ago: - -![the Bride from Kill Bill][killbillfinal.jpg] - -The first thing I did was create a new file in Photoshop, with the dimensions set to what I can print with my inkjet printer (International - A4). -For the design process the canvas size doesn't really matter anyway and I like to work on a familiar size so I can judge how fine the details should be, also I print the images via my phone and so I need to have them in A4 size to get consistent results later anyway. - -The next thing I did was look for a picture to use, after a (very) quick google images tour I settled on this image: - -![Kill Bill movie poster][movieposter.jpg] - -In order to turn this into a stencil, I used the *Threshold* Image Adjustment, but before that I cut away all the background. -With the Magic Wand and Quick Selection, I removed the black bar and yellow background. -Because I am living in constant fear of losing work, I duplicated the layer and then popped open the *Threshold* Dialog (`Image > Adjustements > Threshold`). -I played around with the slider until I got a good ratio of light and shadow and then applied the changes. - -Often some parts of the image require a different threshold setting than other parts (for example the faces often have lower contrast and require a different threshold value). -In those cases, I just duplicate the original resource layer, find the other value and then cut away the pieces that I don't need -(because I am afraid of commitment I sometimes end up masking the layers with vector masks instead). - -After this step, there will be a lot of tiny artifacts and bubbles that are way too tiny to be cut out (or impossible because they would form tiny islands). -For the Kill Bill Stencil, I went over __all__ of those by hand on another layer with the pencil tool (the brush is terrible for stencilwork because you want a hard edge to cut later, not a gradient around what you drew). -However later on I realized that there is a good way to reliably eliminate this noise; all you need to do is apply a blur (*Gaussian Blur* is very effective and configurable, `Filter > Blur > Gaussian Blur`) and then re-apply *Threshold*. -You can play around with this process a bit to get a feeling for how hard you need to blur to eliminate the noise. - -You will still need to manually touch up the stencil though, at least to look for and fix *Islands*; -In my case, I spraypaint black color onto a white background, so everything that is black gets cut out. -This means that every white part that is surrounded completely by black is going to fall out of the stencil together with the black aswell. -Larger islands may be taped to the surface you are spraying on for art, but it's best to avoid Islands wherever possible (and especially small ones). - -To visualize the final stencil, I have looked up the exact colors of the spraypaint I own at the manufacturers website and saved them as swatches in my photoshop. -I use those to put a background behind the whole image and to color layers that I want to spraypaint in color later. - -![Final Stencil in PS][killbillstencil.png] - -One problem when you like working non-destructively on many layers, as I do, is that you normally cannot remove something on a layer below by painting over it. -There are two options, either you can just draw the background color, which means you will have to flatten the image later to get the outline, or you can use the *Layer Blend Modes* to your advantage: -What I did was put all the layers in a Layer Group, and set that groups *Blend Mode* to *Screen*. -This will result in everything Black staying Black and everything White turning into transparent, so now you can just paint white on a layer above one that is black to erase the one below. - -# Printing -To print the stencil out, I apply a *Stroke* to all the seperate color's layers (`Layer Styles > Stroke`) and turn down the *Fill* value to 0%. -That way I save toner when printing and have a clear outline guide to cut at. -If one color is scattered across layers I either merge them or put them in a group, then apply the styles to that group instead. - -Because my printer's drivers are weird I print with the phone app. I save every color's outline as a seperate JPG, push them to my phone and print them. -I used to print on standard A4 paper, tape that to thicker cardboard and cut, but I realized that my printer can actually handle the thicker cardbord paper I have. -That makes cutting a lot easier. - -# Cutting -Cutting is very straightforward, I just try to get as many details as possible. -I use a standard box cutter but a scalpel / x-acto knife would probably work even better. -I have a rubber cutting mat that is specifically made for this and works very well. - -![Cutting Progress][killbillprogress.jpg] - -For small round holes I use an old screwdriver part that turned out to be a perfect hole-punching tool and hit it into the paper with a hammer (on a piece of wood). - -# Painting -To hold down the stencils I usually tape them to the surface with painters tape. -Sometimes I just hold them or press parts flat. -If there are small, flimsy pieces inside that won't stay on the surface or that would get blown to the side or up by the aerosol, I make a small loop out of the tape and stick it to the surface with that makeshift double-sided tape. - -Then I just grab the spraycans and paint the stencil with small, short strokes. -I try not to hit the same spot too often or too long so the paint doesn't flow beneath the stencil or take too long to dry. - -# Results -Here are some of my stencils: - -![The Bride][killbillfinal.jpg] -![Electronic Revolution][elerev.jpg] -![Suits][suits.jpg] -![Balisong][balifinal.jpg] - -I tweet all my daily stencils with the [hashtag #astenciladay on twitter][#astenciladay] and post them in the [*Daily Stencil Art* streak on *streak.club*][dailystencil]. - -If you want any of the `psd`s or the printable outline `jpg`s, [shoot me a tweet][twitter]! - -[#astenciladay]: https://twitter.com/hashtag/astenciladay -[dailystencil]: https://streak.club/s/614/daily-stencil-art -[twitter]: https://twitter.com/S0lll0s - -[killbillstencil.png]: {{site.url}}/assets/{{page.imgid}}/killbillstencil.png -[killbillfinal.jpg]: {{site.url}}/assets/{{page.imgid}}/killbill_final.jpg -[movieposter.jpg]: {{site.url}}/assets/{{page.imgid}}/poster.jpg -[killbillprogress.jpg]: {{site.url}}/assets/{{page.imgid}}/killbill_progress.jpg -[balifinal.jpg]: {{site.url}}/assets/{{page.imgid}}/balistencil_final.jpg -[elerev.jpg]: {{site.url}}/assets/{{page.imgid}}/technofist_final.jpg -[suits.jpg]: {{site.url}}/assets/{{page.imgid}}/suits_final.jpg diff --git a/root/blog/stretching_gates/case/image$jpeg.jpg b/root/blog/stretching_gates/case/image$jpeg.jpg new file mode 100644 index 0000000..e1222dc Binary files /dev/null and b/root/blog/stretching_gates/case/image$jpeg.jpg differ diff --git a/root/blog/stretching_gates/crude/image$png.png b/root/blog/stretching_gates/crude/image$png.png new file mode 100644 index 0000000..a53df51 Binary files /dev/null and b/root/blog/stretching_gates/crude/image$png.png differ diff --git a/root/blog/stretching_gates/mmm$tpl -> text$markdown.md b/root/blog/stretching_gates/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..d50a5a8 --- /dev/null +++ b/root/blog/stretching_gates/mmm$tpl -> text$markdown.md @@ -0,0 +1,92 @@ +As mentioned in the last post, there was some room for improvement in the last iteration of the +trigger/divider circuit. While the divider was working great as a clock source for the drum +machine, the signal output by the comparator was very short and sometimes got triggered twice +with one acoustic hit on the piezo when the reference voltage was not perfectly tuned. +On the other hand the outputs of the 4017 always stay on or off for a whole step. + +While the long steps can be useful to make an oscillator play long notes, shorter pulses each step +are much more interesting to create drum-ish sounds. +Here's a crude drawing of how what the circuit was doing vs how it's supposed to work: + +![some graphs][crude.png] + +The black lines are the signal levels 'as they used to be': you can see that the comparator output +has very short pulses of more or less random duration, the /2 output is on half of the time, the /3 +one third of the steps and so on. +Given some way of creating the blue signal in the top diagram, that stays on a specified amount of +time after each trigger and only then drops back down, the other two blue graphs are very easy to +obtain by simply logical-AND-ing the shaped pulse signal and the divided signal for each divison. +Conveniently, there is a CMOS chip with four AND gates that are more than fast enough: the 4081. + +## hold on +The only missing part is the one that needs to hold the signal for a specified time on each trigger. +Well, the famous 555 Timer IC has our back: in the *monostable Configuration* it will do just that. +Here's a schematic of the basic circuit (pic taken from [here][555-src]): + +![monostable 555 circuit][monostable.jpg] + +This is really half as bad as it looks, but the details are better read up on elsewhere. +Basically, whenever the signal on the trigger (pin 2) goes __low__, the output (pin 3) goes high +and the capacitor between threshold (pin 6) and ground is charged. +When it reaches a certain charge, the output drops back to low and the capacitor is drained. + +This is exactly what is needed, except that the triggers has to go low here to start the timer. +To fix this, I simply swapped the inverting and non-inverting inputs of the comparator, so that it +always outputs the opposite result. + +## putting it together +Here's the final schematic as I built it: + +![the final schematic][schematic.jpg] + +Some things you may notice: + +1. I put a potentiometer into the 555s charging path so that the pulse length can be adjusted. +2. I added a switch that allows me to decide whether I want to AND the divided outputs with the + generated pulse, or basically disable that part by putting 9V there, which basically turns the + AND gate into a normal wire. +3. There are diodes on the reset pins so that I can later expand this with a reset input jack. +4. I am using both halves of the LM393 with the inputs swapped: the positive-going pulse goes to an + LED that shows me the 'raw' incoming signal, and the negative goes to the 555, with another LED + showing the 'shaped' one. With piezo triggers it is impossible to even see the raw LED turn on, + but if I use this with another clock source (LFO for example) it might be useful. +5. We're kind of low on switches so I scrapped that part, but I wanted another switch to choose + between the 555 output or the other LM393 output to be fed into the 4017 dividers. That way I + would've gotten to keep the beat-skipping properties independently of the gate length control, + but now I have to lower the gate length to minimum to disable the 555s debouncing effects. + +## wrapping it up +After this was all working on the breadboard, I started to solder a second version on stripboard. +Before finishing the design I sketched some stripboard layouts on a piece of paper, but in the end I +threw all care overboard and just placed components on the stripboard. + +![half-done stripboard][stripboard.jpg] + +I cut apart a large IC socket and soldered the two halfes to the sides of the board to simplify +testing and panel wiring, but I'm not sure if it was the best idea bceause the sockets aren't really +made to be used over and over and the wires dont hold too well. I'm thinking I might tape over the +sockets once all the cables are in place and tested. + +[Juan][juan] found this great old Video casette case as a chassis and I really liked it. +We used the Dremel that we had luckily gotten our hands on and started drilling holes for the audio +jacks with a template made from paper. + +![the case][case.jpg] + +The inside also needed some plastic spines ground away to make room for the jacks, but the Dremel +made quick work of all that. Juan finished the top of the case with mounting holes for the two +potentiometers, the input jack, the switch, and two hot-glue-covered holes for the LEDs to shine +through. + +
+ Finished Case +
+ +[juan]: https://twitter.com/juanorloz +[555-src]: https://electrosome.com/monostable-multivibrator-555-timer/ + +[crude.png]: {{crude+URL -> image/png}} +[schematic.jpg]: {{schematic+URL -> image/jpeg}} +[stripboard.jpg]: {{stripboard+URL -> image/jpeg}} +[case.jpg]: {{case+URL -> image/jpeg}} +[monostable.jpg]: https://electrosome.com/wp-content/uploads/2013/05/Monostable-Multivibrator-using-555-Timer-Circuit-Diagram.jpg diff --git a/root/blog/stretching_gates/schematic/image$jpeg.jpg b/root/blog/stretching_gates/schematic/image$jpeg.jpg new file mode 100644 index 0000000..64bd239 Binary files /dev/null and b/root/blog/stretching_gates/schematic/image$jpeg.jpg differ diff --git a/root/blog/stretching_gates/stripboard/image$jpeg.jpg b/root/blog/stretching_gates/stripboard/image$jpeg.jpg new file mode 100644 index 0000000..f719c80 Binary files /dev/null and b/root/blog/stretching_gates/stripboard/image$jpeg.jpg differ diff --git a/root/blog/stretching_gates/text$markdown.md b/root/blog/stretching_gates/text$markdown.md deleted file mode 100644 index c288350..0000000 --- a/root/blog/stretching_gates/text$markdown.md +++ /dev/null @@ -1,94 +0,0 @@ -As mentioned in the last post, there was some room for improvement in the last iteration of the -trigger/divider circuit. While the divider was working great as a clock source for the drum -machine, the signal output by the comparator was very short and sometimes got triggered twice -with one acoustic hit on the piezo when the reference voltage was not perfectly tuned. -On the other hand the outputs of the 4017 always stay on or off for a whole step. - -While the long steps can be useful to make an oscillator play long notes, shorter pulses each step -are much more interesting to create drum-ish sounds. -Here's a crude drawing of how what the circuit was doing vs how it's supposed to work: - -![some graphs][crude.png] - -The black lines are the signal levels 'as they used to be': you can see that the comparator output -has very short pulses of more or less random duration, the /2 output is on half of the time, the /3 -one third of the steps and so on. -Given some way of creating the blue signal in the top diagram, that stays on a specified amount of -time after each trigger and only then drops back down, the other two blue graphs are very easy to -obtain by simply logical-AND-ing the shaped pulse signal and the divided signal for each divison. -Conveniently, there is a CMOS chip with four AND gates that are more than fast enough: the 4081. - -## hold on -The only missing part is the one that needs to hold the signal for a specified time on each trigger. -Well, the famous 555 Timer IC has our back: in the *monostable Configuration* it will do just that. -Here's a schematic of the basic circuit (pic taken from [here][555-src]): - -![monostable 555 circuit][monostable.jpg] - -This is really half as bad as it looks, but the details are better read up on elsewhere. -Basically, whenever the signal on the trigger (pin 2) goes __low__, the output (pin 3) goes high -and the capacitor between threshold (pin 6) and ground is charged. -When it reaches a certain charge, the output drops back to low and the capacitor is drained. - -This is exactly what is needed, except that the triggers has to go low here to start the timer. -To fix this, I simply swapped the inverting and non-inverting inputs of the comparator, so that it -always outputs the opposite result. - -## putting it together -Here's the final schematic as I built it: - -![the final schematic][schematic.jpg] - -Some things you may notice: - -1. I put a potentiometer into the 555s charging path so that the pulse length can be adjusted. -2. I added a switch that allows me to decide whether I want to AND the divided outputs with the - generated pulse, or basically disable that part by putting 9V there, which basically turns the - AND gate into a normal wire. -3. There are diodes on the reset pins so that I can later expand this with a reset input jack. -4. I am using both halves of the LM393 with the inputs swapped: the positive-going pulse goes to an - LED that shows me the 'raw' incoming signal, and the negative goes to the 555, with another LED - showing the 'shaped' one. With piezo triggers it is impossible to even see the raw LED turn on, - but if I use this with another clock source (LFO for example) it might be useful. -5. We're kind of low on switches so I scrapped that part, but I wanted another switch to choose - between the 555 output or the other LM393 output to be fed into the 4017 dividers. That way I - would've gotten to keep the beat-skipping properties independently of the gate length control, - but now I have to lower the gate length to minimum to disable the 555s debouncing effects. - -## wrapping it up -After this was all working on the breadboard, I started to solder a second version on stripboard. -Before finishing the design I sketched some stripboard layouts on a piece of paper, but in the end I -threw all care overboard and just placed components on the stripboard. - -![half-done stripboard][stripboard.jpg] - -I cut apart a large IC socket and soldered the two halfes to the sides of the board to simplify -testing and panel wiring, but I'm not sure if it was the best idea bceause the sockets aren't really -made to be used over and over and the wires dont hold too well. I'm thinking I might tape over the -sockets once all the cables are in place and tested. - -[Juan][juan] found this great old Video casette case as a chassis and I really liked it. -We used the Dremel that we had luckily gotten our hands on and started drilling holes for the audio -jacks with a template made from paper. - -![the case][case.jpg] - -The inside also needed some plastic spines ground away to make room for the jacks, but the Dremel -made quick work of all that. Juan finished the top of the case with mounting holes for the two -potentiometers, the input jack, the switch, and two hot-glue-covered holes for the LEDs to shine -through. - -
- Finished Case -
- -[juan]: https://twitter.com/juanorloz -[555-src]: https://electrosome.com/monostable-multivibrator-555-timer/ - -[crude.png]: {{site.url}}/assets/{{page.imgid}}/crude.png -[schematic.jpg]: {{site.url}}/assets/{{page.imgid}}/schematic.jpg -[stripboard.jpg]: {{site.url}}/assets/{{page.imgid}}/stripboard.jpg -[case.jpg]: {{site.url}}/assets/{{page.imgid}}/case.jpg -[monostable.jpg]: https://electrosome.com/wp-content/uploads/2013/05/Monostable-Multivibrator-using-555-Timer-Circuit-Diagram.jpg - - diff --git a/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg b/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg new file mode 100644 index 0000000..dc4b14b Binary files /dev/null and b/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg differ diff --git a/root/blog/video_synth_research/mine/image$jpeg.jpg b/root/blog/video_synth_research/mine/image$jpeg.jpg new file mode 100644 index 0000000..3b4a61e Binary files /dev/null and b/root/blog/video_synth_research/mine/image$jpeg.jpg differ diff --git a/root/blog/video_synth_research/mmm$tpl -> text$markdown.md b/root/blog/video_synth_research/mmm$tpl -> text$markdown.md new file mode 100644 index 0000000..de46241 --- /dev/null +++ b/root/blog/video_synth_research/mmm$tpl -> text$markdown.md @@ -0,0 +1,124 @@ +When we started the *Synths and Stuff* project, we discussed how it would be cool to have video +synthesis to accompany the audio performance. In a modular synth setup, we would be able to patch +audio and control signals into the video phase to make music reactive visuals. + +## expensive toys +While I love video synthesis, and my last project before this [was sort of that][plonat-atek], I was +initially a bit worried about the complexity of it. +I had found out about [LZX Industries][lzx] a few months ago, who make amazing modular video synth +gear... that is very expensive. It looks amazing though: + + + +I think the price is probably justified, as a lot of engineering goes into making this work in the +first place, and it looks very clean, which I would attribute to high quality components. + +However, for our project we don't strive to create perfect and clean audio or video. +Glitches and noise are an important part of the analog aesthetic and make the results feel as +organic as they do. + +I also found the *3trins-RGB+1c*, which looks like a nifty little thing but is also way out of my +budget. + +## visualising another way +Reinforced with these thoughts I started looking for DIY video modules. At least in relation to +audio schematics, there is *very little* content on the internet. +However I did find a few good resources. + +There is a 2013 blog with only a few posts, but it does a great job of filtering out relevant +information in [this post summarizing forum gold][vfold]. + +This led me onto the track of the MC1377 chip, an RGB-to-PAL/NTSC video encoder IC. +At some point I found this video showcasing a video effect device based on it, the *Visualist*: + + + +The best thing is that there is [awesome documentation][visualist] (hotlinked from original dropbox, +I have a copy if it goes down) for this thing. +It's not very detailed but the circuit is rather minimal and the color logic easily removed. +The stripped down version that parses an incoming video signal brightness and encodes RGB values you +make from that as the signals scans over the screen is handleable even if not completely understood. + +To practice my understanding and work it into my brain, I broke the original schematic out into +logical units with single connections. + +My plan is to make the *Visualist* color logic, that pseudo-randomly assigns a color to each +brightness level in a 7-step scale that you can adjust into a small module that can be used, +but also mixed with other effects (perhaps an oscillator and external color input) so that we can +sync to our music control signals. + +![][schematic.png] +![][mine.jpg] + +If you look closely you can see that I left some parts out and added a bit of logic to allow setting +the amount of steps the brightness scale is sliced into. + +## OBS -2.3 +The other videoish thing we have going on sofar is this: + +
+ Video Sketch Titler +
+ +this *SONY Family Studio* 'Video Sketch Titler' is basically a little box that you connect inbetween +your video camera with some awesome family vacation clips on tape and your VHS recorder, which is +hooked up to your PC. + +You can then draw an amazing title screen over your video with this touchpad-ish device. +When you are ready, you rewind the camera to the beginning, press play and start recording on VHS at +the same time. Then you hit the 'fade in' and 'fade out' buttons on the Sketch Titler and go win +that home video contest. + +Well, this is how it's intended to be used anyway. If your camera doesn't work (like mine), you can +instead practice on a gray background: + +![][ich-bin-holz.jpg] + +So ideally, we can get a live camera as an input to this, and draw on it in *real time*! +Like an ancient livestreaming tool like OBS. +(and then hopefully we will also have a Visualist to either hook up before or after this device) + +Also some other people else has already circuit-bent this. +It looks amazing, so we might just give that a go aswell: + + + + +Since taking this for a spin and making a BOM for the *Visualist*, +I haven't spent any more time on the *Visualist* and turned to the audio side of things for now. +The next step on this front will probably be to lay out (parts of) the circuitry on stripboard and' +get ready to solder :) + +[plonat-atek]: https://s-ol.itch.io/plonat-atek +[lzx]: https://www.lzxindustries.net/ +[vfold]: https://vfoldsynth.wordpress.com/2013/01/23/hidden-stores-of-forum-gold/ +[visualist]: https://www.dropbox.com/s/uhjd2e6gur972yo/VisualistKl.pdf?dl=0 + +[schematic.png]: {{schematic+URL -> image/png}} +[mine.jpg]: {{mine+URL -> image/jpeg}} +[ich-bin-holz.jpg]: {{ich_bin_holz+URL -> image/jpeg}} + + diff --git a/root/blog/video_synth_research/schematic/image$png.png b/root/blog/video_synth_research/schematic/image$png.png new file mode 100644 index 0000000..6b8b4de Binary files /dev/null and b/root/blog/video_synth_research/schematic/image$png.png differ diff --git a/root/blog/video_synth_research/text$markdown.md b/root/blog/video_synth_research/text$markdown.md deleted file mode 100644 index d11aab4..0000000 --- a/root/blog/video_synth_research/text$markdown.md +++ /dev/null @@ -1,124 +0,0 @@ -When we started the *Synths and Stuff* project, we discussed how it would be cool to have video -synthesis to accompany the audio performance. In a modular synth setup, we would be able to patch -audio and control signals into the video phase to make music reactive visuals. - -## expensive toys -While I love video synthesis, and my last project before this [was sort of that][plonat-atek], I was -initially a bit worried about the complexity of it. -I had found out about [LZX Industries][lzx] a few months ago, who make amazing modular video synth -gear... that is very expensive. It looks amazing though: - - - -I think the price is probably justified, as a lot of engineering goes into making this work in the -first place, and it looks very clean, which I would attribute to high quality components. - -However, for our project we don't strive to create perfect and clean audio or video. -Glitches and noise are an important part of the analog aesthetic and make the results feel as -organic as they do. - -I also found the *3trins-RGB+1c*, which looks like a nifty little thing but is also way out of my -budget. - -## visualising another way -Reinforced with these thoughts I started looking for DIY video modules. At least in relation to -audio schematics, there is *very little* content on the internet. -However I did find a few good resources. - -There is a 2013 blog with only a few posts, but it does a great job of filtering out relevant -information in [this post summarizing forum gold][vfold]. - -This led me onto the track of the MC1377 chip, an RGB-to-PAL/NTSC video encoder IC. -At some point I found this video showcasing a video effect device based on it, the *Visualist*: - - - -The best thing is that there is [awesome documentation][visualist] (hotlinked from original dropbox, -I have a copy if it goes down) for this thing. -It's not very detailed but the circuit is rather minimal and the color logic easily removed. -The stripped down version that parses an incoming video signal brightness and encodes RGB values you -make from that as the signals scans over the screen is handleable even if not completely understood. - -To practice my understanding and work it into my brain, I broke the original schematic out into -logical units with single connections. - -My plan is to make the *Visualist* color logic, that pseudo-randomly assigns a color to each -brightness level in a 7-step scale that you can adjust into a small module that can be used, -but also mixed with other effects (perhaps an oscillator and external color input) so that we can -sync to our music control signals. - -![][schematic.png] -![][mine.jpg] - -If you look closely you can see that I left some parts out and added a bit of logic to allow setting -the amount of steps the brightness scale is sliced into. - -## OBS -2.3 -The other videoish thing we have going on sofar is this: - -
- Video Sketch Titler -
- -this *SONY Family Studio* 'Video Sketch Titler' is basically a little box that you connect inbetween -your video camera with some awesome family vacation clips on tape and your VHS recorder, which is -hooked up to your PC. - -You can then draw an amazing title screen over your video with this touchpad-ish device. -When you are ready, you rewind the camera to the beginning, press play and start recording on VHS at -the same time. Then you hit the 'fade in' and 'fade out' buttons on the Sketch Titler and go win -that home video contest. - -Well, this is how it's intended to be used anyway. If your camera doesn't work (like mine), you can -instead practice on a gray background: - -![][ich-bin-holz.jpg] - -So ideally, we can get a live camera as an input to this, and draw on it in *real time*! -Like an ancient livestreaming tool like OBS. -(and then hopefully we will also have a Visualist to either hook up before or after this device) - -Also some other people else has already circuit-bent this. -It looks amazing, so we might just give that a go aswell: - - - - -Since taking this for a spin and making a BOM for the *Visualist*, -I haven't spent any more time on the *Visualist* and turned to the audio side of things for now. -The next step on this front will probably be to lay out (parts of) the circuitry on stripboard and' -get ready to solder :) - -[plonat-atek]: https://s-ol.itch.io/plonat-atek -[lzx]: https://www.lzxindustries.net/ -[vfold]: https://vfoldsynth.wordpress.com/2013/01/23/hidden-stores-of-forum-gold/ -[visualist]: https://www.dropbox.com/s/uhjd2e6gur972yo/VisualistKl.pdf?dl=0 - -[schematic.png]: {{site.url}}/assets/{{page.imgid}}/schematic.png -[mine.jpg]: {{site.url}}/assets/{{page.imgid}}/mine.jpg -[ich-bin-holz.jpg]: {{site.url}}/assets/{{page.imgid}}/ich-bin-holz.jpg - - -- cgit v1.2.3