Journal

Videojuegos y bandas sonoras de 8 y 16 bits

Aún recuerdo ese verano. Tenía 13 años, y alquilé un video juego con un amigo para la SEGA Megadrive que quedaría impreso en mi memoria (de hecho, aun recuerdo alguno de los cheat codes :-)).

El juego del que hablo es “Asterix y Obelix: El gran rescate”. No por el juego en sí, que a pesar de ser divertido, era bastante mediocre para la época, sino porque su banda sonora era muy elaborada, dinámica, y ganaba protagonismo sobre la acción del juego, cosa tampoco demasiado común, donde en general las bandas sonoras de 16 bits se acababan por hacer algo repetitivas tras unas cuantas horas de juego.

Con 12 o 13 años, no estaba muy puesto en compositores musicales, tampoco me cuestionaba asuntos relativos al juego, mucho más allá de cómo pasarme el nivel, pero gracias a una escucha adulta posterior, me he dado cuenta que la calidad de esta obra no es casualidad. Nathan McCree era la persona detrás de esta elaborada composición (luego vendrían cosas como Tomb Raider). Pero aún así, me pregunto: con las limitaciones de los medios de la época, ¿cómo fue posible alcanzar ese nivel de sofisticación?

Por su puesto, me estoy refiriendo a usar un chip como instrumento, y una interfaz de texto como entrada, para alguien, que incluso siendo compositor musical, tuviera unas restricciones tan marcadas. Otro claro ejemplo de esta asimetría, y que me recordó un amigo el otro día, es “Monty on the Run”, con un Rob Hubbard quasi barroco:

En el caso de Megadrive el chip era el YM2612, fabricado por Yamaha. Lo curioso de este procesador: limitado en cuanto a reproducción de samples de audio:

While high-end chips in the OPN series have dedicated ADPCM channels for playing sampled audio (e.g. YM2608 and YM2610), the YM2612 does not. However, its sixth channel can act as a basic PCM channel by means of the ‘DAC Enable’ register, disabling FM output for that channel but allowing it to play 8-bit pulse-code modulation sound samples.

y además había que controlar la frecuencia y el buffering en proceso principal:

Unlike other OPN chips with ADPCM support, the YM2612 does not provide any timing or buffering of samples, so all frequency control and buffering must be done in software by the host processor.

Para el caso del Commodore, el Sound Interface Device: SID

The majority of games produced for the Commodore 64 made use of the SID chip, with sounds ranging from simple clicks and beeps to complex musical extravaganzas or even entire digital audio tracks. Due to the technical mastery required to implement music on the chip, and its versatile features compared to other sound chips of the era, composers for the Commodore 64 have described the SID as a musical instrument in its own right.[15] Most software did not use the full capabilities of SID, however, because the incorrect published specifications caused programmers to only use well-documented functionality. Some early software, by contrast, relied on the specifications, resulting in inaudible sound effects

Maldita sea, parece que en vez de componer, luchaban contra el instrumento. De alguna forma, esa limitación técnica (oh sorpresa!) dio lugar a decisiones brillantes.

La solución más evidente al oído es el uso intensivo de arpegios rápidos. ¿Que no podemos hacer acordes? No problemo, se simulan descomponiéndolos en sucesiones de notas individuales tocadas muy rápido. El oído humano hace el resto. En chips como el SID del Commodore 64, con solo tres voces disponibles, esta técnica permitía componer armonías complejas, con bajos y melodías simultáneamente.

Rob Hubbard fue un maestro en este arte. Monty on the Run no suena como un simple tema pegadizo: suena exuberante, casi excesivo me atrevería a decir, como si el chip estuviera a punto de explotar. Y, en cierto modo, lo estaba:

  • Sonidos que aparecen y desaparecen en milisegundos
  • Timbres que mutan mientras la nota sigue sonando
  • Una polifonía aparente casi imposible

Y mirando las rutinas musicales desensambladas, vemos:

  • Rutinas de interrupción extremadamente ajustadas
  • Cambios de registros del SID dentro del mismo frame
  • Uso deliberado de valores ilegales o mal documentados
  • Escritura en registros en momentos muy concretos del raster

Nathan McCree jugó una partida distinta pero igual de interesante en el caso de la Megadrive.

El YM2612, con la síntesis FM, permitía timbres más ricos que los PSG clásicos, pero imponía otra clase de “desventaja” (que en realidad no lo era): sonidos metálicos, bajos difíciles de controlar, y un DAC rudimentario. Aun así, McCree consiguió una banda sonora con estructura, leitmotivs y desarrollo, algo poco habitual en juegos de acción de la época.

Aquí aparece otro truco, creo, fascinante: usar el canal DAC no como un sampler tradicional, sino como textura para la percusión y el bajo. Los timbres, los golpes metálicos, casi “sucios”, cosas que hoy llamaríamos glitches, pero que entonces eran el resultado de empujar el chip más allá para llegar a imitar un sonido concreto. Ese ruido, casi analógico, le daba el carácter único.

Otros compositores siguieron caminos similares. Yuzo Koshiro, por ejemplo, en Streets of Rage, llevó el YM2612 a territorios casi underground, inspirándose en el house y techno de los 90’s, con patrones rítmicos que disimulaban las limitaciones del chip mediante la repetición hipnótica de melodías muy pegadizas.

Y Tim Follin, por su parte, parecía directamente ignorar las reglas: sus composiciones para NES, Commodore o Spectrum sonaban imposibles, con esas escalas rápidas, modulaciones extremas y cambios de dinámica que ahora me hacen preguntarme si realmente salía de ese chip:

Y aquí es donde la asimetría se vuelve evidente: juegos modestos, incluso mediocres, sostenidos por obras musicales que los superaban. Como si alguien hubiera colgado un cuadro de un pintor flamenco en el salón de un piso de estudiantes.

Con el paso del tiempo, pienso que muchas de estas bandas sonoras han sobrevivido mejor que los propios juegos. Se reinterpretan en conciertos, se versionan, se analizan en vídeos técnicos:

Quizá porque, en el fondo, no eran solo música funcional: eran demostraciones de ingenio humano frente a la escasez. Arte nacido de la restricción.

Y tal vez por eso siguen fascinándonos. Porque nos recuerdan que la creatividad no florece cuando todo es posible, sino cuando casi nada lo es. Y digo esto habiendo usado IA en este largo ensayo. Que de otro modo, jamás hubiera escrito. What a time to be alive!

Look ma, I'm using Emacs!

Lately I’ve been testing Emacs. It started as a curiosity: wanting an console environment I can hack in, where the editor becomes more than a text box with plugins. Lisp has been on the back of my mind for a while, and I’ve been comfortable for years with modal editors, shells and tiling window managers. I’m not sure yet whether it will become my daily driver, but it’s definitely a tool I’m enjoying using (although my fingers don’t like it yet).

I didn’t want to fall into the trap of adopting someone else’s megaconfiguration or adding so called “starter kits”. I started small:

  • A plain Emacs setup, only enabling what I needed as I needed it.
  • Org mode, because everyone warns you it’s a rabbit hole, they’re right.
  • Aesthetic tweaks kept to a minimum. I didn’t want the editor to look pretty before I understood how it worked.

From there, I incrementally added layers. The first moment of epiphany? came when I understood the difference between configuring and programming. Configuring Emacs is trivial, or so they say lol. But programming it, bending it to my workflow and absurd ideas like making everything a buffer, that’s where the magic happens.

I’ve been especially interested in using Emacs as a kind of command center: editing files, interacting with terminals, outlining ideas for upcoming projects, and making everything a buffer, because BUFFERS!!!!!!!! HAHAHA.

And of course, I printed this GNU/Emacs Reference Card

A few observations from these experiments:

  • Emacs rewards slow buildup. No big ambitions here, just a few small steps at a time. The moment you try to import a giant config is the moment you stop learning it. I tried spacemacs and in the end I just wanted to build my own config from scratch.
  • Lisp clicks eventually. My background in lots of languages helped, but there was still a threshold moment where Emacs Lisp stopped feeling alien.
  • The editor becomes an environment. Using it to write notes, agenda, todos, browse directories, manage Git, and navigate code from one system has a certain appeal. It is good that also the mouse can be used to navigate when your fingers are tired.
  • Muscle memory fights back. Non-continous periods of heavy use of Vim bindings don’t disappear fast. I’m still evaluating whether I want to go full Evil mode or keep Emacs native. However, tmux muscle memory helps a bit.

None of this is final. I don’t know yet whether Emacs will end up being my daily IDE or a specialized tool for writing, planning and experimentation. But I believe that it has a quality I’ve been missing: it pushes me to think differently about the tools I use and to build systems that match how I think, not the other way around.

The terminal of the future or don't call it a terminal

This HN thread caught my attention: The terminal of the future, and made me think about the concept of a piece of software.

This isn’t the first time I encounter this kind of discussion around the same essential topic: where to draw the line between maintaining a piece of software and pushing new features, versus adding only critical updates because that piece of software is self-contained and complete.

The *nix philosophy made this decision easy: since your goal is just one, you can easily delimit what’s needed and what’s not. Thus, what is not needed is part of another piece of software. Obviously, this is not always the case, and nowadays the industry pushes for a paradigm where constant updates and new features are the justification to keep charging a monthly fee. Not exactly a piece of software anymore, but a product: even absurd pivots, like Spotify going TikTok-like, are becoming more common. Current industry trend is trapped into this loop: a stalled product loses value over time, and the only way to keep it alive is to keep adding new features. That logic is not technical – it’s a business model.

But the terminal? It’s a historical contract between a user and a computer: a basic operating system abstraction. And the ideas behind it are rock solid: they’ve endured the test of time after more than 50 years. It does not need a fancy UI. Yes, it inherits from an old VT100 that does not support many features we take for granted in modern software. But again, the overhead of adding the list of features the author proposes would make it a completely different piece of software. Do not call it a terminal.

Two months into 3D printing

It has been a little over two months since I brought a 3D printer (Creality K1 V2) into the house, and I’m finally starting to understand why so many people describe this hobby as a quiet form of engineering meditation. I had my reservations and doubts about 3D printing, because I’ve experienced it some years ago – the state of the art was far from where it is now. But it has gradually turned into a small lab of experiments, prototypes, failed prints, calibrations, and useful items that now live in different places of the house. And this is my best friend now:

My old caliper

Learning the tools: slicers, settings, and first principles

My first weeks were about selecting the right slicer.

Some offered ultra-detailed control at the cost of complexity. PrusaSlicer is a good example of this. A bit complex for my needs: I installed it at first because I had no idea what I was doing, but I quickly realized I don’t need all that complexity. I finally stick with OrcaSlicer (hat tip to my friend Dugi), because it’s a bit more user-friendly and has a lot of presets for different printers.

Anyways, I had kind of trouble to select the right profile for my printer (looks like there are differences of product naming also between Europe and USA).

Materials: a first taste of the filament world

For now, I’ve stayed in the safe zone with PLA and went a bit further with TPU (which by the way caused my nozzle to clog. I panicked, for a while, but I was able to fix it just tearing apart the plastic tube and bearing it with a pair of pliers).

This guy was extremly useful: https://www.youtube.com/watch?v=weeG9yOp3i4

  • PLA has been my reliable material to print, predictable, I’d dare to say almost boring in the best possible way.

  • TPU pushed my printer a bit more. Flexible filament is a different topic: slower speeds, gentler retraction, a little bit of art. Don’t apply too much temperature to the bed, or the print will be too soft. I use it for the keyboard caps in the LCD prototype (see A prototype with LCD GFX and M5Stack keyboard).

  • I still haven’t tested PETG, but it’s next on my list. I want something stronger and more temperature-resistant for outdoor items and functional prints. PLA is nice until you drop it on the floor.

Glue? No thanks!

For the first weeks, I was applying glue to the bed, as recommended by the notice in the bed. But this is not really needed when you can adjust the bed to the recommended temperature for the filament you’re using. And if it is something small, you can add rafts to the print to help it stick to the bed. I’m not sure why this is not the default behavior.

Glue with hook

Useful things: Building a workspace that works

One of my happiest results so far has been a rack for my electronics-repair tools. It started as a necessity-my screwdrivers, tweezers, and spudgers were spreading across the desk like small metallic weeds.

Rack for electronics-repair tools

I discovered OpenGrid, which is one of the many 3d modular systems out there (e.g. Gridfinity, Multiconnect, and Underware are other examples). It’s a bit more complex than the other systems, but it’s very flexible and can be used to create a lot of different things.

Designing and printing a custom rack forced me to measure, model, and think in three dimensions. The final result is now permanently installed on my bench, a small reminder that 3D printing can be much more than decorative trinkets.

Fun Prints: bringing ideas Into the house

It wasn’t all functional work. The printer also earned me some parental credibility:

  • A few toys for my kids, simple but surprisingly exciting for them.
  • A few little hooks for towels and other small items.
  • More little toys for family and friends.
  • Keyboard fidgets (WASD and arrow keys)
  • A Game Boy cartridge organizer.
  • A Game holder for for hanging into the OpenGrid system.
  • A custom case for my Flipper Zero Dev Board, which finally looks like a proper device instead of wires glued to a PCB.
  • And, for sporadic gaming sessions, a dice tower for Hero Quest, which now stands like a tiny fortress in the middle of the table.

Reflections after two months

What I enjoy the most isn’t the prints themselves, but the loop: idea → model → slice → print → adjust → retry.

There’s a calm rhythm to it. The printer hums for hours, the house feels a bit like a workshop from an older era-mechanical, predictable, purposeful. Something is being built, something is being created.

Next step: PETG, more custom designs, and maybe a bigger project that combines electronics and printed parts? Who knows…

A prototype with LCD GFX and M5Stack keyboard

For the past few weeks, I’ve been working on one of my personal projects: a hybrid of hardware, firmware/software and UI design.A microcontroller-based device inspired by the aesthetic of 1980/90s gadgets.

GitHub repository

It is built using a Raspberry Pi Pico microcontroller paired with a Pimoroni “GFX Pack” display and a small I2C keyboard (CardKB) and programmed in MicroPython.

Prototype early design Prototype early design Prototype early design

The aim is to create a modular, icon-based menu system with multiple “apps” (clock, calendar, memos, todos, games, etc.) and persistent state, in a neat retro form-factor.

I’m still in the early stages of development, but I’m already able to create a simple menu system with a few apps. The 3D design is not yet finalized, but I’m happy with the progress so far. I’m learning Fusion 360 – Tinkercad was great at first, but I think Fusion 360 is a better fit for this kind of project.

A jellyfish

I saw this fascinating animals the other day and I had to take a picture of it.

A jellyfish

Harvest: a simulation game of growth and decay 🌱

Harvest is a compact idle-simulation game that explores the dynamics of growth, resource management, and system equilibrium within a minimal interface. In ohter words: manage a set of plants that need to be watered, tended, and eventually harvested for profit.

Originally implemented in HTML and JavaScript and later prototyped in Rust (lol yes, I know) with an egui graphical front end, it models the life cycle of simple plants that must be watered, tended, and eventually harvested for profit. Despite its simplicity, the game applies fundamental design principles of simulation systems and incremental gameplay.

Harvest screenshot

At its core, Harvest maintains a discrete-time state machine that advances in fixed ticks:

  • Each tick updates plant parameters such as hydration, growth, and risk of infestation.
  • Players intervene by watering, purging, or harvesting, influencing the stochastic outcomes of plant survival and yield.
  • The state evolves deterministically except for random events, pest outbreaks and death, which introduce variability and replayability.
  • Economic elements overlay this biological model: fruits can be sold, upgrades purchased, and automation unlocked, creating feedback loops typical of incremental or “clicker” games. s

The game is available at nowhere because I haven’t released it yet. But I will, soon.

My first open source gem: facturae-rb

I started the project “facturae-rb” a few weeks ago with a very clear motivation: I’ve spent years working with invoices, billing formats, and documentation systems in Rails teams, and I wanted a clean, reusable gem to handle the Spanish Facturae XML format.

Why I started

I saw it as a chance to cleanly apply patterns I’ve been thinking about lately (separation of concerns, repository/finder patterns, clean architecture) but at gem-library scale. It is worth noting that Facturae format will be mandatory for all invoices in Spain from 2026.

How I built it

I kicked off the repo with the usual structure: a facturae.gemspec, lib/, spec/, CI workflows. I set up RuboCop, RSpec, basic CI via GitHub Actions. I committed early a README with “Work in progress” so users know it’s not yet production-hardened. GitHub

Then I defined the domain model:

  • Facturee::Invoice (or similar) as a root object.
  • LineItem, Tax, Party (seller/buyer) classes.
  • A Serializer class (or module) that converts the model into the correct Facturae XML structure.ç
  • A Validator/Schema checker for mandatory fields, versioning of the Facturae spec.
  • A Repository module to persist or load invoices (e.g., from XML, to XML, maybe to DB).

Key technical decisions & trade-offs

I decided not to build heavy UI or CLI on top of the gem yet: keep the scope narrow. That means “just the core library” for now.

I opted for plain Ruby, no Rails dependencies. The gem must work in any Ruby project. That simplifies usage but means I have to implement things (e.g., I/O, file loading) manually rather than using Rails’s ActiveRecord or ActiveModel.

For the XML generation, I evaluated different approaches: builder, Nokogiri::XML, plain string templates. I chose (for flexibility) Nokogiri with builder style, to maintain strong structure and allow easy tweaks. The trade-off is slightly more code than a naive template.

Versioning: Facturae has different versions (3.2.1, 3.3, etc). I added support for version switching via configuration, but not all versions are yet fully implemented. That’s one of the “almost finished” parts.

I designed the gem using a “Context/Configuration” object allowing users to set defaults (seller default data, tax rates, formatting options). This reduces boilerplate in app usage, but adds another layer of abstraction.

I kept the repository pattern in mind: I created modules like Facturae::Repository::XMLLoader and …::XMLWriter. I didn’t go full heavy domain‐driven architecture, but enough to separate concerns.

What remains / “almost done”

Review and implement full support for all fields in the latest Facturae schema (there are many optional fields, some rarely used by typical businesses).

Add more sample XML files to the spec/fixtures/ folder, covering edge cases: e.g., multiple taxes, discounts, expeditions.

Improve error handling: when mandatory fields are missing or invalid, raise meaningful errors; at the moment some errors are generic.

Polish the documentation / API reference: how to plug into a Rails app, how to extend for custom fields, examples of real-world usage.

Consider publishing the gem to RubyGems, with versioning and changelog (I have a CHANGELOG.md but no release yet).

Add optional features like CSV import of line items, or integration with ActiveModel for Rails users.

Reflections from building it

Well, I’m reminded how fun it is to build a “library” for developers. You think about the API, the ergonomics for a person like you, not just the functionality. That differs from building end-user features, and that’s what I enjoy the most.

Writing clear specs early pays off: when I changed the internal model I could rerun tests and be confident I didn’t break the XML output, yay!

Even though this is “just a gem” (maybe not even that much), I treated it like a small product: domain modelling, OOP, versioning, documentation and thinking in long term maintenance.

Kept the surface area small: no rails magic, just plain Ruby; that helps with gem reuse, but some convenience is lost (for example, built‐in validations would have been easy in Rails, but not worth the hassle for a gem).

The hardest part: dealing with the multiplicity of optional fields and the variety of real-world invoicing practices. The modeling is… well, not easy at first. Real World(TM) businesses often have weird combinations of taxes, discounts, shipping, retentions, whatever the Gods of Taxes want them to do. Ensuring the library is flexible but keeps the spec’s integrity is tricky. Also signatures are a bit (no, fucking really) boring to implement.

What’s next (if I ever finish it)

This gem may stay lightweight, or evolve into a richer ecosystem (gem plus CLI plus Rails engine). Either way, finishing this piece now will let me reuse it elsewhere and reduce duplication in future projects.