Categories
Week 2

Week 2: Supernova & Voyeur

This week, I continued working on implementing keymapper for more game engines. The highlight was getting my SLUDGE keymapper PR merged, and diving into two new engines: Supernova and Voyeur.


Supernova Engine: The Challenge of Custom Actions

The Supernova engine powers the Mission Supernova series—old-school point-and-click adventures that are surprisingly engaging (and tough!). To test my changes, I had to play through parts of the game, and I genuinely enjoyed the puzzles and storytelling, despite the lack of modern visuals. Honestly, without the walkthrough, I would’ve spent more time solving puzzles than coding the keymapper.

Unlike SLUDGE, this engine uses engine-driven input handling, which gave me the flexibility to define custom actions instead of just simulating keypresses. Why is this better? Because:

Custom actions give the engine full control over what happens when a key is pressed, while mimicking keypresses can cause issues like duplicate handling or unexpected default behavior still triggering.

The biggest challenge I faced in Supernova was how the engine handled keyboard input. It stored the raw keycode of every key press in a single variable called _key, which was then used for both gameplay actions and full-text input.

This became a problem when introducing custom actions. Unlike raw keycodes, custom actions are more abstract—they represent “what to do” rather than “what key was pressed.” But if I allowed both to be handled the same way, the engine might mistakenly store a custom action as if it were a real keypress, which would break things like text input.

The Solution

I separated the handling of keycodes and actions using two variables:

  • _key → stores the raw keycode (used only when text input is needed)

  • _action → stores the custom action (used during normal gameplay)

Then, I made sure the engine would:

  • Disable the keymapper when full keyboard input was required (e.g., entering text). This way, real keypresses would go through, and _key would be filled correctly.

  • Enable the keymapper during gameplay. In this mode, keypresses would be intercepted, converted into actions, and stored in _action.

This setup allowed me to cleanly separate when to use keycodes and when to use actions, without breaking any existing input logic. Once this system was in place, replacing the original key handling with action-based logic was pretty straightforward. All I had to do was replace hardcoded keycodes with custom actions.


Voyeur Engine: Simple, Then Smarter

Compared to Supernova, Voyeur was a breeze. The game is almost entirely mouse-driven, with very little keyboard interaction. I initially thought I could get away with two simple binds—left and right click—and be done in a few hours.

But… why stop there?

I decided to improve it by breaking the keymap into multiple context-specific keymaps, depending on where the player is in the game. For example, different menus or in-game sequences would have their own set of keybinds with clearer action labels.

The tricky part was figuring out where in the code to enable/disable each keymap. That took a whole day of reading through the engine, but once I nailed it, the final implementation was clean and intuitive.


Wrap-Up

This week, I:

  • Got my SLUDGE keymapper PR merged 🎉

  • Implemented full keymapper support for Supernova (with custom actions)

  • Added smarter, context-aware keymapping to Voyeur

Next week, I plan to continue this momentum and bring keymapper support to more engines. The work is getting smoother now that I’m more familiar with ScummVM’s input systems—and every engine brings a new twist to solve.

Categories
Week 1

Week 1: Diving into SLUDGE Engine

This week marked the beginning of my journey with ScummVM for Google Summer of Code, and I kicked things off by working on the SLUDGE engine.

For those unfamiliar, SLUDGE is an engine that enables developers to create and publish their own point-and-click adventure games. These games are highly script-driven, especially in how they handle input. Keyboard input, in particular, is passed directly to the script, and from there, it’s entirely up to the game developers to define how those inputs are interpreted and used in their game logic.

My main goal for the week was to implement ScummVM’s keymapper support in the SLUDGE engine. However, this came with its own set of challenges.

Each SLUDGE-based game defines its own key bindings for different actions. That meant I had to manually identify the default controls for over 10 supported games. This process was quite time-consuming, as there was no centralized documentation. In some cases, I found the information in the game’s source code, in others through manuals, and occasionally I had to just play through the game and note what each key did.

While this part of the task was tedious, it was relatively straightforward. The real challenge came when I had to figure out when to disable the keymapper.

Why? Because some games allow players to enter custom save file names, which means they need unrestricted keyboard input. If the keymapper remained active during such input modes, it would interfere with typing. Unlike many other engines, SLUDGE doesn’t offer a built-in pause menu or modal state, so each developer handled menus differently.

After some digging through the engine source and various game scripts, I discovered two important functions: `freeze()` and `unfreeze()`. These were used every time a menu was shown or hidden. While not all menus required full keyboard input (most only needed mouse interaction), this discovery gave me a reliable enough hook. I could safely disable the keymapper when a menu was active and re-enable it when gameplay resumed.

With that, I successfully implemented keymapper support for the SLUDGE engine in ScummVM!

Categories
Week 0

Introduction

Hi everyone! I’m Prime, a third-year computer science student and lifelong gamer. This summer, I’ll be working with ScummVM as part of Google Summer of Code 2025.

My project, “Add Keymapper to More Games,” focuses on integrating ScummVM’s keymapper system into more of its supported game engines. This will allow players to customize controls across a wide range of classic games — making gameplay smoother and more accessible on different input devices like keyboards and gamepads.

Over the summer, I plan to add keymapper support to over 20 engines. For each engine, I’ll analyze its input system, replace hardcoded key handling with keymapper logic, and thoroughly test the changes to ensure everything works as expected.

A huge thank you to my mentors, the ScummVM community, and the GSoC organizers. I’m looking forward to contributing to the preservation and improvement of these classic games!