u/wavestation3109

Interactive music engine plugin for AGS

Interactive music engine plugin for AGS

Hey everyone, I built an interactive music engine inspired by LucasArts' iMUSE, and it's actually fully compatible with iMUSE MIDI data. Just a heads-up: while it's still in active development and technically a beta, this first build is already highly usable. I wanted to share the main features of the AGS plugin (agsimwrap) I've been working on.

1. The Runtime Plugin (agsimwrap-x32.dll)

Core Engine & Drivers

  • It includes a full reimplementation of the LucasArts iMUSE v6 system.
  • Audio rendering is multithreaded using miniaudio, so the callback handles the music timeline and sample mixing completely in the background.
  • Included drivers: FluidSynth for software General MIDI (via .sf2 files), standalone AdLib/FM OPL3 emulation (no extra hardware needed), and direct hardware output for both GM and Roland MT-32.
  • For the MT-32, it handles native timbre mapping and even lets you set a custom welcome message (up to 20 characters).

Loading & Playback Control

  • You can load .ims banks (iMWrap_LoadBank) either as loose files or directly from AGS-packaged assets (requires AGS 3.6.0+). If FluidSynth can't stream packed SoundFonts directly, the plugin automatically extracts them to a temp file.
  • Full control over your sounds: you can start/stop them by ID, query their status (active, scheduled, etc.), and count what's currently playing.
  • You get granular mixing controls: master volume, per-sound tweaks (volume, pan, relative/absolute transpose, speed, priority), and you can toggle volume on specific MIDI channels.

Interactive Flow & Callbacks

  • Flow control: You can instantly jump to a specific measure/tick, fast-forward through events without playing notes (scan), define dynamic loop regions, or set up smooth volume fades.
  • Hooks: You can schedule interactive branching by hook class, value, and MIDI channel (iMWrap_SetHook).
  • Syncing: The engine calls iMWrap_OnTrigger(soundId, markerId) in the AGS Global Script whenever a MIDI marker is hit. This is super useful for syncing music with game animations.

Setup & Extras

  • Players can configure things outside the game using SetMIDI.exe, a native Win32 GUI tool I included (no Qt dependency). It auto-detects the game executable and lets them pick their driver and MIDI device. It also supports .imc config files.
  • Includes compatibility profiles (generic iMUSE v6 standard and a specific Sam & Max Hit the Road profile).
  • Optional debug logging to console and imwrap_debug.log.

2. The Editor Plugin (AGS.Plugin.IMWrap.Editor.dll)

I also made a plugin for the AGS editor to manage everything easily (targets .NET 4.8, so it's fully AGS 3.6.2 compatible).

  • It adds an iMWrap menu and a "Banks" node in the project tree that automatically discovers all your .ims files.
  • Opening a bank gives you a dedicated tab where you can inspect the list of sounds, their MIDI tracks, and control events per track.
  • You can manage (create, rename, delete) your .ims banks right from the project tree.
  • Under the hood, it uses a native shim bridge (imwrap_shim.dll + IMWrapShim.cs) to call into the core C++ engine directly from the C# editor context.

You'll find the GitHub repo right there...

... and here is a PoC video to watch it in action : https://www.youtube.com/watch?v=yl-vt7jXKYI

Let me know if you have any questions or feedback!

https://preview.redd.it/u5mso3m842ah1.png?width=1920&format=png&auto=webp&s=91d3db1c87d02459744314c5de2512ea1ef135d9

reddit.com
u/wavestation3109 — 8 days ago