Daniel Marino is dedicated to creating simple, high-quality experiences.
He currently works as a UX Engineer at Planning Center. Outside of work, he enjoys spending time with family, woodworking, making video games, hand-lettering US state mottos, composing music, and experimenting with generative art.
Moving from Eleventy to Astro
I'd been running on Eleventy for a while now, but I've decided to move on. After weighing the pros and cons with Claude, I've landed on [Astro](https://astro.build/). ## Why I'm leaving Eleventy Eleventy is a great tool, and I still highly recommend it. But for better or worse, I've been bitten by the [React](https://react.dev/) bug, and I want to start writing more React and incorporating it into my personal site. It can be done with Eleventy, but it requires jumping through some hoopsāand even then, it's not really what Eleventy is built for. Finding a tool where React (or another framework) is part of the ecosystem makes more sense to me. The other thing that leaves a bit of a sour taste in my mouth is that Eleventy has been acquired by Font Awesome. I don't have anything against the company, or against [Zach](https://www.zachleat.com/) for selling it. Eleventy (now renamed [Build Awesome](https://build.awesome.me/)) looks like it's still open source, but they've introduced a paid version too. It scares me that at any moment the tool my website is built on could stop being free. ## Why Astro As I mentioned, Astro is designed to work with React and other frameworks out of the box, and I like the idea of sprinkling React components throughout my site. The switch from Eleventy to Astro was mostly a one-to-one conversion, so the learning curve was fairly small. Astro also seems pretty popular, and I like staying aware of the more widely used tools to keep current with emerging techāthough admittedly that's becoming less of a concern now that I'm folding AI into my workflow. Fittingly, I had Claude handle the conversion from Eleventy to Astro. ## Where's the Design? I'm jumping on a bandwagon here too. I hadn't redesigned in a while and was getting the itch, so this felt like an opportune time. But rather than unveiling a new design in one big push, I've decided to do a live redesign. That means things will look ugly for a bit, and I'm okay with that. I'm not sure anyone reads this blog anyway š¤£! A live redesign will be less stressful and let me poke at things slowly.
I Still Havenāt Made the Game
Two weeks ago I wrote about [vibe coding a voxel editor](/posts/voxel-editors-kind-of-suck-so-im-vibe-coding-one/) because the existing ones kind of sucked. Roxel is now at v0.6.3. ## Whatās in it now The core editing experience is solid. Full color palette system, command palette, view-angle presets, a custom color picker with color-space support, flyby camera mode. The UI went through a canvas-first redesign with floating chrome, and a first-launch tour. It even auto-checks for updates. Itās starting to feel like something Iād actually pay for. ## Whatās ahead The one thing blocking me from actively sharing it is macOS code signing. Iām waiting on an Apple Developer account to get that sorted. Longer term, I want to build a plugin architecture. One of the primary goals for Roxel is to keep it simple ā and a plugin system would let people bring their own features without bloating the core app for everyone who doesnāt need them. Thatās probably not a 1.0 feature, but itās where I want to take it. ## The detour became the thing I started Roxel so I could make a CSS game. I still want to make that game. But somewhere along the way Roxel stopped being the detour. Thatās fine. Maybe it turns into something. Maybe it stays a hobby app I use myself. Either way ā itās [open source on GitHub](https://github.com/starzonmyarmz/roxel) and free on [itch.io](https://starzonmyarmz.itch.io/roxel) for Mac and Windows, and Iāve shipped more working software in the last two weeks than I expected ā in a language I canāt write. Still a win.
Voxel Editors Kind of Suck, so Iām Vibe Coding One
Iāve been working on a new CSS-only game idea, and finally settled on voxel-like artwork. But building voxels in HTML/CSS isnāt that fun. I was vibe coding a web-based editor to go along with it, but it started getting sluggish and complicated to use. I more or less abandoned it in favor of using a real voxel editor to create the artwork ā I figured Iād export the work and use AI to convert it to HTML/CSS. ## The voxel editor landscape is rough I tried a handful of voxel editors: MagicaVoxel, Goxel, and Voxelator. The first thing I learned is that itās apparently required for a voxel editor to have āoxelā the name. The second thing I learned is that voxel editors kind of suck. The UI is either too complex or too unintuitive to learn. [Goxel](https://goxel.xyz/) was the closest to _easy-to-use_, but it died while exporting my file. Not great. Also, Iām on a Mac. None of those titles feel native ā they all feel like Windows apps in a wrapper. Thatās a deal-breaker for me. Iām used to polished software like [Figma](https://figma.com), [Affinity](https://www.affinity.studio/), [Sketch](https://www.sketch.com/), [Zed](https://zed.dev/), and [Retcon](https://retcon.app/). I want software that feels native, looks good, and is smooth. I really struggle to use anything thatās less. ## Enter Roxel So Iām taking a detour from the game. Iām now vibe coding a voxel editor called **Roxel**, and [Iām doing it in the open](https://github.com/starzonmyarmz/roxel).  Rust is fast, and you can build good-looking native apps with it for Mac and Windows ([Zed](https://zed.dev/) is a great example). The stack ended up being Rust + [Bevy](https://bevy.org/) + [egui](https://www.egui.rs/) ā or so Claude tells me. ## On vibe coding something you canāt write Hereās the honest part: I canāt write Rust. But I can _review_ Rust ā and it turns out thatās enough. Iāve got Claude Code running in a terminal in the background most of the day. Iāve been in the game long enough to know what quality software looks and feels like. I know what makes a good codebase: lean, simple, tested, CI, the usual. Iāve used enough design software to know what an efficient workflow feels like ā the tools, the layout, the UI, the UX. That taste is the thing Iām actually bringing to the project. The Rust is just the medium. ## Where itās headed Itās been a few days of vibing, but Iām impressed enough with how itās coming along that I really feel like this app has wheels. Claude and I worked on building out a logo, identity, and branding together. I think it could be a solid contender for the indie or hobby designer. But Iām not putting pressure on myself. Iām building it for me, so I can make a single game. Maybe itāll turn into a viable app. Maybe Iāll find a niche. Maybe Iāll find the one or two things other voxel editors donāt have. Either way ā Iāve got a working voxel editor on my Mac that I didnāt have a week ago. Thatās already a win.
Letting Claude Teach Me
Now that I use AI regularly to help write code and complete tasks, I find myself in a position where Iām not learning as much as I used to. That feels a bit crummy. Fairly often, Claude writes code I donāt fully understand. For example: I know enough TypeScript to _be dangerous_, but Iām definitely not an expert. Recently I had Claude take some typing I thought was overcomplicated and drastically simplify it. The new version was clearly better ā I just couldnāt tell you _why_. So I asked Claude to explain it in simple terms. Sure enough, it did. I guess thatās a silver lining to using AI: it can at least explain why it did what it did. A coworker mentioned he has Claude write one-off explanations with examples whenever this happens, and I liked that idea. So I built a [skill](https://gist.github.com/starzonmyarmz/32dbc5e468919dc1b1b9e1fd0b6664ad) around it. The skill looks at my uncommitted code, breaks it down, and writes a short blog article for me to read. Iām a fan of [Josh Comeauās blog](https://www.joshwcomeau.com/) and the way he uses interactive examples to teach a concept, so I made that part of the skill too ā Claude generates interactive examples alongside the explanation, then packages everything up in a small Vite environment. The first iteration was expensive to run. At least 3 minutes, and roughly 10K tokens. Iām fine burning tokens, but Iām also thrifty š¬. The second iteration kept the Vite environment and styles already wired up, so Claude only had to write the article and the examples. That brought it down to about a minute and 7K tokens. Better ā though Iād still like to get the token usage lower. The blog format is great, but itās a lot of work (for Claude) to generate all of this just to delete it when Iām done reading. Itād be nice to have these articles persist somewhere I could revisit later, or share with other people. That brought me to my current iteration. Itās an [Astro project](https://github.com/starzonmyarmz/til) that lives on GitHub. The skill works roughly the same way ā review uncommitted code, generate a post complete with interactive examples ā but now it publishes to a [TIL subdomain](https://til.iamdanielmarino.com/) where I can read the articles at my leisure or pass them along. Itās all vibe coded, and that feels appropriate. Iām up front about it on the site itself: _Things Claude changed that I didnāt understand ā explained⦠by Claude._ Iāll probably keep tinkering to bring the token usage down further, but it was a fun project to put together, and Iām happy to let Claude teach me what itās doing.
What Iām Using in 2026
This is an updated list of what Iām using in 2026. Iām only sharing whatās changed since [last yearās list](/posts/what-im-using-2025). ## Applications - [Chrome](https://www.google.com/chrome/) ā Chrome was on my list last year, but Iām mentioning it again because I actually used Brave for most of 2025. I like Brave, and honestly I canāt even remember why I switched back to Chrome š¤·š». - [ChatGPT](https://chatgpt.com/) ā I hate that Iām listing AI tools, but if Iām going to be transparent, it has to be here. I use it a bit for code, but mostly for rewording messages or rubber-ducking ideas. - [Claude Code](https://www.claude.com/product/claude-code) ā I [wrote about my thoughts and reluctance to embrace](/posts/vibe-coding-and-the-existential-dread-of-progress/) AI for coding. My company pays for it, so I use it. - [Endel](https://endel.io/) ā Iām [neurodiverse](https://en.wikipedia.org/wiki/Neurodiversity) and have been trying to be more intentional about using tools that help me stay focused. Endel is super cool and has a lot of genuinely helpful features. - [Hyper](https://hyper.is/) ā I was previously using [iTerm2](https://iterm2.com/), but switched to Hyper mostly because it feels prettier. Thatās probably a dumb reason since I could have customized iTerm2, but I installed Hyper on my new machine and never felt the need to switch back. - [Retcon](https://retcon.app/) ā My team is pretty opinionated about Git history, and rewriting history via the command line or VS Code started to feel tedious. Several coworkers use [LazyGit](https://github.com/jesseduffield/lazygit), but I didnāt want another terminal-based tool. Retcon does exactly what it promises and lets me handle more advanced Git workflows without having to be a Git super-nerd. - [Notion](https://www.notion.com/) ā I was using [Bear](https://bear.app/) for notes, but didnāt feel like I was getting enough value out of paying for it. Thatās not a knock against Bearāitās a great product. Notionās free plan works just fine for me. I also tried [Obsidian](https://obsidian.md/) this year and liked it, but parts of it felt quirky. It also seemed like a bigger time investment to make it feel as polished as Notion or Bear. - [VS Code](https://code.visualstudio.com/) ā I tried [Zed](https://zed.dev/) for a bit, and there are things I really like about it. That said, I ran into a few weird and buggy behaviors that I just couldnāt get past. ## Equipment I got a 2025 M4 MacBook Pro when I started my new job this year. Itās more than powerful enough for anything I need to do.
The Money Filter
One of the biggest challenges Iāve faced as a web designer is how often people expect a website for next to nothing. Somewhere along the way, the perception formed that a website is a commodityāquick, cheap, and interchangeable. So when someone asks what I charge (for a very basic marketing site), I usually reply, *āThatāll cost around $5,000.ā* That number isnāt a gimmickāitās a filter. It immediately reveals who understands the craft behind the screen, who values quality, and whoās serious about investing in their own business. It separates those looking for something fast and inexpensive from those seeking something *purposeful* and *crafted*. It used to frustrate me when people balked at the cost. Now? I see it as a helpful sorting mechanism. It shows me who I actually want to work with. ## The Cost of āCheapā Thereās no shortage of DIY website builders promising professional results at a low price. And honestlyāsometimes thatās *fine*. If you just need something quick and functional, a template might be all you need. But a boutique website is something entirely different. When you hire me, youāre not buying convenienceāyouāre investing in craft. A boutique site is designed *and* engineered specifically for you. Itās not a template dressed up with new colors. Itās built intentionally, shaped around your goals, your audience, your brandās personality, and the experience you want people to have. And cheap solutions often come with hidden costs: - lost conversions - poor usability and performance - accessibility issues - a generic, forgettable brand presence The value of a bespoke website isnāt just in what it *does*. Itās in *how* itās madeāand what it communicates about you. ## Why Bespoke Work Matters When I build a custom website, itās not just about aesthetics. Itās about alignmentāmaking sure every part of the experience supports your story, your content, and your clientsā needs. Every choiceātypography, layout, semantics, performanceāis intentional. Anyone can make a website that *looks* good. *I handcraft websites that feel right and function beautifully.* As a **design engineer**, I donāt hand off a static mockup and hope the final result captures the original intent. I design with the intent to build, carrying the project from concept to code so the final experience is cohesive, thoughtful, and true to the vision. Thatās what boutique design is: every pixel and every line of code has purpose. ## The Bottom Line If you only need a website, you donāt need me. But if you want a *boutique digital experience*āsomething that reflects your values, your vision, and your commitment to qualityāthen Iām the right fit. Youāre not paying for a website. Youāre paying for craftsmanship, collaboration, and care. And while not everyone values that, the right clients do. My pricing isnāt just a numberāitās a filter that helps me focus on the people who appreciate the work, the craft, and the impact it can create.
How I Handletter
When I first got into hand-lettering, I had a hard time finding people who shared their *full* processāespecially the digitizing phase. So hereās a look at how I typically work. Everyoneās process is different, and a lot depends on your style and how you plan to present the piece. For me, since I donāt have the steadiest hand, I tend to embrace rough, scrappy, distressed looks. Most of my work ends up digital anyway, so mistakes can be fixed later. Hereās a short process video I made a while back. <iframe width="100%" src="https://www.youtube-nocookie.com/embed/5FnhKEcAM4E?si=65vKvS4Y2KdvPrhf" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ## Thumbnails & Sketching - Start with quick thumbnail ideas on scrap paper. - Refine the chosen direction with a pencil on Bristol Paper. - If possible, I use a drawing pencil (softer, lighter lead makes cleanup easier). - After inking, I clean up with an art gum eraser. ## Inking - My go-tos are **Microns** in different thicknesses. In the video I sharedI used a `.08` for outlines and `Graphic 1` for filling letters. - I used a **Gelly Roll 10** to add *cut-outs*, create depth, and fix small mistakes š¬. ## Digitizing - I scan the inked artwork using [Scanner Pro](https://apps.apple.com/us/app/scanner-pro-scan-documents/id333710667) on iOS. - Clean up in [Pixelmator Pro](https://www.pixelmator.com/pro/). - Add textures for distress and wear (Iāve collected a bunch of texture packs over the years). ## Where Iāve Used This This is basically the same process I followed for my [State Motto](https://states.iamdanielmarino.com) series, and most of my other lettering projects. Donāt be afraid to lean into your natural tendencies (like a scrappier style if your hand isnāt steady) and use the digital phase to enhance or correct. Trial and error is a huge part of it.
Vibe Coding and the Existential Dread of Progress
Does anyone else hate the term _vibe coding_? Iāve been pretty resistant to incorporating AI directly into my development workflow. I use it all the time to clean up emails, Slack messages, and blog posts (including this one). Itās helped me plan vacations, write my cover letter for [Planning Center](https://www.planningcenter.com/), and even gain insights from journaling. But coding? That felt like crossing a line. At first, I confined AI to repetitive tasksā[formatting long word lists into arrays](https://iamdanielmarino.com/posts/daily-inspirational-word/), deciphering cryptic console errors, or exploring how to integrate Vite into a Rails codebase still using Sprockets. All helpful, but I steered clear of anything that touched ārealā engineering. Still, AI isnāt going anywhere. And as much as I hate admitting how much I rely on it, it genuinely makes my life easier. So I gave _vibe coding_ a shot. Spoiler: Iām soldāwith a few caveats. ## Vibe Coding an Alfred Workflow Iād played with basic [Alfred workflows](https://www.alfredapp.com/) before, using the built-in UI or tools like [Alfy](https://www.npmjs.com/package/alfy). But I had an idea for something more complexāand neither the time nor the motivation to learn how to build it from scratch. ### The Problem At Planning Center, our design system has 300+ tokens (and counting). To grab one, Iād open our Storybook instance, scroll to the search bar, type in a few characters, click to copy, then return to my editor to paste it. Repeat that a few dozen times a day, and the friction starts to add up. ### The Solution An [Alfred workflow](https://github.com/starzonmyarmz/pco-tapestry-tokens-alfred) that lets me search tokens via fuzzy matching, press Enter to copy, and paste directlyāeliminating multiple steps and speeding up my flow. ## Using Claude Code Iāve tried ChatGPT and GitHub Copilot. They both work well (though I find Copilotās integration with VS Code a bit invasive). Iām not ready to pay out of pocket, so I started using Claude Code through Planning Centerās access. Setup took less than 10 minutes. [Anthropicās documentation](https://docs.anthropic.com/en/docs/claude-code/overview) is clear, and their tips on effective usage are actually helpful. ## Building the Workflow with Claude Code I kicked things off with a prompt: > I want an Alfred extension where I can enter āttā followed by characters, and tokens from ~~URL redacted~~ will be shown using fuzzy search. Claude generated a Python script⦠that didnāt work. It produced a workflow Alfred couldnāt import. So I responded with: > The Alfred extension fails to import. Claude replied something like, _āYouāre right, let me fix that,ā_ and, impressively, it did. After about three hours of iterative prompts and debugging, I had a [fully functional Alfred workflow](https://github.com/starzonmyarmz/pco-tapestry-tokens-alfred) that: - Stores design tokens as a JSON database - Caches data locally - Refreshes if unused for over an hour - Fuzzy-finds tokens on input - Displays color swatches for color-based tokens I also used Claude to: - Generate 100+ color swatches (since Alfred canāt use data URIs) - Write a Bash script that builds the workflow with semantic versioning I donāt know much Python, but I know enough to skim the output and feel confident in the structure. And because this was a small, siloed project, I wasnāt concerned about maintainability or codebase conventions. ## The Cost Aside from the monthly AI access fee, the entire three-hour build process cost around $10 in usage tokens. Thatās ~$3.33/hourāfar below the value of my time. And now, every use of the workflow saves me 10+ seconds. That adds up quickly. If Iād tried to build this from scratch, it easily couldāve taken 10+ hours and been half as effective. Thatās not even accounting for generating the color swatch images. I did spend about an hour trying to get Claude to scrape the tokens directly from the design system site, but that turned out to be unreliable. Still, the final solution works and required zero extra effort from the rest of my team. ## The Pros and Cons of AI in the Workflow ### Pros - **Efficiency Boost**: Great at handling menial but necessary tasksāJSON formatting, token lookups, error decoding, etc. - **Rapid Prototyping**: I built a working Alfred workflow in a single evening. Even if it were only a prototype, it wouldāve been valuable. - **Creative Leverage**: Designers and PMs can use AI to sketch out ideas and flows, helping engineers jump into development faster. ### Cons - **Skill Stagnation**: Over-reliance on AI could erode problem-solving ability or deeper understanding of frameworks and languages. - **Job Displacement**: AI is replacing some roles. At Planning Center, leadership has been clear AI wonāt replace peopleāonly support them. But the broader industry picture is less certain. - **Environmental Cost**: Running large AI models consumes a lot of energy. - **Price Tag**: Even if it saves time, AI access and usage can get expensiveāespecially if youāre footing the bill. ## So Why Do I Still Feel Icky? It took me a while to name the feeling, but I got there: **Iām grieving the loss of what it means to be an engineer.** Iāve spent over 20 years solving problems, building UIs, and turning ideas into code. Iāve always taken pride in being able to take a design and bring it to life. But now, what it means to be an engineer is changingāand thatās uncomfortable. I donāt want to become just a prompt wrangler. But I also donāt want to be the person who gets left behind because they refused to adapt. The logic is clear: why pay one engineer for 10 hours of work when another can produce the same result in two with AI? ## Finding the Sweet Spot I think the answer lies somewhere in the middle. Engineers should still understand their craftābe able to reason through problems, write maintainable code, and build features from scratch when needed. But AI should be a tool we use intentionally to reduce toil and accelerate progress. We donāt call it cheating when someone uses code completion. Why should this be any different?
Making an Escape Room with only HTML and CSS
**Beware! This post includes spoilers!** I recently built an escape room game called [CSScape Room](https://csscape-room.iamdanielmarino.com/). This isnāt my first JavaScript-free web game, but HTML and CSS have evolved significantly since my previous attempts, with newer additions allowing for more complex selectors and native interactions. Rather than saving this idea for a game jam, I built it purely for fun, which freed me from theme constraints and time pressure.  Iāve enjoyed escape room games since childhood, and it was nostalgic to recreate that experience myself. This project pushed my artistic limits while challenging me to design puzzles and translate them into complex HTML and CSS. The learning process was fun, challenging, and sometimes tediousāmostly through trial and error. ## Process My creative process isnāt linearāitās a blend of designing, puzzle creation, and coding that constantly influences each other. I frequently had to redesign or recode elements as the project evolved. There was also that time I accidentally deleted half my CSS because I wasnāt backing up to GitHub... lesson learned! š¬ This might sound chaotic, and honestly, it was. If youāre wondering where to start with a project like this, I began by prototyping the room navigation system. I figured that was the minimum viable featureāif I couldnāt make that work, Iād abandon the project. The solution I eventually found seems simple in retrospect, but I went through several iterations to discover it. This flexible approach makes sense for my creative projects. As I build something, both the in-progress work and my growing skills inevitably influences the entire project. Iām comfortable with this non-linear processāit also suits my ADHD brain, where I tend to lose interest if I work on the same thing for too long. ## Artwork Iād wanted to design a pixel art-styled game for some time but never felt confident enough to attempt it during a game jam because of the learning curve. I watched tutorials from [Adam Yunis](https://www.youtube.com/adamcyounis) and [Mort](https://www.youtube.com/channel/UCsn9MzwyPKeCE6MEGtMU4gg) to get a crash course in pixel art best practices. Initially, progress was slow. I had to figure out 2D perspective with vanishing points, determine a color palette, practice shading techniques, and decide how much detail to include. While I tried to adhere to pixel art ārules,ā I definitely broke some along the way. One challenge I set for myself was using only 32 colors to capture the feeling of an older gaming console. Once I got comfortable with shading and dithering, working within this constraint became easier. An added benefit to using 32 colors was it resulted in smaller image sizesāthe gameās 79 images account for only about 25% of the total payload.  I attempted to design sprites using dimensions in multiples of eight, but Iāll admit I became less strict about this as the project progressed. At a certain point, I was struggling enough with the color and styling limitations that this guideline became more of a starting point than a rule. I considered creating my own font, but after exhausting myself with all the artwork, I opted for Googleās PixelifySans instead. Almost all animation frames were individually drawn (except for the āoneā TV animation). This was tedious, but I was determined to stay true to old-school techniques! I did use CSS to streamline some animationsāfor instance, I used `animation-direction: alternate` on the poster page curl to create a palindrome effect, halving the number of required sprites.  ## Mechanics Like my previous game [Heiro](https://starzonmyarmz.itch.io/hiero), this project primarily uses checkbox and radio button mechanics. However, the addition of the `:has()` pseudo-selector opened up many more possibilities. I also utilized the `popover` API to create more detailed interactions. ### Checkbox and Radio Selection Triggering interactions by toggling checkboxes and radio buttons isnāt new, but the `:has()` selector is a game-changer! Before this existed, you had to structure your markup so interactive elements were siblings. The `:has()` selector makes this far more flexible because you no longer need to rely on a specific HTML structure. ```css #element { display: none; } :has(#checkbox:checked) #element { display: block; } ``` Using this pattern, `:has()` looks for `#checkbox` anywhere on the page, meaning you donāt have to rely on `#checkbox`, its corresponding `<label>`, or `#element` being siblings. The markup structure is no longer a constraint. Most of this game functions on toggling checkboxes and radios to unlock, collect, and use items. ### Navigation I almost gave up on the current implementation, and used basic compass notation to avoid visual transitions between directions. After several failed attempts, I found a solution. The tricky part was determining how to transition into a direction from either left or right, depending on which arrow was clicked. My solution is conceptually simple but difficult to explain! First, I used radio buttons to determine which direction youāre facing (since you can only face one direction at a time). Second, I needed a way to determine if youāre entering a direction from west or east. This required eight radio buttonsātwo for each direction. For example, if youāre facing east (having come from facing north), you have two possible directions to go: west (returning to face north) or east (to face south). I needed to make the radio buttons visible that would take you north from east, and south from west.  The CSS looks something like this: ```css :has(#east-from-west:checked) :is( [for="south-from-west"], [for="north-from-east"]) { display: block; } ``` This pattern was implemented for each direction, along with animations to ensure each room view slid in and out correctly. ### Zooming In I initially focused so much on checkbox mechanics that I assumed Iād need the same approach for zooming in on specific areas. Then I had a "Duh!" moment and realized the `popover` API would be perfect. Hereās the basic markup for looking at an individual book: ```html <button popovertarget="book">Zoom in</button> <div id="book" popover> <!-- Book content goes here --> <button popovertarget="book" popovertargetaction="hide">Close</button> </div> ``` ### Turning the Lights Off I procrastinated on implementing this feature because I thought Iād need to create darkened variations of all artwork. I donāt recall what inspired me to try blend modes, but Iām glad I didāthe solution was surprisingly simple. When the light switch checkbox is toggled, a `<div>` becomes visible with a dark background color and `mix-blend-mode: multiply`. This multiplies the colors of the blending and base layers, resulting in a darker appearance. ### Playing the Crossword This required [surprisingly complex CSS](https://github.com/starzonmyarmz/csscape-room/blob/main/styles/east.css#L204-L234). Each square has three letters plus a blank tile, meaning four radio buttons. The `:checked` letter has a `z-index` of 3 to display above other letters, but also has `pointer-events: none` so clicks pass through to the next letter underneath (with `z-index: 2`). The remaining tiles have a `z-index` of 1.  The CSS becomes even trickier when the last tile is `:checked`, requiring some [creative selector gymnastics](https://github.com/starzonmyarmz/csscape-room/blob/main/styles/east.css#L227) to target the first radio button in the stack again. ## Tools I created all artwork using [Aseprite](https://www.aseprite.org/), which is specifically designed for pixel art. I probably only used a fraction of its features, and Iām not sure it actually made my life easierāit might have made things more difficult at times. Iām not giving up on it yet, though. I suspect Iāll occasionally discover features that make me think, āOh, thatās way easier than what I was doing!ā I started coding with basic HTML and CSS but eventually found navigation difficult with such a long HTML file. It also became tedious writing the same attributes for every `<img />` element. I migrated the project to [Eleventy](https://www.11ty.dev/) to improve organization and create custom shortcodes for simplifying component creation. I used the `html-minifier-terser` npm package, which integrates well with Eleventy. I chose native CSS over [Sass](https://sass-lang.com/) for several reasons: 1. CSS now has native nesting for better organization and leaner code 2. CSS has built-in variables 3. HTTP/2 handles asset loading efficiently, eliminating the major benefit of bundling CSS files The game uses 12 CSS files with 12 `<link rel="stylesheet" />` tags. The only Sass feature I missed was the ability to loop through style patterns for easier maintenance, but this wasnāt a significant issue. The game is hosted on GitHub Pages. During deployment, it runs an npm command to minify CSS using [Lightning CSS](https://lightningcss.dev/). I mentioned accidentally deleting half my CSS earlierāthis happened because I initially used Eleventyās recommended approach with the `clean-css` npm package. I strongly advise against using this! This package doesnāt work with native CSS nesting. While losing code was frustrating, I rewrote much of it more efficiently, so there was a silver lining. ## Nice to Haves I initially wanted to make this game fully accessible, but the navigation system doesnāt translate well for screen reader users. I tried implementing a more compass-like navigation approach for keyboard users, but it proved unreliable and conflicted with the side-to-side approach. Adding text labels for interactive elements was challenging because you canāt track the `:focus` state of a `<label>` element. While you can track the `:focus` of the corresponding `<input />`, it wasnāt consistently reliable. The main keyboard accessibility issue is that the game exists as one long HTML page. When you navigate to face a different direction, keyboard focus remains elsewhere on the page, requiring extensive tabbing to reach navigation elements or item selection. I ultimately decided to make the game deliberately inaccessible by adding `tabindex="-1"` to all keyboard-accessible elements. Iād rather users recognize immediately that they canāt play with assistive technology than become frustrated with a partially broken experience. Sound would have been a nice addition, but I encountered the same issues as with my previous game Heiro. You can toggle the visibility of an `<embed>` element, but once itās visible, you canāt hide it againāmeaning thereās no way to toggle sound on and off. ## Conclusion [CSScape Room](https://csscape-room.iamdanielmarino.com/) was a fun but exhausting four-month project. It began as an experiment to see if creating a JavaScript-free escape room was possibleāand the answer is definitely yes. Iāve only touched on some aspects here, so if youāre interested in the technical details, check out the source code on GitHub. Finally, Iād like to thank all my playtesters for their valuable feedback!
Self-avoiding Walk
Iām a bit late to this, but back in summer 2024 I participated in the [OST Composing Jam](https://itch.io/jam/ost-composing-jam-7). The goal of this jam is to compose an original soundtrack (minimum of 3 minutes) of any style for an imaginary game. While Iāve composed a lot of video game music, Iāve never created an entire soundtrack around a single concept. <iframe style="border: 0; width: 100%; height: 310px;" src="https://bandcamp.com/EmbeddedPlayer/album=3143278153/size=large/bgcol=ffffff/linkcol=eb4d55/artwork=small/transparent=true/" seamless><a href="https://danielmarino.bandcamp.com/album/self-avoiding-walk">Self Avoiding Walk by Daniel Marino</a></iframe> To be honest, I wasnāt entirely sure where to start. I was torn between trying to come up with a story for a game to inspire the music, and just messing around with some synths and noodling on the keyboard. I did a little bit of both, but nothing really materialized. ## Synth + Metal ā Synthmetal Feeling a bit paralyzed, I fired up the āole [RMG sequencer](https://rmg.iamdanielmarino.com/) for inspiration. I saved a handful of randomized melodies and experimented with them in Reaper. After a day or two I landed on something I liked which was about the first 30 seconds or so of the second track: "Defrag." I love metal bands like Tesseract, Periphery, The Algorithm, Car Bomb, and Meshuggah. I tried experimenting with incorporating syncopated guttural guitar sounds with the synths. After several more days I finished "Defrag"āwhich also included "Kernel Panic" before splitting that into its own track. I didnāt have a clue what to do next, nor did I have a concept. Composing the rest of the music was a bit of a blur because I bounced around from song to songāiterating on the leitmotif over and over with different synths, envelopes, time signatures, rhythmic displacement, pitch shifting, and tweaking underlying chord structures. ## Production The guitars were recorded using DI with my Fender Squire and [Behringer Interface](https://www.sweetwater.com/store/detail/UMC202HD--behringer-u-phoria-umc202hd-usb-audio-interface). Iām primarily using the ML Sound Labs [Amped Roots Free](https://ml-sound-lab.com/products/amped-roots) amp sim because the metal presets are fantastic and rarely need much fuss to get it sounding good. I also used [Blue Cat Audio free amp](https://www.bluecataudio.com/Products/Product_FreeAmp/) sim for clean guitars.  All the other instruments were MIDI tracks either programmed via piano roll or recorded with my [Arturia MiniLab MKII](https://www.arturia.com/minilab-mkii/resources). I used a variety of synth effects from [my library of VSTs](https://iamdanielmarino.com/posts/what-im-using-2025/). I recorded this music before acquiring my Fender Squire Bass guitar, so bass was also programmed. ## Theme and Story At some point I had five songs that all sounded like they could be from the same game. The theme for this particular jam was "Inside my world." I had to figure out how I could write a story that corresponded with the theme and could align with the songs. I somehow landed on the idea of the main actor realizing his addiction to AI, embarking on a journey to "unplug." The music reflects his path to recovery, capturing the emotional and psychological evolution as he seeks to overcome his dependency. After figuring this out, I thought it would be cool to name all the songs using computer terms that could be metaphors for the different stages of recovery. ## Track listing - **Worm** ā In this dark and haunting opening track, the actor grapples with his addiction to AI, realizing he can no longer think independently. - **Defrag** ā This energetic track captures the physical and emotional struggles of the early stages of recovery. - **Kernel Panic** ā Menacing and eerie, this track portrays the actorās anxiety and panic attacks as he teeters on the brink during the initial phases of recovery. - **DƦmons** ā With initial healing achieved, the real challenge begins. The ominous and chaotic melodies reflect the emotional turbulence the character endures. - **Time to Live** ā The actor, having come to terms with himself, experiences emotional growth. The heroic climax symbolizes the realization that recovery is a lifelong journey. ## Album art At the time I was messing around with [Self-avoiding walks](https://en.wikipedia.org/wiki/Self-avoiding_walk) in generative artwork explorations. I felt like the whole concept of avoiding the self within the context of addiction and recovery metaphorically worked. So I tweaked some algorithms and generated the self-avoiding walk using JavaScript and the [P5.js](https://p5js.org/) library. I then layered the self-avoiding walk over a [photo I found visually interesting](https://unsplash.com/photos/a-close-up-of-a-brown-and-yellow-substance-Smpy9LZmksY) on Unsplash using a [CSS blend mode](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode).  ## Jam results I placed around the top 50% out of over 600 entries. I would have liked to have placed higher, but despite my ranking, I thoroughly enjoyed composing the music! Iām very happy with the music, its production quality, and I also learned a lot. I would certainly participate in this style of composition jam again!
What Iām Using in 2025
Iāve always been fascinated to see what other apps or workflows others are using in their day-to-day lives. Every now and then I learn about a new app or some cool trick I didnāt previously know. I doubt anyone seriously cares about what Iām using, but figured Iād list them out anywayāif for no other reason than to keep a historical record at this point in time. ## Applications - [Alfred](https://www.alfredapp.com/) ā I have a lifelong license, and I like it. No point in fixing something that isnāt broken. I primarily use it for app switching, but also use it for math, and to [search for gifs](/posts/my-gif-workflow-using-eleventy-netlify-alfred/). - [Aseprite](https://www.aseprite.org/) ā Sometimes I do pixel art! Even if the UI is clunky, and some keyboard shortcuts arenāt always convenient, there are some unique features that help facilitate creating pixel art. - [Audacity](https://www.audacityteam.org/) ā I rarely use it, but sometimes itās easier to make some quick audio edits with Audacity than to use a full blown [DAW](https://en.wikipedia.org/wiki/Digital_audio_workstation). - [Bear](https://bear.app/) ā This is the note-taking, task-tacking app Iāve landed on. The UI is beautiful and it feels snappy. It syncs, so I can use it on my iPhone too. - [Chrome](https://www.google.com/chrome/) ā I used [Arc](https://arc.net/) for the better part of 2024, but after they announced they were done working on it to focus on a new AI-powered browser, I peaced out. There are a couple of features I really missed, but was able to find some extensions to fill those gaps: [Copy Current Tab URL](https://chromewebstore.google.com/detail/copy-current-tab-url/kjfaieigmkklodbpcnadhkmbfjapgljd), [Meetings Page Auto Closer for Zoom](https://chromewebstore.google.com/detail/meetings-page-auto-closer/pbgidoglkjhfgjhalbbiiahdlokjcplb), [Open Figma app](https://chromewebstore.google.com/detail/open-figma-app/hgeipfdfhbmmgbkdjbeplocahpgkpkal), and [JSON Formatter](https://chromewebstore.google.com/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa). - [Figma](https://www.figma.com/) ā I use it because itās what we use at work. Iām happy enough with Figma. - [iTerm2](https://iterm2.com/) ā Has a few features that I like that makes me chose this over Macās native Terminal app. - [Pixelmator Pro](https://www.pixelmator.com/pro/) ā I havenāt paid the Adobe tax for a long time, and it feels good. I started using Pixelmator because at the time it was the best alternative available. Iām comfortable with Pixelmator at this point. I donāt really use image editors often these days, so I probably wonāt switch anytime soon. - [Reaper](https://www.reaper.fm/) ā My DAW of choice when composing music. Itās very customizable, easyish enough to learn, and the price is right. It also has a die hard community, so Iām always able to find help when I need it. - [VS Code](https://code.visualstudio.com/) ā Iāve tried a lot of code editors. I prefer [Sublimeās](https://www.sublimetext.com/) UI over VS Code, but VS Code does a lot of things more easily than Sublime does, so I put up with the UI. - [YouTube Music](https://music.youtube.com/) ā I still miss [Rdio](https://en.wikipedia.org/wiki/Rdio). YouTube Music works well enough I guess. Paying for YouTube Music has the benefit of not seeing ads on YouTube. ## Command-line Tools These arenāt apps per se, but these are some tools that I use to help manage packages or that I use regularly when developing. - [Deno](https://deno.com/) - [Eleventy](https://www.11ty.dev/) - [Homebrew](https://brew.sh/) - [pure](https://github.com/sindresorhus/pure) - [statikk](https://github.com/paulirish/statikk) - [Vite](https://vite.dev/) - [Volta](https://volta.sh/) - [yt-dlp](https://github.com/yt-dlp/yt-dlp) ## Equipment I have one computer and I use it for everything, and Iām okay with that. Itās more than powerful enough for work, composing music, making games, and occasionaly playing games. Although I have a dedicated home office, lately I tend to work more on the go, often with just my laptopāwhether thatās at a cafe, a [coworking space](https://thecoworkinghouse.com/), or even just moving around the house. - 2021 M1 MacBook Pro - [AKG K240 Studio Headphones](https://www.sweetwater.com/store/detail/K240S--akg-k240-studio-semi-open-pro-studio-headphones) - [Arturia MiniLab MKII Controller](https://www.arturia.com/minilab-mkii/resources) - [Behringer UMC202HD USB Audio Interface](https://www.sweetwater.com/store/detail/UMC202HD--behringer-u-phoria-umc202hd-usb-audio-interface) - [Fender Squire Strat Guitar](https://www.sweetwater.com/store/detail/StratMinIBK2--squier-mini-strat-black-with-laurel-fingerboard) - [Fender Squire Bass Guitar](https://www.amazon.com/gp/product/B0CSLMDCLY) - [Shure SM57](https://www.shure.com/en-US/products/microphones/sm57?variant=SM57-LC) ## Virtual Instruments This is quite specific for composing music, so if that doesāt interest you, feel free to stop reading here. This list is not exhaustive as Iām regularly trying out new VSTs. These are some staples that I use: - š¹ [Arturia Analog Lab V (Intro)](https://www.arturia.com/products/software-instruments/analoglab/overview) ā My Arturia controller came with this software. It has over 500 presets and I love exploring the variety of sounds. - šø [Bass Grinder (Free)](https://plugins4free.com/plugin/2082/) ā I recently came across this VST, and it has a great crunchy overdrive sound for bass guitar. - š„ [Manda Audio Power Drum Kit](https://www.powerdrumkit.com/) ā Even though you can use this for free, I paid the $9 because it is fantastic. The drums sound real and are great for all styles of music. - šø [ML Amped Roots (Free)](https://ml-sound-lab.com/products/amped-roots) ā What I like about this is that I get great metal guitar out of the box without having to add pedals or chaining other effects. - š„ [ML Drums (Free)](https://ml-sound-lab.com/pages/ml-drums) ā I just started experimenting with this, and the drum tones are amazing. The free set up is pretty limited, but I like how I can add on to the base drum kit to meet my needs rather than having having to buy one big extensive drum VST. - š¹ [Spitfire LABS](https://labs.spitfireaudio.com/) ā More variety of eclectic sounds. I also use several built-in VSTs made by Reaper for delay, EQ, reverb, pitch-shifting, and other effects. Reaperās VSTs are insanely powerful enough for my needs and are much less CPU intensive.
Daily Inspirational Word
Over the past couple of years Iāve gotten into journaling. Recently Iāve been using a method where youāre given a single inspirational word as a prompt, and go from there. Unfortunately, the process of finding, saving, and accessing inspirational words was a bit of a chore: 1. Google a list of ā366 inspirational wordsā. 2. Get taken to a blog bloated with ads and useless content all in an effort to generate SEO cred. 3. Copy/paste the words into Notion. 4. Fix how the words get formatted becasue Notion is weird, and I have OCD about formatting text. While this gets the job done, I felt like there was room to make this a more pleasant experience. All I really wanted was a small website that serves a single inspirational word on a daily basis without cruft or ads. This would allow me to get the content I want without having to scroll through a long list. I also don't want to manage or store the list of words. Once I've curated a list of words, I want to be done with it. ## Creating a microsite I love a good microsite, and so I decided to create one that takes all the chore out of obtaining a [daily inspirational word](https://daily-inspirational-word.iamdanielmarino.com).  The website is built with all vanilla tech, and doesnāt use any frameworks! Itās nice and lean, and itās footprint is only 6.5kb. ### Inspirational words While Iām not a huge fan of AI, I did leverage ChatGPT on obtaining 366 inspirational words. The benefit to ChatGPT was being able to get it to return the words as an arrayācutting down on the tedium of having to convert the words I already had into an array. The [words are stored in itās own JSON file](https://github.com/starzonmyarmz/daily-inspirational-word/blob/main/words.json), and I use an [async/await function to pull in the words](https://github.com/starzonmyarmz/daily-inspirational-word/blob/main/script.js), and then process the data upon return. ## Worth the effort I find these little projects fun and exciting because the scope is super tight, and makes for a great opportunity to learn new things. Itās definitely an overengineered solution to my problem, but it is a much more pleasant experience. And perhaps it will serve other people as well.
My current prototyping environment
The other day I shared [why I prefer coding prototypes](/posts/why-i-still-prefer-prototyping-using-code/) rather than using design apps to create them. My prototyping environment has evolved over the years. I love to hear how others build prototypes, so I thought Iād share where Iām at now. Maybe youāll find it useful. ## A single repository I currently have a [single GitHub repo](https://github.com/starzonmyarmz/prototypes) housing all of my prototypes. I do this primarily so I donāt have to remember where any given prototype lives. They all live in the same place! Another benefit is if I pull in a library or some CSS component, I can reuse it in other prototypes without having to go out and grab it from the source again. ## My old setup In the past I used [Sinatra](https://sinatrarb.com/) hosted on Heroku. Having Ruby and a basic server (Such as [Webrick](https://github.com/ruby/webrick)) in the backend was pretty nice: - I could code up some fairly complex prototypes out with realistic url schemes. - Gems! If I needed fake data, I could use the [Faker gem](https://github.com/faker-ruby/faker). - If I wanted a table with a 100 rows, I could easily generate that with a super simple loop. But it got clunky. Spinning up a new prototype wasnāt very efficient. Setting up the urls took time. Deploying to Heroku wasnāt always straight forward. Heroku also got rid of their free plan, and I didnāt want to go looking for a new service. Maybe Iām making excuses. ## A dumb server Now I just use HTML, CSS (vanilla), and Javascript with no special backend. I donāt have Node.js running, and I donāt use a package manager like NPM or Yarn. To start a server I navigate to the prototype directory in iTerm, and run [Statikk](https://github.com/paulirish/statikk). Easy peasy. This setup requires no upkeep, so I can focus on actually prototyping! I have a basic file structure for keeping prototypes separate. I typically use [Preact](https://preactjs.com/) for scaffolding. To `import` Preact or other NPM packages I use [esm.sh](https://esm.sh/). When I push changes to the GitHub repo itās deployed to GitHub pages. I can then share a public URL to folks that need to review the prototype. ## One glaring problem Thereās only one issue Iāve run into using this setup, and its not even related to the setup! The [Porchlight design system](https://porchlight.design/) (which we use at [Harvest](https://www.getharvest.com/)) doesnāt have itās styles or components available to consume publicly via CDN. Womp womp. I can get around the CSS issue. I end up having to copy the compiled CSS from the design system and paste it into a new file in my prototype environment. And Iām kind of out of luck with the JavaScript: I have to code these up from scratch. Although, I suppose I could copy the compiled components, and paste them into my prototype environment. The easiest fix is probably to introduce a package manager, but Iād rather not. We have talked about making the design systemās CSS and components available via CDNāitās just a matter of getting around to it. ## Prototype! So thatās my current prototyping setup. Maybe it will help inspire you to setup your own prototyping environment. Whether you use code or a design appāyou should prototype!
Why I Still Prefer to Prototype Using Code
There are several design apps available at a product designers disposal, and Iāve used several of them over the years. I think these days, most everyone is using Figma, but whatever app youāre usingāmost of them typically have some sort of prototyping feature. Typically they have required very little coding to get a prototype up and running. Despite the advances in the ability to prototype using design tools, I still prefer to use HTML, CSS, and JavaScript. ## Greater Flexibility I find myself needing much more flexibility than what prototyping in Figma offers. I think itās cool that theyāre regularly adding features to make prototyping more flexible, but itās becoming so complicated and time consuming to figure out. A lot of the new features that Figma has been addingālike variablesāis essentially coding! It doesnāt really simplify or speed things up for me. At some point thereās usually a moment where I think this would have been faster if I had just built this prototype in code. When animating designs in a prototyping tool, thereās only so much control over how the transitions work or what they look like. With CSS and JavaScript, I have complete control over how a design animates or transitions. ## Safer Portability When I think of portability, thereās a couple of things that come to mind: being able to easily share a prototype with someone else, and being able to access a prototype regardless of the design tool Iām using. When Iām sharing a prototype with someone I like knowing that I can send them a URL that wonāt breakāat least theoretically. I get that Figma has URLs to prototypes, but I donāt own or have control over that URL. What if Figma changes the URL scheme someday? Would that happen? Probably not, but I also donāt have to worry about it if I own/control the URL. Right now I use Figma. I used to use Sketch, and never thought I would stop using it. I donāt pretend to believe that some new design tool will come and replace Figma some day. If I decide to up and leave Figma, Iād prefer not to have to leave all my prototypes behind. ## Learning and Experimentation Prototyping with HTML, CSS, and JavaScript is a great way to test out new features or frameworks. Through prototyping Iāve learned how to use Flexbox/Grid, [Eleventy](https://www.11ty.dev/), [Sinatra](https://sinatrarb.com/), [P5.js](https://p5js.org/), [Preact](https://preactjs.com/), and a plethora of various little CSS properties or JavaScript methods and micro libraries. Its also a good way to stay on top of whats new and trendy, and try out not-quite-ready-for-primetime features. ## A More Realistic Experience When I use a prototype made in code verses Figma, the coded version feels more real: the way you interact with it, being able to actually type in a text input, being able to use and experiment with more complex interactions. I also typically tend to discover other interactions that go beyond the happy path, and can account for those before engineers discover them while building out the actual feature. States like validation and error, what happens when thereās no data to show, and other uncommon scenarios. ## Design Apps Still Have Their Place I think design apps have come a very long way over time, and it is very convenient to be able to prototype in the same app youāre doing your designing ināespecially if youāre not comfortable with coding. And there are times when I will use Figma prototyping. If I have a simple interaction that doesnāt require a lot of user input or too many frames, then prototyping in Figma is relatively quick and painless. But once I go beyond a handful of interactions, it typically pays off in the long run to just use code.
Using the p5play JavaScript Game Engine
I was messing around with [p5play](https://p5play.org/) last week to experiment with a game idea, and was pleasantly surprised by how easy it is to use. It was designed to be intuitive for beginners, such as students. In under a half hour I had created some common basic mechanics! Check it out: <p class="codepen" data-height="500" data-default-tab="js,result" data-slug-hash="WNmRzOK" data-user="starzonmyarmz" style="height: 500px; display: flex; align-items: center; justify-content: center; margin: 1em 0; padding: 1em;"> <span>See the Pen <a href="https://codepen.io/starzonmyarmz/pen/WNmRzOK"> p5play</a> by Daniel Marino (<a href="https://codepen.io/starzonmyarmz">@starzonmyarmz</a>) on <a href="https://codepen.io">CodePen</a>.</span> </p> <script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script> ### What I Like - It builds on top of [P5.js](https://p5js.org/). This means that I can leverage all the built-in features I'm already familiar with in P5. It even expands upon some built-in features in P5ālike creating a new [Canvas](https://p5play.org/learn/canvas.html). - It uses the same [Box2D physics simulator](https://piqnt.com/planck.js) that some popular games use. Some physics engines are a little floaty, while others are too constrained. This simulator has some really comfortable defaults out of the box. - The documentation is easy to follow along, and there's a [Discord server](https://discord.gg/3UTbqUgmPF) where I can (and have) ask questions. I typically have gotten a response from the library maintainer, himself, within a couple of hours. ### What I Dislike - Not everything is documented, and that's not necessarily a bad thing. However, there are some really handy properties and even methods available that I happened to come across by accident just from purusing the source code and outputting various p5play global methods to `console.log()`. - The licensing is a [little weird](https://github.com/quinton-ashley/p5play/blob/main/LICENSE.md). In short: its free to use for open source projects, but for professional use you need to pay for a license. I'm not going to argue whether you should have to pay for a license or not, but its definately something to be aware of. I'll definitely be keeping [p5play](https://p5play.org/) in my toolkit the next time I want to prototype some game mechanics or participate in a game jam!
Making Generative Art
I saw [Joshua Davis](https://joshuadavis.com/) give a talk over 10 years ago, and I was mesmorized. Not just by how engaging he was, but more so with the work he was doing with *generative art*. I had never heard of generative art before, but I immediately fell in love with the concept of it. I like to draw, but I wouldnāt consider myself much of an artist. I can work my way around Photoshop pretty comfortably, but again, wouldnāt consider myself much of an artist. I didnāt think much of generative art again for some time later. Several years ago, I started toying with the idea fo experimenting with generative art. A buddy of mine, [Arun](https://codepen.io/satchmorun) shared some of his work, and inspired me to go for it. So now Iāve been creating generative art for the past five years or so, but Iāve only recently started [sharing my experiments](/generative-art/)). Libraries like [P5.js](https://p5js.org/) make it very approachable. And Iām a huge fan of P5! I even [made a video game](https://iamdanielmarino.com/posts/github-game-off-game-jam-2021-retrospective/) with it. If you have the slightest interest in creating generative art, you should go for it! If you donāt know where to start, I recommend checking out [The Coding Train](https://thecodingtrain.com/) where youāll find some great tutorials for getting started with programming, and more specific tutorials for using the P5 library. I love to write code. I love art. I love being creative. The idea that I can combine all these into a single hobby is so cool.
Free Radon album released
A little over a year ago, I composed a handful of songs. If I had to fit them into a genre, Iād go with _Lofi_ or _Chillvibes_. Or maybe _Not-Rock-n-Roll_. I donāt knowāIām so bad at classifying music. I wasnāt sure what to do with the songs. I was experiencing some intense emotions when I was composing them. Iāve been doing a lot of emotional growth over this past year (and still am), and I feel like by releasing them into the wild would be cathartic for me. To acknowledge that that chapter in my life happened, and itās okay. So with that, hereās [Free Radon](https://danielmarino.bandcamp.com/album/free-radon). <iframe style="border: 0; width: 100%; height: 274px;" src="https://bandcamp.com/EmbeddedPlayer/album=2458624556/size=large/bgcol=ffffff/linkcol=eb4d55/artwork=small/transparent=true/" seamless><a href="https://danielmarino.bandcamp.com/album/free-radon">Free Radon by Daniel Marino</a></iframe> So why *Free Radon*? Iād like to say I put a lot of thought into naming the album, but I didnāt. I needed cover art for the album, and I thought it would be fun to generate random artwork for it. So I used the [p5.js JavaScript library](https://p5js.org/) to do so. I used the p5.js web editor, and when you create a new sketch it automatically creates a random name for itāin this case Free Radon. Speaking of using p5.js to create the artwork, you can [view the script](https://editor.p5js.org/iamdanielmarino/sketches/0QgAM4zz3), and mess around with it. Hope you like the music. If you do, [share it with others](https://danielmarino.bandcamp.com/album/free-radon), or [buy it](https://danielmarino.bandcamp.com/album/free-radon), or [both](https://danielmarino.bandcamp.com/album/free-radon)! If you donāt like it⦠oh well.
Building a Random Music Sequencer with Preact
As I've composed music for video games, something that has piqued my interest is the concept of randomly generating music. Not that this is a new concept, but I was curious to see what I could come up with. Go ahead and check out the [RMG-2021](https://rmg.iamdanielmarino.com/). ## Design I love how sequencers look and feelāand there is so much variety as to how they're designed! I really wanted to recreate the vibe of using a physical sequencer, and referenced a lot of gear when designing the UI. It was a bit of a balancing act to capture the essence of a physical sequencer while adapting it to a screen.  ## Preact One of my goals was to get better at understanding and using React. I really just wanted to get more familiar with the basics, so I went with [Preact](https://preactjs.com/) which more or less offers the same API and low-level functionality. I'm also using [HTM](https://github.com/developit/htm) which provides JSX-like syntax in vanilla JavaScript. At first, I found it really difficult to buy in to the React/JSX ecosystem, but the more I work with it, the more I appreciate it. I'm still not super fond of writing HTML in JavaScript, but I'm getting over it. ## Sound When working with audio for [ONOFF](https://js13kgames.com/entries/onoff), I used [TinyMusic](https://github.com/kevincennis/TinyMusic), and I'm using it here too. Is it necessarily? No, but true to it's nameāit's tiny, and offers a nice API. It simplifies authoring audio sequences in JavaScript. I'm even outputting the TinyMusic sequence syntax so it can be easily reference it. ## Features This is one of those projects that I could have easily kept adding features. At some point I had to call it _done_ and ship it. Every feature I added ended up adding more complexity to using the sequencer. The RMG allows you to specify: - The number of notes to use in the sequence - Which key the notes should be pulled from - A range of octaves to generate a sequence within - Snapping the total number of beats to an integer - Toggling the loop of the sequence - Toggling a metronome click, and adjusting various metronome settings - Adjusting various effects such as wave type, EQ, sweep, and decay - Adding a _pulse_ effect to a sequence On top of these features you can also easily randomize all the settings, and share a sequence via URL. ## Random Sequences are Fun I've used [random sequences](https://rmg.iamdanielmarino.com/?notes=16&key=E&rangemin=2&rangemax=8&arrangement=B6+0.25%2CE2+2%2CF%234+0.75%2CD%238+1%2CC%234+4%2CF%237+4%2CD%236+0.75%2CD%238+2%2CG%235+0.75%2CC%238+1%2CC%236+0.25%2CD%233+0.25%2CC%233+1%2CF%238+2%2CD%238+0.5%2CD%233+0.5&tempo=314&wave=square&smoothing=0.38&staccato=0.34&bass=-9&mid=-1&treble=-1&loop=true) generated by the RMG for various things: drumming along with sequences, challenging myself to compose music around a random sequence, or even sending goofy sounds to my friends. It was a fun project, and I learned a lot.
GitHub Game Off 2021 Retrospective
Recently, I completed the [GitHub Game Off](https://itch.io/jam/game-off-2021). With over 500 entries, this is the largest game jam Iāve been a part of. I had some lofty goals for this game, and I just about met them all. Iām extremely happy with how the game came out! Like prior games Iāve made, I donāt tend to join a game jam unless I have some specific idea/mechanic Iād like to explore. Iād been wanting to tackle a mobile game for some time now while exploring motion/accelerometer mechanics. ## Mechanics The theme for this jam was ābugā. I donāt remember how I arrived at the concept and gameplay, but the gist is: a fly mysteriously gets sucked into a phone. By tilting your phone (utilizing the phoneās motion/accelerometer sensors), you move the fly to avoid colliding with objects on the phoneās screen. Tilting your phone at steeper angles increases the flyās velocity and speed. While relatively basic, I found it challenging to get the mechanics just right, and reprogrammed this mechanic several times. The game consists of seven auto-scrolling levels, progressing in difficulty as you complete them. Each one is scripted to be about a minute long. While the scrolling is scripted, there is quite a bit of randomness sprinkled into each level such as the placement and dimensions of objects.  The game is hard to play. Really hard. My play testers got frustrated quicklyāespecially with the first round of testing. I did quite a lot of tweaking based on their feedback. I simplified the levels by adding larger gaps between objects and slowing the scrolling down. Even with the adjustments itās still hard to play, but not so hard that itās unenjoyable. I decided I was okay with the level of difficulty. I wanted a game that made you feel good about making progress. Iāve played through the entire game probably five or six times now (aside from rigorous testing throughout), and I can get through from beginning to end in about 20ā30 minutes. ## Graphics If youāve seen the game before reading this, you might think Iām joking by calling the visuals āgraphicsā. Believe it or not, the choice of simplicity was purposeful. I intentionally used a handful of basic shapes and solid colors. Each level resembles a popular mobile app (can you figure out which ones), and all the design is stripped down to each appās bare essence. By keeping the design so minimal, the graphics doesnāt feel overly _iPhone_ or _Android_, so players can relate regardless of what kind of phone they use. Here are a couple of sample screenshots:  I did receive a lower ranking on the gameās graphics, and thatās fair. I can understand why people would want something more high-fidelity. I even questioned my judgement on the decision to go low-fi a few times, but in the end I think it really does enhanced the gameās vibe and playability. While the game play graphics are primarily generated with code, there is a single sprite! Itās the _fly_ character during the cut scenes. I wanted to try out using [Aesprite](https://www.aseprite.org/), so decided to make the fly in the pixel-art style. ## Audio I got a little carried away with audio, and put way more effort into it than I had toāespecially for a game jam. If Iām being honest, I had the most fun when I was composing and producing audio than doing anything else for this game. I didnāt really intend to go all in with the jazz-style of music, but after writing the initial theme I was locked in. I started out composing a simple melody for the title screen. A few days later I had an albumās worth of music! The music is inspired by pianists like Vince Guaraldi and Danillo Perez. I love how they combine simple, playful, and whimsical-sounding melodiesāwith a little dissonance thrown in for good measure. <iframe style="border: 0; width: 100%; height: 406px;" src="https://bandcamp.com/EmbeddedPlayer/album=1082942060/size=large/bgcol=ffffff/linkcol=eb4d55/artwork=none/transparent=true/" seamless><a href="https://danielmarino.bandcamp.com/album/trapped-soundtrack">trapped soundtrack by Daniel Marino</a></iframe> Iām a lot more proficient using [Ableton](https://www.ableton.com/en/live/) and my [Arturia MiniLab MKII](https://www.arturia.com/products/hybrid-synths/minilab-mkii/overview) since my [last game jam](/posts/gamedevjs-jam-2021-retrospective/) and found it much simpler this time to produce music. In keeping with the minimalistic artwork style, I kept the instrumentation minimal as well: piano and drums only. ## Environment and Tooling Like my other games, the game is developed with HTML, CSS, and JS. Iām most comfortable with this tooling environment, and enjoy pushing myself to learn and do new things with it. Iāve been experimenting with creating generative art using JavaScript and the [P5.js library](https://p5js.org/). I wasnāt sure how it would work as a game engine, but decided to try it out. In addition to P5, I also used a couple of additional libraries to help with [scene management](https://github.com/mveteanu/p5.SceneManager) and [collision detection](https://github.com/bmoren/p5.collide2D). Some highlights working with P5: - The output renders to a `<canvas>` element at 60fps, which makes the game quality pretty decent, and performant. - You can get started very quickly because [the loop](https://developer.mozilla.org/en-US/docs/Games/Anatomy#building_a_main_loop_in_javascript) is handled automatically. There are also a ton of useful built in methods for creating and manipulating graphics. - It has built-in event listening for screen touching and device rotation, which was pretty helpful in my case. Despite those highlights, I honestly donāt know if I got as much mileage out of P5 to justify using it. - I ended up having to create my own Class with various methods for drawing and manipulate shapes. This is mostly because I wanted to be consistent in how shapes were generated, as well as being able to easily set up consistent timings for shape manipulation. - I ran into problem using P5ās vector manipulation methods, and used plain āole vanilla JS to calculate and manipulate shapes. ## Developing a Browser-based, Mobile Game is Hard I kind of knew going into making a mobile game was going to come with its own set of challenges, but I wasnāt prepared for how difficult some of them would be to work out: - iOS Safari, for better or worse, has a huge market share on mobile devices. Not only that, all browsersāwhether it be Chrome or Firefox or whateverāon iOS get stuck using the same Webkit rendering engine as Safari. Unfortunately, iOS Safari seems to be a little behind in some features that are implemented, making it difficult to work around some challenges. - iOS requires [acquiring the userās permission to access device rotation events](https://github.com/starzonmyarmz/trapped/blob/main/src/game.js#L39-L50)āwhich not only hinders the user experience, but also adds some complicated code to handle this. It should be noted that P5 doesn't handle this on any level, and just assumes permission is granted from the start. - Itch.io doesnāt handle hosting browser-based mobile games very well. It also doesnāt help that neither iOS or Android make it easy to run cross-origin code. For various reasons working around this limitation is quite painful. In the end I published a QR code with a link to the game on Itch.io and published the actual game on GitHub Pages. - Developing and testing a browser-based mobile game locally is frustrating and kludgy. Itās slower than normal desktop-based development, and debugging was very hard. To access my localhost on my phone I used [ngrok](https://ngrok.com/) to tunnel my localhost to a public server. I would then use the public URL in Safari on my iPhone. I could inspect the DOM and check the console for errors using Safari on my Mac. ## Goals and Results I mentioned at the beginning of this post that I had some lofty goals. They were (in no particular order): - **Complete a mobile game**. Pretty sure I succeeded here! - **Build the game without any assistance**. I did actually have a little help from my buddy, Brad with some of the finishing touches. That said, I did the vast majority of the development on my own, and I feel really good about that! - **Rank in the top 10% of games for the game jam**. Overall, my game ranked 77th out of 526 submissions, which is about the top 15%. Iāll take itāespecially for my first attempt at a mobile game. Also, I ranked 10th for *Audio* and 18th for *Innovation* which I think is awesome! You can check out [my submission](https://itch.io/jam/game-off-2021/rate/1291063) for the score breakdown and player feedback. While I didnāt meet all my goals, I came pretty darn close. More importantly, I had a lot of fun with this game jam. I learned a lot and expanded my knowledge on using P5 as well as other various coding techniques. Besides [Brad](https://github.com/braddunbar), I had help from other folks, and Iād be remiss if I didnāt thank them: [Matthew](https://matthewlettini.com) and [Danny](https://twitter.com/dannywen) for play testing, as well as my kids for play testing and suggesting good ideas when I was feeling stuck. Lastly, my wife: not only does she play my games, but is very supportive, lets me vent about crappy API support, and inspires me to put everything I got into my work. Be sure to give [trapped](https://trapped.iamdanielmarino.com) a play or check out the [source code](https://github.com/starzonmyarmz/trapped)!
Gamedev.js Jam 2021 Retrospective
Recently, I participated in the [Gamedev.js Jam 2021](https://gamedevjs.com/jam/2021/): a 13-day competition to build a game that can run on the Web in a browser without extra plugins. This yearās theme for the competition was āmirrorā, which could interpreted however participants chose. I had an itch I wanted to scratch, and the timing was right, so I decided to join. Youād think JavaScript would be necessary to make an HTML5 game, but the [Internet has shown us](https://codepen.io/collection/AKkZro?cursor=ZD0wJm89MCZwPTEmdj00) _it is_ possible to make simple games without JavaScript. I wanted to see just how far I could take this limitationāespecially in an environment where it is competing against other games. ## Game Concepts [Hiero](https://starzonmyarmz.itch.io/hiero) is the third game Iāve made (the first by myself), and by now I should have some sort of process to making a game, right? Well⦠I donāt really. So far, the process has been different for every game.  In my experience, working on various aspects of a game (artwork, sound, etcā¦) greatly influences the other aspects of the game, so I find myself ping ponging around. Over the course of 13 days, I ended up implementing three core concepts into Hiero. 1. **Complete 15 puzzles within a short timeframe.** Not really much to say about this other than the earlier puzzles start out pretty easy. This teaches the player how the game is played. Over time the puzzles ramp up in difficulty. To keep things fast-paced, the game is short. 2. **To complete a puzzle you have to find the mismatched shape.** Each puzzle contains three to seven shapes. When hovering over a shape, a āmirroredā version of the shape is shown underneath. The catch is, in each puzzle one of the mirrored shapes doesnāt match. In some cases itās a completely different shape, while in others itās a very similar shape with a slight modification. This not only satisfied the āmirrorā theme requirements, but also seemed to be a different and slightly-more challenging take on the classic which-one-doesnāt-belong concept. 3. **You can only make three mistakes.** This was a last minute addition to Hiero. Without it, the game can be cheesed by spamming clicks on the shapes until solving a puzzle. This adds an extra challenge of forcing the player to be judicious with their selections.  ## Mechanics As mentioned earlier, I didnāt want to use any JavaScript. My game is primarily built around two CSS mechanics: checkboxes with insane selector magic to update the gameās state, and an in-game timer created with an animation delay. The resulting code is in no-way elegant! Itās quite messy, convoluted, and slightly laggy. The CSS weighs in at roughly 60K! ### Checkboxes Most interactions are triggered with an HTML checkbox. Take this example: ```html <input type=ācheckboxā id=āfooā> <label for=āfooā>Interactive element</label> <div>Hidden element triggered by checkbox state</div> ``` We [visually hide](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/sass/_base.scss#L30-L35) the `<input>` element using CSS, but we can still interact with it by clicking on a corresponding `<label>`. This works so long as the `for` attribute matches the `<input>`s `id` attribute. The input returns a checked/unchecked state, and if we keep these elements as siblings (as opposed to parents/children) we can use this state to trigger other elements using CSS: ```css div { display: none; } #foo:checked ~ div { display: block; } ``` Now this is a highly simplified example. Iām combining this checkbox functionality with CSS animations to time certain events such as scenes being loaded or triggering sound effects. Very little HTML is nested, and most elements are siblings to one another. One of the challenges was implementing the layout/design while keeping the HTML mostly flat. If I had nested elements a certain way, they wouldn't have been selectable with CSS. ### Time Limit When the player starts the game, it kicks off the [losing scene animation](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/sass/_lose.scss#L36-L37) with a 78-second delay. The only way to pause/stop the animation is to [match the CSS selector](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/sass/_transitions.scss#L40-L55) that determines if you beat the 15th puzzle, which simultaneously triggers the winning animation. Controlling animations this way is achieved using the `animation-play-state` CSS property. ### Triggering Sound Setting an `<embed>` element to `display: none` will prevent itās content from loading until itās `display` property is reverted. So by setting an `<embed>` source to a sound file, I was able to use this to load sound on demand. However, once the content is loaded, itās here to stay. You canāt hide/unhide it to make it play again, stop it from playing, or even loop it. This trick also does not work with `<audio>`, `<video>`, or `<iframe>` elements. I was able to use the same checkbox mechanics above, and in some cases, an elementās `:hover` state to change an `<embed>`s `display` property. These constraints made it challenging to work with sound, but I am very happy with how it came out. ## Artwork I knew I was going to need a decent amount of artwork for matching shapesāon top of the other game-supporting graphics. By chance, I discovered that there are a ton of Hieroglyphs available as unicode characters. This spearheaded the visual direction, and adds to the gameās ominous atmosphere. As I sketched out ideas for the interface, the more I liked the idea of using my personal art style which combines hand-drawn illustrations and digital painting. As I started putting all the pieces together it started feeling a bit like a cartoon. This inspired my use of [Kalam](https://fonts.google.com/specimen/Kalam#standard-styles) for the title screen. I wanted to use something a little more legible for the interface text, and landed on [Josefin Sans](https://fonts.google.com/specimen/Josefin+Sans) which is inspired by geometric sans serif designs from the 1920s. To really help seal the deal on the old-school cartoon vibe, I added the film-grain overlaying textures, using CSS animation to [shift the texture around](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/sass/_base.scss#L128-L135). In my opinion, this game would have worked just as well without the mirror graphic. It certainly would have simplified development not having to incorporate it! However, it really helps to drive the jamās theme, so why not. It also gave me an excuse to mess around with CSS 3d transforms and perspective which isnāt something I get to do too often. The last thing Iād like to talk about in regards to the artwork is the ātunnel visionā gradient that occurs as you near the end of the time limit. This was an idea my daughter had while play testing for me. It really helps simultaneously create tension, panic, and focus. This was implemented at the last minute using a CSS `radial-gradient` and [animating itās appearance](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/sass/_base.scss#L139-L172).  ## Sound Design In the past, I've used JavaScript-powered, chiptune-styled sound. But that wouldn't really match the art style or ambiance. Also, I wanted to try something new! The limitations for triggering sound created some challenging conditions for creating sound. I couldnāt always control when the player would trigger a scene transition. Syncing chord progressions, rhythm, and melodies together was practically impossible. My approach was to keep the sound atmospheric in a way where sounds could be independently layered. The result was a bass layer of a single chord being held while randomly fluctuating effects on it. Next, a percussive track is layered on top when the player instantiates the game play. 30 seconds in the percussive track starts having echo effects slowly applied to help build intensity and uneasiness. Finally, a game over sound is layered in. ## Tools Iāve become a big fan of [Eleventy](https://www.11ty.dev/) since using it for my blog, and ended up using it to generate the game. It makes life so much easier than having to hand code every puzzle. With Eleventy, I have a [JSON file](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/src/_data/puzzles.json) with all the puzzles, an [Nunjucks](https://mozilla.github.io/nunjucks/) [puzzle template](https://github.com/starzonmyarmz/gamedevjs-jam-2021/blob/main/src/index.njk#L25-L40), and Eleventy just spits out the final HTML. One could argue that Iām using JavaScript by creating my game using Eleventy and Nunjucks, but Iām really just using those tools to optimize my workflow. The final output is HTML and CSS. I used [Sass](https://sass-lang.com/) for authoring CSS. I donāt always use Sass because I find the overhead isnāt always worth the benefits. However, in this case I really took advantage of Sass loops and logic statements which made it a lot faster/easier to generate a lot of the selector magic I shared earlier. I use any paper and pencil I can find to illustrate, and then ink those with [Microns](https://www.dickblick.com/products/sakura-pigma-micron-pen/). Scan them in with my phone, and send them to my computer where I use [Pixelmator](https://www.pixelmator.com/pro/) to paint and optimize images. To create all the sounds, I used a [MiniLab MKII](https://www.arturia.com/products/hybrid-synths/minilab-mkii/overview) midi controller by Arturia with [Ableton Live](https://www.ableton.com/en/live/), as well as [Audacity](https://www.audacityteam.org/) to refine the sounds a bit. Creating sound for this game was a completely different experience for me compared to [ONOFF](https://js13kgames.com/entries/onoff), and I absolutely loved it! First of all, using a midi controller and Ableton are brand new tools for me. I spent two or three days doing nothing but messing around with sound and learning how to use Ableton. I really do see myself taking advantage of these tools in future projects! The source is [hosted on Github](https://github.com/starzonmyarmz/gamedevjs-jam-2021), and Iām using a GH workflow that was shared with me by one of the other developers in the jam which generates a ZIP file of the game and assets, and uploads it to [Itch.io](https://itch.io/jam/gamedevjs-2021/entries) where the game jam and games are hosted. ## Nice to Haves There are two primary things I really wish I could have put in the game, and would have had I not restricted myself from using JavaScript: a restart button on the end scenes, and the ability to randomize puzzles. The later would have added a lot more replay value. At the same time, it doesnāt bug me too much because I like the fact that everyone can beat the game after playing it a handful of times from memorizing the puzzle. I suppose another minor _nice to have_ would have been a counter letting you know how many strikes you have. That would have been easy enough to implement, but didnāt because I didnāt think it was too hard to keep track of strikes, nor did it add a lot of value by showing you those strikes. ## Also⦠What I havenāt mentioned yet is my son also joined the game jam! Heās been learning [Unity](https://unity.com/) and [Blender](https://www.blender.org/), but has struggled to complete a full game. I suggested he work with me to get some experience. After I shared my game idea, he decided to [go it alone](https://twitter.com/starzonmyarmz/status/1381928874272030722?s=20)! We had a lot of fun pinging ideas of of each other, sharing each others pain and frustrations, and play testing! Iām very happy with how his game, [Mirror Madness](https://glassedgmr.itch.io/mirror-madness) came out, and am very proud of him. ## Wrap Up Heiro was ranked 11th out of 88 submitted games. I was hoping for top 10, but I'm not going to complaināespecially since the game only uses HTML and CSS mechanics! You can also check out the [full score breakdown](https://itch.io/jam/gamedevjs-2021/rate/1007795), if you feel so inclined. Iām extremely happy with how [Hiero](https://starzonmyarmz.itch.io/hiero) came outāespecially given the personal challenge of not using JavaScript! Thanks for everyone who played, and scored my game. Iād like to thank my daughters for play testing and being brutally honest when I asked for feedback. They gave me great ideas and pushed me to make Hiero as good as it is. My son, for coming along for the ride for me. And my wife, for putting up with the shenanigans of her middle-aged husband, and for challenging me to always do my best. I donāt know when Iāll make my next game, but the ideas are already brewing!
My GIF Workflow Using Eleventy, Netlify, and Alfred
I used to keep my GIFs on Dropbox in the `/public` directory. There was a time when Dropbox would serve content as HTML from this directory. This was a simple way to share my GIFs with the world. I even adopted an [Alfred workflow](https://destroytoday.com/blog/gif-workflow) for quickly searching and copying my GIFs URL to the clipboard. Back in 2017, Dropbox disabled the ability to render HTML from the `/public` directory, and thus this workflow stopped working. Since then Iāve been keeping my personal collection of GIFs in a GitHub repoāwhich has been just okay. I really missed having a quick way to search and copy URLs. To use a GIF Iād have to go to the repo, find the image, view the raw image, and finally manually copy the url from the browser. Lame. A few weeks ago, I decided to give my GIF workflow an upgrade! I started by turning my [GIFs repo](https://github.com/starzonmyarmz/gifs) into a static site using [Eleventy](https://www.11ty.dev/). The static site consists of two primary things: a directory with all of my GIFs, and a [generated JSON file](https://github.com/starzonmyarmz/gifs) listing all my GIFs (more on this in a bit). I created a new site on Netlify that watches my GIFs repo, and runs a build process anytime I push to `main` branch. This only took a few minutes to set up, and all my GIFs are now easily accessible by URL. I was still missing a component thoughāa quick and easy way to search for GIFs and copy their URLs. I built an [Alfred script](https://github.com/starzonmyarmz/gifz-alfred-workflow) using [Alfy](https://github.com/sindresorhus/alfy) to handle this part. Alfy is so cool to work with, allowing you to build Alfred workflows using JavaScript and Node. The Alfred Script takes an input, and searches for it against the [JSON file on the Netlify site](https://gifz.netlify.app/gifs.json). When I find the GIF I want, it copies the URL to the clipboard.  This update was well-needed, and I find myself using my personal GIFs much more often now! I only wish I had done something like this much sooner.
How to Process Customer Criticism
Why do us product designers opt into a career where weāre regularly challenged to be vulnerable?! Design is super subjective, and everyone is a critic! Regardless of your education or how sharp your _design eye_ is, youāll never be able to please everyone. This is especially true when you work on a product that has thousands upon thousands of users! One of my personal challenges of being a product designer is learning how to process customer criticism. Its an ongoing struggle for me because I tend to be very sensitive to criticism in general. Iāve grown thicker skin over time, but there are still some days where I get down in the dumps. My knee jerk response is to cave in, and give everyone what they want (or demand) so we can all be happy. However, good product designers donāt cave. We take a breath and carefully processes the criticism. ## Digging into Customer Criticism Itās hard, but sometimes you need to dig underneath the harsh and sometimes-hurtful comments. Is there actual legitimate feedback? Even if a customer insults you, it doesnāt negate the fact that theyāre having a poor experience. Once youāve pushed past the hurtful comments and processed the feedback, are there common themes or issues raised by these customers? Obviously, bugs should be fixed, but have you overlooked some UX considerations? Be honest with yourself. If there are things you can improve, and time allows for it, you should improve them. Even the tiniest improvement can be enough to change someoneās reception to a design! ## Haters Gonna Hate What about the people that hate something just because they can? Sometimes you just have to accept the fact that some people arenāt going to like something. Some things to consider: * **Youāre more likely to hear negative feedback.** People are more inclined to write a support ticket when they dislike something. For every person complaining about your design, thereās likely hundreds or thousands that really like it! * **Some folks like to complain for the sake of complaining.** Iām not ashamed to admit that if someone tweets something nasty at us, Iāll often stalk them on Twitter for a bit to help get a read on the person. Youād be surprised (or maybe you wouldnāt) how often these folks are habitual complainersāwasting time tweeting at other companies. Youāll never please these people. * **Sometimes a thoughtful response will be appreciated.** I donāt necessarily do this for every support request, but sometimes Iāll respond by explaining the reasoning of why a design was implemented the way it is. This does require a little care because you donāt want to sound like you donāt care about a personās feedback. You still want to acknowledge the the customerās complaint even if youāre not planning on changing the design. Sometimes these customers reply with a heartfelt appreciation for the explanation. * **If someone really dislikes your product, theyāll pack up and leave.** It sounds harsh, but itās reality. Obviously you donāt want an exodus, and if thatās the case you should probably take a step back and reexamine things. However, itās quite possible your product isnāt the right fit for some particular people. That said, itās also unlikely that one disliked design is going to drive a customer away. ## Abusive Customers I donāt advocate taking abuse from customers on the chin. While I donāt think itās okay to sling it back at your customers, I do think itās fair game to call out hostile tone. Iām blessed to work for a [company](https://www.getharvest.com) that has a policy around handling abusive customers. Your company may also address how to handle these types of customers. If youāre in a position to make these types of policies I highly recommend you do! ## Youāre Awesome I mean⦠maybe youāre not awesome? Regardless, dealing with customer criticism can be really hard! And at the end of a hard dayāno matter how awesome you are or arenāt, [treat yoself](https://media.giphy.com/media/13jJIY0llDdip2/giphy.gif)! Have a little extra dessert, play video games a little longer, crank some tunes extra loud! Try not to take customer criticism personally. Instead, look past the harsh tones, and try to find legitimate and actionable feedback.
Donāt Overthink Remote Working
The coronavirus is here, and as a result a lot of employers are asking employees to work remotely if possible. Iāve seen a fair share of _tips for remote working_ blog posts this past week. I figured Iād cash in on the action and share my thoughts. ## Donāt Overthink It Most of the posts Iāve read, more or less, are saying the same things: have an enjoyable working environment, communicate with your team regularly, stick to a schedule, yada yada yada⦠All of those are great, but also seem subjective. Maybe its because Iāve been a remote working for over 10 years, but I have a different point of view here. The best advice I have is: **donāt overthink it**. Iām not saying all those other things arenāt important, however if you spend too much time focusing on: _I have to do this_ and _I have to do that_, youāll probably find the transition will be more difficult and take longer. ## It is a Transition Simply be aware that remote working _is_ a transition, especially if youāve worked in an office environment for some time. And thatās ok! Recognize this, but try not to dwell on it too much. Do what you can to figure out how to get into _your_ groove quickly. Maybe that means working in pajamas, or working at the kitchen table instead of a dedicated office, or whatever! The fact is, it will take you a little time to get used to remote working. And youāll likely have to try different things to find what works for you. Your preferences might also fluctuate over time. Be aware of the transition, and try not to overthink it.
Deploying My Eleventy Site to GitHub Pages
I really like [GitHub Pages](https://pages.github.com/), and have used it to host my site for a while. The biggest challenge of switching my site to [Eleventy](https://www.11ty.dev/) was getting deployments to GitHub pages set up. I suppose I could have built my site locally, and then push that to the `gh-pages` branch, but that felt _wrong_. I prefer my `master` branch to be the source of my site, while `gh-pages` to only be the published content. Iām aware of tools such as [Netlify](https://www.netlify.com/) and [Travis CI](https://travis-ci.com/) which aid in hosting or deployment processes. However I wasnāt looking to add another service into my tech stack. With some digging into [GitHub Actions](https://github.com/features/actions), this seemed like a plausible route for getting my site deployed without having to rely on an external service. ### Setting Up a GitHub Action GitHub Actions allow you to automate workflows such as code deployment, running tests, compressing images, and so much more. GitHub has a whole _Marketplace_ where you can explore community-created actions. Iām using the [GitHub Pages action](https://github.com/marketplace/actions/github-pages-action) which handles everything I need for deploying. My workflow is fairly simple, and is largely based on the instructions for [Static Site Generators with Node.js](https://github.com/marketplace/actions/github-pages-action#%EF%B8%8F-static-site-generators-with-nodejs). In `/.github/workflows/eleventy_build.yml`, I have the following: ```yaml name: Eleventy Build on: push: branches: - master jobs: deploy: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 - name: Setup Node uses: actions/setup-node@v1 with: node-version: '10.x' - run: npm ci - run: npm run build - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: deploy_key: {% raw %}${{ secrets.ACTIONS_DEPLOY_KEY }}{% endraw %} publish_dir: ./dist ``` Depending on how your Eleventy project is set up you might need to make some tweaks to the defaults. I recommend checking out the rest of the [documentation](https://github.com/marketplace/actions/github-pages-action#table-of-contents) to see what you can do. ### Hey GitHub, Iām Not Using Jekyll I found this to be the biggest hurdle, and it kind of buried in [GitHubās documentation](https://help.github.com/en/github/working-with-github-pages/about-github-pages#static-site-generators). By default, GitHub tries to use Jekyll to build your site. If youāre using any syntax other than what Jekyll recognizes, then you _might_ get errors and your build could potentially fail. The good news is the fix is really easy. In the root of your project, include an empty file `.nojekyll`. ### Committing the Package Lock file This GitHub action is an _automated environment_, so rather than use `npm install` our action should use `npm ci`. This ensures that you get a _clean install_ of your dependencies. One of the requirements for using `npm ci` is that the project **must** have an existing `package-lock.json`. Iām not really sure what the norm is here, but I donāt typically commit this file. So if you fall into that category, make sure you get that file committed! ### Creating an NPM Build Script When itās time for Eleventy to build your site when the `master` branch is pushed upstream, it needs to happen in the context of the Node environment. In my `package.json` I have a script mapped to the command `eleventy`: ```json "scripts": { "build": "eleventy" } ``` Now when `npm run build` runs in the GitHub action, it will know where to find the `eleventy` command. ### No SSH Deploy Key? No Deployment! For security purposes, GitHub requires that you have a _deploy key_ and a corresponding _secret_ set up in the repository that this GitHub Action is in. Thereās handy [step by step guide with screenshots](https://github.com/marketplace/actions/github-pages-action#%EF%B8%8F-create-ssh-deploy-key) on how to create the deploy key and secret, as well as adding them to the repository. In my case Iāve labelled my deploy key _ACTIONS_DEPLOY_KEY_. This is case-sensitive, so make sure you pay attention to what you call your deploy key! ### Wrapping Up While Iām not sure if this is the best way to get my Eleventy site deployed to GitHub Pages, it meets my needs. As far as I can tell, this general deployment process would be fairly similar to set up with a service like Netlify or Travis CI. However I find it extremely satisfying not being dependent on extra services.
Trying Out Eleventy
As I started to think about blogging again, I began looking at options for hosting, CMS frameworks, static site generators, etc. [Eleventy](https://www.11ty.dev/) has been in the mainstream for sometime now, and I've heard nothing but good things about it. I figured I should give it a shot. There are no shortage of examples for using Eleventy, but I particularly found [Andy Bellās](https://hankchizljaw.com/) [Hebra](https://github.com/Andy-set-studio/hebra) starter kit, as well as the [Eleventy Base Blog](https://github.com/11ty/eleventy-base-blog) to be excellent resources. I'm using [Nunjucks](https://mozilla.github.io/nunjucks/) for templating. It more or less feels like [Liquid](https://shopify.github.io/liquid/) which I'm familiar with from having used [Jekyll](https://jekyllrb.com/), as well as creating [State Motto Prints](https://states.iamdanielmarino.com). In the course of an afternoon, I was able to put together the [bones of this redesign](https://github.com/starzonmyarmz/iamdanielmarino.com). Over the past week, during my spare time, I've been adding polish, and getting deployments working with Github Pages. I'll continue to make tweaks here and there, but overall I feel good about it.
How I Manage Projects
As a Product Designer at [Harvest](https://getharvest.com), part of my role is running projects. While I donāt believe there is a _right_ or _wrong_ way to manage projects, I do think there are some methods that can yield better results. Iām hardly an expert in this area, but Iād like to share some of the ways I find success in managing projects. I should mention that these thoughts are my own. Iām extremely blessed to work for a company that gives some freedom as to how individuals run projects. Of course there are some fixed variables. For example, we all use Basecamp for tracking updates, and follow the same guidelines for communicating updates with other teams within Harvest. ### Ethos I donāt really have some profound wisdom to share. Basically, I try to stay out of the way as much as possible, leaving room for my teammates to get their work done. Their time, much like mine, is valuable. Out of respect, I try not to gum up the works with unnecessary meetings or emails. This doesnāt mean Iām out of the loop. Weāre all generally aware of what the other person is working on. ### The Kickoff In preparation for the _Kickoff_, I prefer creating a Google Doc with the project details rather than a slideshow. Itās much easier to review and edit on the fly. I also donāt have to get hung up on the little things like _does this slide look pretty_. Typically, I keep the Kickoff to 30 minutes or less. This isnāt the place to figure out technical or design decisions. We still might kick around some ideas and ask questions, but typically we breakout into smaller groups as needed. My preference is to have the Kickoff the Friday before the project starts. This allows my distributed team to hit the ground running first thing Monday morning. ### Weekly Hangout Once a week, our team will meet over a Google Hangout for about 20ā30 minutes to discuss updates. We donāt necessarily try to solve problems in these meetings unless theyāre quick and easy to figure out. The goal of these hangouts is to make sure weāre all on the same page throughout the course of the project. ### Daily Slack Check-in Simply put, I hate _unnecessary_ meetings, and find that most others do too. They disrupt the flow of my work day, and I suspect they do for others too. I prefer daily check-ins on [Slack](https://slack.com/) because itās asynchronous. It allows my to get updates as breaks occur naturally throughout my day. I ask teammates to write a one- or two-sentence update. Basically what are you working on and is anything blocking you from completing it. Short and sweet. Of course, if something is pressing or Iām blocking a todo from progressing, I ask my teammates to @ me, so that I get an immediate notification. I know some people are into multiple email check-ins throughout the week (such as Basecampās automated check-ins). Personally, I dislike theseāprimarily because it feels like extra clutter in my inbox. ### Todos on Basecamp Previously I mentioned we all use [Basecamp](https://basecamp.com) at Harvest. I hold my teammates responsible for making todos, and keeping related discussions up-to-date. That means a developer may create multiple todos for building out a feature or creating a todo for me to apply some design polish. Thatās the bulk of it. Of course there are little things here and there that I didnāt go over, but this should give you a glimpse into how I manage projects.
JS13K 2018 Retrospective
In one of my weekly developer emails, I saw a link for [JS13KGames](https://2018.js13kgames.com/). I've always wanted to create a video game. I asked my JavaScript-whiz buddy, [Brad](https://github.com/braddunbar), if he was interested in building a game with me. Without hesitation, he said āYes!ā ### Concept A couple of years ago I came up with the basic concept/mechanic of toggling layers on and off to create various platforming challenges. I had even sketched out several level designs, and cobbled together a super basic prototype using [Phaser.io](http://phaser.io/). I was pretty happy with this simple mechanic. On top of that our character movement would consist of basic platforming: moving left/right and jumping. There are [other ideas](https://github.com/starzonmyarmz/js13k-2018) we had early on such as moving platforms/spikes, enemies, variances in gravity, as well as an in-game timer, but we ended up punting on those due to time and size constraints. Aside from adding complexity to our code, I think having the constraints challenged us to explore more with level design - as well as simplifying game play. ### Art Style, Design, and UX Originally, I envisioned the game having a pixel art style, but with the 13K and 30 day limits, I decided to simplify. Designing a minimum of 20 levels would take up quite a bit of time. Exploring pixel sprite and background designs would have prevented me from being able to create enough levels to make the game worth playing. I decided to stick with two colors. I wanted to avoid using text to educate game mechanics. I took inspiration from countless video games (but specifically Super Mario World, Super Metroid, Megaman X), and started out by creating the first three levels that would introduce game mechanics one at a time. I then kept exploring various level designs until I had about six or seven solid levels.  While Brad was developing the mechanics, I solicited the help of my son to help me design the character. It went through some variations, but the final character was pretty similar to what we started with. In my mind I could see his legs moving and his head bobbing. He originally had rounded corners, but that ended up making the `svg` output more complicated, so in the end we ditched them.  I liked the idea of the _toggle_ concept being carried through all the various screens, and not just the levels. So I designed the title, end, and controller screens with this in mind.  ### Music and Sound Effects I procrastinated with sound for two weeks or so. At first I got hung up on the options available for creating music and sound effects, until I came across [TinyMusic](https://github.com/kevincennis/TinyMusic). I really liked the simplicity of it, that I was able to focus on music, not getting hung up on the plethora of styles and effects. The [original track](http://jsfiddle.net/0k6tLnfd/8/) I wrote was more driving, but lacked personality. I hemmed and hawed for a week, then one morning I just started humming a really silly tune, and it felt just right for the game. The second part of that song (with the walking bass line) came a week later. I was experimenting to see if I could get chords [fade in and out](https://github.com/starzonmyarmz/js13k-2018/blob/gh-pages/src/sound.js#L327-L351). Once I got that working the bass line just worked itself out, and I had the second half to my song. For sound effects, I had found some effects I really liked on [OpenGameArt](https://opengameart.org/) - however the file sizes were huge. No amount of resampling got them even close to 13K. So I ended up trying to _recreate_ those sounds using TinyMusic. ### Development We didnāt think it was necessary to use `canvas`, and opted use `svg`. This allowed us to easily scale graphics, use CSS to flip the colors when the layers were toggled, as well as easily develop graphics. In a lot of cases, I hard coded graphics such as the [death animation](https://github.com/starzonmyarmz/js13k-2018/blob/gh-pages/index.html#L135-L159) or the death counter, and then Brad would step in and wire it up with JavaScript. I ran every graphic I created through [SVGOMG](https://jakearchibald.github.io/svgomg/) which helped keep our SVG super lightweight. In some cases, I found it more performant to use plain old `rect`s or take advantage of SVG `pattern`s for the [numbers used](https://github.com/starzonmyarmz/js13k-2018/blob/gh-pages/index.html#L107-L118) in the death and level counter, as well as the [spikes](https://github.com/starzonmyarmz/js13k-2018/blob/gh-pages/index.html#L80-L93). I left the decision to Brad whether we should roll our own game mechanics or use an existing library. We both felt it would be more fun to write our own. This also gave us a lot more control over the file sizes and code quality. Using ES6 made the vast majority of the code easier to write, and we didnāt end up having to polyfill anything. For level design, Brad had created the ability to bootstrap levels quickly just by passing in an array of coordinates for the character, goal, and platforms (including the layer they should exist on). After getting a little burnt out on level design, I messed around with creating some dynamically generated levels. We developed right up to the very end. Within the last 12 hours before the deadline we rolled out Gamepad support, the ability to share and play custom levels, and wrote another song to play when the game is completed. ### Tooling and 13k Our tooling was minimal. We would run our JS, CSS, and HTML through minifiers - thatās it. We decided to build everything as minimal as possible from the beginning, so we didnāt really have to go back and rework anything to hit the 13k limit. After building the game we were still far under 13k, so Brad decided to roll out a custom level editor! That actually turned out to be a huge help because it made it a lot faster to test out ideas, and generate level code that we could just paste into our game. We though it was so cool we decided to include it as a bonus with a day left before the deadline! ### Playtesting Aside from having our kids play the game frequently (and they did!) we invited a few friends to play with about a week left in the competition. They felt that the game mechanics felt good, and were fairly easy to figure out. Looking back I wish we had people play it sooner - only because we were scrambling around with a few days left to finish building the game. If we had received more drastic feedback, we would have been in a really tight spot. ### Wrap Up Brad and I had a blast working on the js13k this year! Iām really grateful to Brad and all his help, our friends who took the time to playtest and give us feedback, and especially our families who gave endless support, and endured hours and hours of that music loop! If you havenāt yet, make sure you check out our game [ONOFF](https://js13kgames.com/entries/onoff)!
My First Sketch Plugin and What I Learned
Iāve been Adobe Illustrator free for almost six months now, and what I miss most about it are some of the nice effects it ships with. I love Sketch, but I donāt think these effects will ever make their way into Sketch. Sketch does have the ability to add plugins, and Iāve always wanted to try my hand at creating one. I really miss is Illustratorās _Roughen_ effect as itās really useful for creating that trendy-old-timey-beat-up look. Since a Sketch plugin that _roughens_ a path doesnāt already exist (that I could find) I decided to create one! Iām going to be up front, and this is mostly a decompression of all the frustration I felt while working on the plugin. ## Delete and reinstall * Infinity I spent a lot of time just uninstalling, reinstalling the plugin any time I made a change to the plugin script. This was super annoying, but Iām not entirely sure if there was a way around this. Using the **Custom Plugin** menu option was quick and useful for testing out snippets of code, but itās not a fully fledged code editor, so I wouldnāt want to use it for sole development. Using `print()` was sometimes useful for logging data to the console, but a lot of the times what was being logged was utter nonsense and useless. This brings me to my next topic. ## Documentation Wasnāt Too Useful I admit Iām not a hardcore developer, but I like to think Iām seasoned enough that I can review some documentation and forge ahead. Looking at the docs on Appleās site was like reading a Unix software manual out of the 80ās. It didnāt help me out so much. Not only that, Googling Appkit or Cocoa (to be honest I donāt even understand which is which) methods didnāt help either. Is there a secret club you have to belong to to get useful examples and tutorials? Iām good with JavaScript, so CocoaScript was nice for bridging the gap. However itās really weird to me that you can write code in Cocoa notation in CocoaScript. Pick a syntax variation and stick with it! The Sketch API docs are incomplete, and the examples that were there werenāt entirely useful. They must also be restructuring because halfway through development all the docs and links changed. Some content was removed entirely that I found kind of useful. Thank God for Google caching! I learned the most from looking at other plugins that did similar things I was looking to do. I also found [this resource](https://github.com/turbobabr/Sketch-Plugins-Cookbook) invaluable - there is so much great stuff in there. ## Late to the Party So while Iām decompressing from this project Iām remembering I belong to the [Team Sketch](http://teamsketch.io/) Slack Team. I wish I had remembered this earlier because thereās a channel dedicated to plug in development, and Iām sure I couldāve have received a lot of help from there. Just scrolling through the last 50 or so messages I saw an assortment of links that would have been useful. ## Wrap Up I know I complained a lot in this post. Despite the things that I felt held me back, I feel like I can improve my plugin quite a bit, so I wouldnāt say Iām done. Iād like to utilize the Team Sketch Slack Team and some of the resources I found.
Install Mcrypt PHP Extension on OSX Yosemite
After updating [Statamic](http://statamic.com/) to 1.10.2, I started getting [Mcrypt](http://en.wikipedia.org/wiki/Mcrypt) errors. After some Googling, I found some complicated fixes. After some noodling around, hereās a simple way to fix it with [Homebrew](http://brew.sh/): First, figure out which version of PHP youāre running. You can do this by opening up Terminal, and running the following command: ```bash > php -v ``` I happen to be using PHP 5.5.21 locally, so Iāll use that in my examples. Next, _tap_ the `homebrew/php` cask: ```bash > brew tap homebrew/php ``` This next step is sort of optional. You can search for which versions of mcrypt is available to make sure it matches your version of PHP: ```bash > brew search mcrypt ``` Like I said earlier, Iām running PHP 5.5.21. Make sure you install the version that corresponds with your version of PHP. ```bash > brew install php55-mcrypt ``` That last command took several minutes to install it on my machine. After it is installed, restart the server, and you should be good to go!