diff --git a/presentation/slides.fnl b/presentation/slides.fnl index d9ce594..dbb3801 100644 --- a/presentation/slides.fnl +++ b/presentation/slides.fnl @@ -82,71 +82,44 @@ {:target 30 :section :Intro}] [h "Honeylisp is hard to explain" ** "It is an experimental programming environment designed to enable a productive Apple // game development workflow" - "https://fennel-lang.org/" - {:target 30}] - [(bgimg "presentation/pics/pete286.jpeg") - h "Some Background" - ** "2019: Built a 16-bit MS-DOS game engine, using only retro hardware and software." - " * Driven by a custom Forth interpreter" - {:target 90}] - [(bgimg "presentation/pics/ggj2020.jpeg") - h "Neut Tower" - ** "2020: Created Neut Tower as part of two game jams. -* Global Game Jam - One weekend - Feb 2020 - First two rooms -* MS-DOS Game Jam - 1.5 months - April 2020 - 'Shareware Episode 1'" - {:target 60}] + "* Built with https://fennel-lang.org/" + "* Extends the lite text editor https://github.com/rxi/lite" + {:image "presentation/pics/assembly-markup.png" :justify :center} + "* Built all tools from scratch from the assembler up" + "* Not command-line driven - all tools, including the assembler / compiler, run _inside_ the editor" + (openfile :presentation/slides.fnl {:split :right :line 89}) + " * Including this presentation!" + {:target 120}] [(bgimg "presentation/pics/boot-tower.jpeg") {:action #(files.reload :neuttower/game.json)} h "Neu] [ower" ** "A small puzzle adventure game!" - "Magic Trick #1" + "Magic Trick #1: Assemble the game and poke it directly into emulated RAM" {:action boot-game} "--== D E M O ==--" {:target 300}] - [h "How It's Made" - ** "Is the Apple ][ running Lisp?" - " * Not really?" - "Is the code written in Lisp?" - " * Sort of!" - "Show me some Lisp already! >:/" - (openfile :neuttower/level1.fnl {:split :right :line 42}) - " * OK!" - {:target 90 :section "How It's Done"}] - [h "What is this unholy abomination?" - ** "Lisp and Forth?!" - {:image "presentation/pics/thinkhard.png" :justify :center} - "Not super keen on writing a complicated compiler" - " * \"Direct threaded\" inner interpreter" - "Forth allows efficient, composable, interactive code" - {:target 60}] - [h "Why use Lisp to compile Forth?" - ** "\"Immediate words\" can be Fennel functions that generate code!" - "Program can be compiled into a rich data structure" - (openfile :neuttower/level1.fnl {:split :right :line 59}) - "Magic Trick #2" - (np **) "Magic Trick #3" - {:button #(vm-eval :mixed) :text ":mixed"} - {:button #(vm-eval :hires) :text ":hires"} - {:button #(vm-eval 1 2 :+ :.) :text "1 2 :+ :."} - {:button #(vm-eval :earthquake) :text ":earthquake"} - {:pause-after true} - {:target 180}] [h "Explain this voodoo!" ** "Directly inspired by Dagen Brock's 2016 KFest talk on GSPlus" "Ended up using MAME - Lua plugin system exposes EVERYTHING" "Use Jeejah nREPL server library with custom nREPL client" - "1. What if I could poke my program directly into an emulator's memory?" - "2. What if I could preserve the current runtime state but rewrite the code?" - " ... even if the data has moved?" - "3. What if I could interactively try out new code while my game was running?" - {:target 60}] - [h "Wait WTF Is An Assembler" - ** "It's just converting mnemonics to bytes, right?" - {:image "presentation/pics/assembly-markup.png" :justify :center :pause-after true} - "Whoooops, actually the hard part is converting labels to addresses" - "Zero-page instructions are a different size, which messes up data layout!" - "Initial pass is needed to gather all symbols to determine sizes" - {:target 60}] + "The assembler running inside the editor means the output is a rich object, not a file" + {:target 45}] + [h "Hot-Code Reload" + ** "What if I could preserve the current runtime state but rewrite the code?" + (openfile :neuttower/level1.fnl {:split :right :line 59}) + "Magic Trick #2: Areas of memory can be marked as 'preserved' when new code is uploaded" + {:target 180}] + [(bgimg "presentation/pics/ggj2020.jpeg") + h "Interactive Execution" + ** "What if I could interactively try out new code while my game was running?" + (np **) "Magic Trick #3" + {:button #(vm-eval :mixed) :text ":mixed"} + {:button #(vm-eval :hires) :text ":hires"} + {:button #(vm-eval 1 2 :+ :.) :text "1 2 :+ :."} + {:button #(vm-eval :jaye-yx :get :.) :text ":jaye-yx :get :."} + {:button #(vm-eval :earthquake) :text ":earthquake"} + {:pause-after true} + {:target 180}] [h "The Tools" ** {:image "presentation/pics/retro-game-dev-quote.png" :justify :center :pause-after true} {:action #(files.reload :neuttower/game.json)} @@ -160,12 +133,9 @@ (openview #(MapEditView)) "Full-screen bitmap editor" (openview #(ScreenEditView :neuttower/title.screen) {:pause-after true}) - (openfile :presentation/slides.fnl {:split :right :line 133}) - "Presentation viewer" {:target 300 :section "Tooling"}] [h "Editing Editors With My Editor" - ** "lite is a small, highly-extensible text editor written in Lua" - "Lua provides a very dynamic environment" + ** "Lua provides a very dynamic environment" (openview #(MapEditView)) (openfile :editor/mapedit.fnl {:split :right :line 235}) "Downside:" @@ -193,6 +163,33 @@ {:pause-after true :section "Thanks!"}] ]) +; [(bgimg "presentation/pics/pete286.jpeg") +; h "Some Background" +; ** "2019: Built a 16-bit MS-DOS game engine, using only retro hardware and software." +; " * Driven by a custom Forth interpreter" +; {:target 90}] +; [(bgimg "presentation/pics/ggj2020.jpeg") +; h "Neut Tower" +; ** "2020: Created Neut Tower as part of two game jams. +; * Global Game Jam - One weekend - Feb 2020 - First two rooms +; * MS-DOS Game Jam - 1.5 months - April 2020 - 'Shareware Episode 1'" +; {:target 60}] + +; [h "What is this unholy abomination?" +; ** "Lisp and Forth?!" +; {:image "presentation/pics/thinkhard.png" :justify :center} +; "Not super keen on writing a complicated compiler" +; " * \"Direct threaded\" inner interpreter" +; "Forth allows efficient, composable, interactive code" +; {:target 60}] + +; [h "Wait WTF Is An Assembler" +; ** "It's just converting mnemonics to bytes, right?" +; "Whoooops, actually the hard part is converting labels to addresses" +; "Zero-page instructions are a different size, which messes up data layout!" +; "Initial pass is needed to gather all symbols to determine sizes" +; {:target 60}] + ; [h "Step 5: Running on Hardware" ; ** "I have a IIgs with a serial cable - I can poke bytes in directly from the monitor" ; "]IN#2\n]PR#2\n]CALL-151"