Forgot password?
login to retroachievements.org:
User: 
Pass: 

** Achievement Creation **

Page: 1 2 3 4 5 >
AuthorMessage

Scott
Posted: 20 Apr, 2013 11:54
Last Edit: 11 Apr, 2015 18:20
Welcome to the world of Achievement Creation! Ensure you have retroachievements.org/download.php first and retroachievements.org/createaccount.php so you can log in using the emulator.

I'll be using RAGens to demonstrate, and the game Sonic the Hedgehog. You can use whatever you like, but I'll refer to RAGens as the emulator I'm using; the same applies for the other emulators.

To begin, run the RAGens executable, and login when prompted. If you have any issues logging in, please send me a message on these forums and I'll get back to you ASAP. Next, use File..Open and select whatever ROM you would like to find achievements for.

You should now have your main window running Sonic. There are 3 other dialogs we'll be using, which can be found under RetroAchievements in the menu. We'll be dealing with the Memory Inspector first:



The Memory Inspector can be used to find addresses in RAM for us to use. Essentially you are on a treasure hunt for memory locations - this dialog will help you examine and filter the game's RAM while the game is running. To start or restart a test, click 'New 8-bit Test' near the top middle.

To keep things simple, we'll start by looking for the memory address which holds the number of rings we have collected. Our steps will be the following:

1. Load the ROM and start a new game.

2. Reset the memory dialog: click 'New 8-bit Test'.

3. Return to the game and change the number of rings in memory. For example, collect a ring.

4. In the memory dialog, we now want to filter for values that are 'greater than previous values' (symbol '>'). We select this, then hit Filter.

Each time you perform 3 then 4, the number of possibilities or 'candidates' will get smaller. We will continue doing this until the number of candidates reaches a very small number (as few as possible), it might take 4-5 attempts. Next we can click in the results window, and monitor the memory address in the memory viewer at the bottom. Continue using the game and you should see the values in memory change as you collect rings. If you don't, or if something doesn't look right, try another value. With the first Sonic the Hedgehog, the memory address for the number of rings should be 0xfe20.

Note: Using save states (F5 to save state, F8 to load state, F6-F7 to toggle which state to use), you can switch back and forth between different states allowing you to alter what is in RAM, and use this to filter out bad candidates. You can search for values that remain the same (I.e. If you know the value didn't change, use '='), or values that are different (use 'not equal', symbol '!=').

Note: There's unfortunately no guarantee from game to game on how the developers have stored their data (4-bit, 8-bit, 16-bit, binary-coded decimals, negative/inverted, i.e. using 0xff/0xffff to represent 'set', or plain randomly), but eventually you should come across some good address. Note if you are struggling to find good values, post in these forums, or see the note at the end of this post. There are plenty of people who will be very happy to help!!

Tip: if you'd like to experiment with memory, try entering new values directly into the RAM viewer. This can have devastating effects on the game, or it might do exactly what you expect, (or nothing at all!) It can be useful though, to see if you can enter a value and get the result you expect. Use with caution!

When you've found an address you're happy with, you can write a short note for what it is and hit 'Save Note', this will store it on database, and will be automatically restored next time you load up the memory viewer for this game, wherever you are! Edit: now after clicking 'Save Note', the note will be automatically stored on the database, and shared so all developers will share access to these memory notes. They will all be downloaded afresh when you load a ROM. If you try to overwrite a note, it will check with you first before submitting.

OK so the memory location for the number of rings is stored at 0xfe20 (note to a non-programmer, we're dealing in hexadecimal which can be daunting, but don't worry, essentially its just letters instead of numbers), and not forgetting '0x' at the start to show that it's a memory location in hex. We've found an address we're interested in and stored it using Save Note. We now want to create a new achievement. We will now move to the Achievement Set dialog:



Here we group all the achievements we know about into three sets:
1. Core Achievements (the main, public Achievement set),
2. Unofficial/User Achievements (public, but will not award you points: for peer review),
3. Local Achievements (personal to your PC).

In the Achievements dialog, click 'Local Achievements' (top left), then 'Add New Achievement' (bottom left). This will add a blank entry to the list in the centre. Double click on it: if it's not already open, this should select it and open the Achievement Editor dialog.



This is the final dialog where we bring all the data together. Most of the top fields are self explanatory, I.e. Title, Description, Points. The main one is the 'Requirements' part.

Lets say we want to add an achievement for collecting a certain number of rings. Lets say 15 rings for simplicity. After filling out the fields at the top and selecting a suitable icon (you can upload a new one, I'll just select the gold trophy badge (00136) for now), we need to fill out Requirements. I have one requirement, that the number of rings is at least 15. Next click is 'Add New Requirement'.

Clicking this button will add several default values to the Requirements list. These defaults just ensure that something relatively sensible is added to the list. For now, ignoring the field 'Special?', what this says is, 'please check that this value of memory is equal to the value 10.' (10 is just a default value). When we clicked create, the default memory value will be whatever value you last left in the memory dialog.

Next we will change these values to the following:

* Size: 16-bit
* Memory: 0xfe20
* Cmp: '>=' - this is the comparison to make. We could have any comparison here, but it's sensible to have 'greater than or equal to'. This is important because if we get 10 rings then a super ring box to have 20, we would miss out having 'exactly' 15 rings.
* Type: 'Value' - we're comparing this memory value to a fixed value: 15
* Size: 'Empty' - this is only relevant when comparing memory to memory
* Mem/Val: 15 - the number of rings required: the value we are comparing the memory to
* Hit Count: 0 - ignore this for now, its useful for when something needs to happen a certain number of times

With that set, we don't have any more conditions to add, so we return to the Achievements Dialog. To be safe, we should save our progress by hitting 'Save Local'! This saves everything to file locally to ensure that we won't lose any progress. We can now 'activate' this achievement locally by hitting 'Activate' on the right-hand side. This will start monitoring these memory locations and will award the achievement once all the conditions are true. Now we can go ahead and test to see if this achievement works!



If we press ESCAPE in-game, you will see the achievement show up as a demonstration of what it would look like in the in-game overlay!



Once we have tested that the achievement works locally, there is a two-step commit process that's (mostly) pain-free! First in the Achievements Dialog, we select our achievement and press 'Commit Selected', and agree to the dialog. This will push our achievement to the server and store it under 'Unofficial User-submitted Achievements'. Note that our achievement still exists in this dialog, it's just moved to a different tab.

Note: (The idea of this middle-part is that it would be a holding ground where users can vote on the best achievements before they get pushed to the 'Core Achievement' set. At the moment anyone can simply promote an achievement to the core set, but in the future this might be an super-user privilege (in case of spam/abuse etc).)

Finally, to push our achievement to the Core Achievement set, and allow everybody to download achievements, we select 'Unofficial User-submitted Achievements' at the top left of this dialog, select our achievement, then click 'Promote to Core', and accept the dialog. And viola! You have just submitted your first achievement!

Naturally, it's best only to submit achievements that are unique and interesting into the Core Achievements group. If there are duplicates in the Core group, the most recently added duplicates will be manually moderated and deleted. If you don't want your achievement in the Core group, or you think it might not be appropriate for the Core group (i.e. if it's incomplete, or if sometimes it appears to trigger when it's not supposed to, like when the game is showing a demo), leave it in the Unofficial/User Submitted section.


Extra Note: when finding addresses, there is potentially a bit of a shortcut. PAR files can come in very useful, see bsfree.shadowflareindustries.com/?s=11&d=5 for examples of PAR codes. PAR codes are commonly used to force an address in RAM to stay a certain value. The addresses are easily decoded: if it begins 'ff', that means 'keep a value stuck in this address'. The next four digits are the address, and after the colon is the value that should be used. For example:

FFFE20:00C8

This code is for Sonic 1, and the Action Replay would ensure that the value 00c8 is stuck in the address 0xfe20. This causes sonic to permanently have (hex)c8 rings, which is 200.

Note that it is only Action Replay (PAR) codes that will be useful to get addresses for use with RetroAchievements: Game Genie codes modify ROM rather than RAM and aren't what we're looking for.

thonay
Posted: 01 May, 2013 00:15
yeah, i know this thread shouldn't have other stuff aside tutorial, i can read that, but after my questions you can delete this post.

When you answer my ideas you say "this can be implemented" or things like that, ok. For those like me that give only ideas but don't wanna or are lazy to actually create the code lines and give birth the achievements, tell me, what kind of achievements are possible or things that you can't do at all ???

It's possible...?

- block passwords to make ppl play the game in a single playthrough
- block emulator's save states to make ppl play the game in a single playthrough
- calculated the time spent playing in a hole (al the time spent in the game even if you close and reopen the emulator)
- calculate time without die or any "condition" + "time" to fulfil
- cumulated stuff, i.e. pass 1000 times at a soccer game, can be done in many game sessions (turn off emulator and reopen later - without using save states to restore the previous session) or it wil reset counting
- forbid player to change char until the finish of the game, i.e. Beat MK1 with Scorpion don't changing char at continue.
- force players to have coop since beginning of the game instead of player 2 press start just in the final boss for the achievement.

so, all this kind of stuff, what can ppl with ideas do and what it's impossible to make the code?

Scott
Posted: 01 May, 2013 00:44
Hey ! Glad you asked, and I think these are some very important and relevant questions. OK:

- block passwords to make ppl play the game in a single playthrough
- cumulated stuff, i.e. pass 1000 times at a soccer game, can be done in many game sessions (turn off emulator and reopen later - without using save states to restore the previous session) or it wil reset counting
- forbid player to change char until the finish of the game, i.e. Beat MK1 with Scorpion don't changing char at continue
- calculate time without die or any "condition" + "time" to fulfil
- force players to have coop since beginning of the game instead of player 2 press start just in the final boss for the achievement

All of the above can be achieved using the tools as they stand, and some state-logic when making the achievement. It's tricky, but I'll try and explain how briefly, and add a proper tutorial for this tomorrow as it really does need explaining: every achievement condition can have hit counts, meaning that the memory has to equal this value for a certain number of times. There's a Super Hang On Achievement where the speed of the bike has to be over a certain value for 10 seconds. What I do is check that the speed is over the required value, and I set the hit count to be 600. The Genesis will produce 60 frames every second, and after 10 seconds or 600 counts of this being true, the achievement will unlock. To add to this, there is a 'reset if' condition. This basically says if the speed drops below the specified value, reset all the hit counts and achieved conditions. All of these checks happen once every frame, but they are so trivial they don't make an impact on the game.

To extend on this example, I'll examine in Castlevania Bloodlines. This achievement has various conditions; the first condition is that the current level is equal to 2 (0xfb2c=2). However it is possible for the player to put in a password and reach level 2 instantly! Now to combat this, we have another three checks, all of them on the same memory variable, the one that controls the screen 'mode' (0x9002). This value tells us what screen the player is on, from title screen, ingame, pause, password entry screen etc. Firstly, we have a 'one-hit' check that the player enters the title screen (0x9002=4). This means, as soon as this is true, it stays true, which acts as a 'gate' for the player to have to have gone through. We also have a reset condition on (0x9002=7). This means that if the player enters the password screen, reset all the conditions. If the player THEN goes onto play the game, the current level will be equal to 2. HOWEVER! As the 'was at main menu' condition hasn't been hit or isn't true, the player won't be awarded the achievement. The only way to enable this would be to reset the game, or die and go to the 'sega' logo. If the player does this, there is another reset condition on the sega logo (0x9002=1) to stop him from getting the achievement that way. From all these, we force the player to have hit the title screen once, then progress into game, reaching the achievement how he is supposed to.

You may have noticed that all achievement progress is saved along with the save states (don't worry if you haven't noticed, that means it's working! :P) in a secure hash along with your existing save state. This means that using save states won't mess up your achievements, and you can't use save states to force an achievement to unlock.

To very quickly touch on another point you made, the 'number of passes ever' could be done using a 'delta' value. Under 'Type' in the achievement editor, there are the options Mem, Value or Delta. Delta represents the 'last known previous value' at this address. If the number of passes is stored somewhere as a variable, lets say in memory location (0x1234), we can use a single condition to check this: Mem 0x1234 > Delta 0x1234, Hit Count: 1000. Now what this means is, every time the value at memory 0x1234 is greater than the value it was previously, it will hit the hit counter. If the memory becomes smaller, nothing will change (i.e. start a new game), and the hit count will remain where it was. Note what I said earlier, if the player loads a save state, the achievement progress will be restored too, so this will only persist across exactly one session.

To pick up things like 'time' or 'time since', currently the only support is to examine if the data is present in RAM, and use that. However support for other variables is something I'm interested in as well, and is likely to make an appearance at some point.

- block emulator's save states to make ppl play the game in a single playthrough

Ah. This one hasn't been addressed (but I'm not denying it might be possible one day?) - I made a decision a while ago to allow and support save states, but there is the possibility this could be a 'special' option that could be enabled for an achievement, but this is a wish list item at the moment.

- calculated the time spent playing in a hole (al the time spent in the game even if you close and reopen the emulator)

This one I'd like to address along with the previous one - I'm interested in watching a few other variables here as well, including number of button presses, time since boot, number of save states loaded/saved since boot,

Hopefully this makes some sense, I'm off to bed as I'm exhausted. I'll try and rewrite some of this so it makes more sense and put it in a tutorial tomorrow. Thanks Thonay for the questions, hopefully these were the answers you were looking for? :P

thonay
Posted: 01 May, 2013 19:22
It makes sense for me, even considering my lack of coding skills, but at least i know that i can add more variety to my ideas and without ppl who code become "tool-less" to acomplish my idea.

Pereira006
Posted: 07 May, 2013 03:23
Hi! I have question
I did my own achievement game called " Alisia Dragoon " in Mega drive, When i did my owm achievement after test and work but I wanna update my achievement how ? I wanna people to play and funny catch my achievement.
so my question is how update achievement ?

Sorry my bad english

Pereira006
Posted: 07 May, 2013 06:41
Never mind I did now lol, thank tutorial :)

jackolantern
Posted: 01 Jul, 2013 10:16
Is the Hit Count the best place to add repeaters i.e. to hit a certain number 10 times or is there a better way to do this? I have seen the mini Delta tutorial above but not too sure how that works.

I've noticed the value for hit count is 0 however when something is triggered it goes up. Do I need to set a hit counter to be 1 below the eventual bracket number? i.e. If I want a certain number hit 10 times would the number be set to 9 so when the bracket hits 10 it will activate?

Would a Delta value be better?

I'm asking as trying to add a finish line achievement in Mario World To pass 10 times at a certain number. I've got a single one working but not too sure for multiples.

Thanks.

Scott
Posted: 01 Jul, 2013 21:48
Hey jacko, don't worry I haven't forgotten about you - the hit counts work really well when you combine them with delta values, but there's a trick to them. I'll put together a document for you now and link to it in a moment, hold on...

Scott
Posted: 01 Jul, 2013 22:34
Posted: retroachievements.org/viewtopic.php?t=182 - let me know what you think, jackolantern :)

jackolantern
Posted: 01 Jul, 2013 23:46
Cheers for that, Made things clearer, I think I was making it too complicated.

Cinos58
Posted: 08 Jul, 2013 06:07
hi i'm new and i added teenage mutant ninja turtles tournament fighters, but i can't add
achivements, the dialogs just freeze the emulator and when i minimize the window, and
maximize it back and try again it does nothin, what can i do bout it?

Wolferhu
Posted: 08 Jul, 2013 06:12
Hi:)

I think there's something server problem now and there're different issues around the achievements upload.
Hopefully it'll be solved soon.

(By the way if your achievements're already in the "Unofficial User Submitted Achievements" list then they're already in the system,and if the server issue'll be solved you can promote them to core achievements).

Wolferhu
Posted: 08 Jul, 2013 06:22
Hmm..or do you mean the editor's not working at all?
Try to minimize the window firstly then just open the editor after that.

Cinos58
Posted: 08 Jul, 2013 06:44
i just now tried that it still wouldn't load the dialog, also when i added the ninja turtles tournament fighters i accedently
typed nina turtles because when i hit j they must have been some kinda crumb under it and it didn't actually type the j,
so here on this website is there a way to fix the miss spelling?

Cinos58
Posted: 08 Jul, 2013 06:47
oh and before i forget, i really just want to make achivements locally just for me.
Page: 1 2 3 4 5 >

login

login to retroachievements.org:
User: 
Pass: 
or create a new account