Creating a Script for a New Game - Jamiras/RATools GitHub Wiki

Prep Work

Open the game in the emulator

This downloads the existing achievements and code notes from the server.

  • For a new game, there probably won't be any existing achievements, but there might be some code notes available.
  • You will probably have added some of your own code notes before you start writing the script, but many can be added while you are writing the script.

Create the script file

  • Select "New Script" from the RATools File menu
  • Enter the Game ID and hit Search
  • Create helper functions for any addresses where code notes were found that you think you might use.
  • Press the Create Button
  • Enter a file name and press Save

Populate the script file

This part of the process varies from developer to developer. You can do one achievement at a time, or attempt to flesh out the entire game. This is just one suggested process:

Note the MD5 you're developing against.

  • I typically do this with a comment just after the header:
// Game Title
// #ID=1234
// md5: abcdef0123456789abcdef - US

Build an outline

Play through the game and outline the achievements.

// ==== Progression ====
//  5 - Complete level 1
//  5 - Complete level 2
// 10 - Complete level 3

// ==== Secrets ====
//  5 - Find the hidden item on level 2

// ==== Challenges ====
// 10 - Defeat the level 1 boss without taking damage

While creating the outline, update the code notes in the emulator and create some helper functions in the script:

function current_level() => byte(0x0407)
function current_hp() => byte(0x0413)

Start building dictionaries for the rich presence script:

levels = {
    1: "Level 1-1",
    2: "Level 1-2",
    ...
}

Write preliminary achievement definitions

After finishing the outline, flesh out the script with code to generate the achievements from the outline. These definitions may be incomplete if enough notes were not gathered on the first playthrough. Just consider them as non-functional and fix them on the next playthrough.

function achievement_complete_level(level, points)
{
    achievement(title = "Level " + level, description = "Complete level " + level, points = points,
                trigger = current_level() == level + 1 && prev(current_level()) == level)
}

achievement_complete_level(1, 5)
achievement_complete_level(2, 5)
achievement_complete_level(3, 10)

If cheat codes exist for the game, consider adding a no_cheating() method to your trigger. You can define this method once and use it in all relevant achievements.

If the game has SRAM, your achievement should contain a prev on the trigger condition. The prev ensures that the achievement won't trigger when loading a save where the requirements had previously been met. You can further save-proof the achievement by limiting where the achievement can trigger. Typically, this is something like "on level 3" or "in dungeon X".

trigger = at_appropriate_place() && trigger_address() == value && prev(trigger_address() != value)

Define the rich presence

Your script should also include a rich presence definition. At this point, you should have a good idea what you want in the rich presence. Don't worry if you didn't collect everything necessary in the first playthrough. Just consider it incomplete and implement what you have:

rich_presence_display("{0}, {1} lives",
    rich_presence_lookup("Level", current_level(), levels),
    rich_presence_value("Lives", current_lives())
)

Deploy the results

Copy the achievements to Local using the Update Local right+click menu item for each achievement, or using the Update Local menu item to deploy multiple achievements at the same time.

NOTE: the local rich presence will be overwritten any time you reload the ROM. When testing rich presence, you may have to switch back to RATools and Update Local to reapply the test script.

Alpha playthough

Play through the game, testing and fleshing out each achievement in the outline. This is also a good time to capture any in-game art that you might want to use for achievement badges.

  • Load the achievements into the emulator. Depending on your toolkit version, you could use the Refresh from Disk button or reload the game from the Recent menu.
  • Activate them.

As you approach an achievement, create a Save State.

  • If the achievement doesn't trigger properly, update the script, recompile, update local, refresh the emulator, load the Save State, reactivate the achievement, and reattempt it. Repeat until the achievement does trigger properly.
  • If the achievement triggers when a value changes to 0 or 255 (boss achievements usually have this), then you should try resetting the game while the achievement is in progress. Resetting sometimes zeroes out memory values. Fix and retry if necessary.

After passing an achievement, you should reactivate it in case it might be triggered incorrectly at a later point. This is particularly important in games where the stages may be non-linear or accessed via a password or cheat code.

Periodically check the Rich Presence value using the Parse Rich Presence menu option. This loads the file from disk each time you do it, so you can make changes in RATools, Update Local, and immediately Parse Rich Presence again. If you leave the Rich Presence Monitor open, it will automatically detect changes to the file and reload.

Perform sanity checks

Once all the achievements appear to be functioning normally by themselves, you should look for common problems:

  • Load the game and hold down the frameskip button until you've skipped through any demos or tutorials. Fix any achievements that trigger.
  • Reset the game. Fix any achievements that trigger.
  • Check for 'triggers on startup' achievements. Depending on the emulator, you'll want to pause the emulator before loading/reloading the ROM, or pause it ASAP once the ROM has loaded (sometimes this can be achieved simply by clicking on the achievement list, which causes the main window to lose focus). Then activate all achievements and unpause the emulator. Fix any achievements that trigger.

Adjust the achievement points

Each achievement's points should be based on required effort or difficulty of the achievement.

  • Required effort includes everything leading up to the achievement. For games with passwords or cheat codes, this metric should start from the password point. For games without passwords, consider the distance from starting the game. to reach a target total number of points.
  • Difficulty is subjective. It's easiest to categorize difficulty compared to other achievements.

Upload badges for each achievement

  • Badges should have the same width and height, but can be any size. The server will scale them to 32x32, 64x64, and 128x128.
  • Badges must be attached using the emulator. After attaching badges, save in the emulator, then refresh the script to pick up the badges so they aren't lost when using Update Local later.

Beta playthrough

Play through the game again. Achievements are expected to be functional, but may still have some issues. Save States are still recommended in case any issues are found. If issues are found, correct and retest just like before. Depending on the number and complexity of fixes made at this time, you may want to play through the game again.

Publishing the achievements

Once you feel the achievements are functional and correct, you can upload them to the server.

Promote to Unofficial

Achievements must be promoted to Unofficial using the emulator.

  • Unofficial achievements can be earned by users by selecting the Unofficial set from within the emulator. They give points to the user, but don't actually appear on the game page or under the recently played game in the user's profile.
  • After this point, to make further modifications to the achievements from RATools, you have to set the id=XXXXX parameter in the achievement call so it can associate the locally modified achievement to the published one.

Play through the game again

Play using the Unofficial achievements with Hardcore mode on.

  • Hopefully, no further issues are found. But if they are, fix the achievement in the script, recompile it, and manually update the Unofficial achievement.

Promote to Core

When you're sure your game is ready, promote it to Core so people can officially earn the achievements.

Announce changes

Post to the official forum thread indicating that the set is ready for public consumption. Also post in the #achievement-news channel in discord.