Mods / Achievements
Author: Nateonus
Side: Both
Created: Dec 20th 2023 at 1:15 PM
Last modified: Mar 22nd at 10:25 PM
Downloads: 3872
Follow Unfollow 96
Latest file for Various v1.19.x:
natsachievements_1.1.0.zip
1-click install
You guessed it - This mod adds achievements. Currently comes with 16 achievements, and contains a super easy API for other modders to add achievements!
Achievements work on singleplayer and multiplayer! If used on a server, unlocking an achievement will be broadcast to all players, if the server's modconfig allows it.
Other mod developers should check out the Api Details section below. You can add achievements for this mod without requiring a dependency!
Press 'L' (configurable) to open your Achievements Journal.
If you wish to support my work, please consider donating a small amount at https://ko-fi.com/nateonus!
The achievements mod can be added to existing worlds without issue.
The following mods support achievements:
Want your mod listed here? Use the achievements mod API and leave a comment!
The achievements API consists of a single .cs class that can be used to register, unlock, and check achievements.
The great thing about this is that it requires no dependencies on your part. If the user has the achievements mod installed and enabled, your newly added achievements will work. If the user does not have the achievements mod installed and enabled, your newly achievements will just silently not do anything. Error free, and easy to manage.
Step by step instructions:
- Create a new .cs class file, named "AchievementsManager".
- Replace your new file with the entire contents of the script below.
- Achievements should be registered on both sides - So call RegisterAchievement as many times as needed in your mod system's Start function.
- The achievementId should be unique across all mods - It is recommended to use something that is tied to your mod name to ensure it is unique, otherwise it will not be correctly registered.
- The achievementGraphicCode is a full item or block code. e.g. "gear-rusty" or "clay-fire".
- To finish setting up your achievement, add the following entries to your .lang file:
- "achievement-{achievementId}": "{Achievement name}"
- "achievement-{achievementId}-desc": "{Achievement description}"
- (Optional!) "achievement-{achievementId}-desc-undiscovered" : "{Achievement description when not unlocked}"
- Achievements can be unlocked or checked on either client side or server side.
- Achievements should not be checked before they are unlocked - The unlock function already does this. If the achievement has already been unlocked, nothing happens.
- The given script contains no error checking for an invalid achievement id. It is up to you to keep these ids in a static place.
- If your achievement appears in the Achievements Journal (L) (Requires Achievements mod installed), you have successfully created an achievement.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Vintagestory.API.Common;
namespace Achievements
{
internal class AchievementsManager
{
static Assembly cachedAchievementsAssembly = null;
static MethodInfo registerAchievementMethod = null;
static MethodInfo unlockAchievementMethod = null;
static MethodInfo isAchievementUnlockedMethod = null;
public static void RegisterAchievement(string modId, string achievementId, string achievementGraphicCode)
{
if (registerAchievementMethod == null)
{
Assembly a = GetAchievementsAssembly();
if (a == null) return;
Type t = a.GetType("Achievements.AchievementsApi");
registerAchievementMethod = t.GetMethod("RegisterAchievement");
}
registerAchievementMethod.Invoke(null, new object[] { modId, achievementId, achievementGraphicCode });
}
public static void UnlockAchievementForPlayer(string achievementId, EntityPlayer player)
{
if (unlockAchievementMethod == null)
{
Assembly a = GetAchievementsAssembly();
if (a == null) return;
Type t = a.GetType("Achievements.AchievementsApi");
unlockAchievementMethod = t.GetMethod("UnlockAchievementForPlayer");
}
unlockAchievementMethod.Invoke(null, new object[] { achievementId, player });
}
public static bool IsAchievementUnlockedForPlayer(string achievementId, EntityPlayer player, bool defaultIfNotInstalled = false)
{
if (isAchievementUnlockedMethod == null)
{
Assembly a = GetAchievementsAssembly();
if (a == null) return defaultIfNotInstalled;
Type t = a.GetType("Achievements.AchievementsApi");
isAchievementUnlockedMethod = t.GetMethod("IsAchievementUnlockedForPlayer");
}
return (bool)isAchievementUnlockedMethod.Invoke(null, new object[] { achievementId, player });
}
static Assembly GetAchievementsAssembly()
{
if (cachedAchievementsAssembly != null) return cachedAchievementsAssembly;
AppDomain cDomain = AppDomain.CurrentDomain;
Assembly[] assemblies = cDomain.GetAssemblies();
foreach (Assembly a in assemblies)
{
if (a.GetName().Name == "natsachievements")
{
cachedAchievementsAssembly = a;
return cachedAchievementsAssembly;
}
}
return null;
}
}
}
JSON Achievements are pretty simple to add! The mod comes with a few standard json achievements for you to take a look at.
Achievement files must be added to an "achievements" folder, in the same location as the "blocktypes", "itemtypes", "recipes", etc. folders.
In the "achievements" folder, create a new json file. This file can have any name, and you can store any number of achievements within one file.
The general syntax of an achievement file is:
[
{
"enabled": "true",
"id": "eatcheese",
"graphicCode": "cheese-waxedcheddar-4slice",
"criteriaType": "EatAny",
"criteriaData": [
"game:cheese-*"
]
},
{
"enabled": "true",
"id": "killtwoheadeddrifter",
"graphicCode": "creature-drifter-double-headed",
"criteriaType": "KillAnyEntity",
"criteriaData": [
"drifter-double-headed"
]
}
]
- Enabled - Whether to load this achievement.
- id - A unique (currently for all mods) identifier for your mod. Used throughout .lang files as well.
- graphicCode - The block/item code that will show when the achievement is unlocked.
- criteriaType - The type of trigger for this achievement. The available triggers are currently:
- CreateAnyFromGridRecipe
- HaveAnyInInventory
- HaveAllInInventory
- KillAnyEntity
- EatAny
- DestroyAnyBlock
- PlaceAnyBlock
- criteriaData - An array of asset locations - including wildcards that are used as data for the criteria.
- For example, when using CreateAnyFromGridRecipe, if ANY of the blocks or items in criteriaData are crafted in the grid, the player will unlock the achievement.
- All criteria types can use one or more asset locations for their criteria data.
- Note that HaveAllInInventory will not unlock the achievement until all the asset locations are satisfied.
- orderInList - An optional parameter that controls how achievements are listed in the achievement journal. Achievements are sorted based on lowest to highest from this value. Default is 1000.
When achievements have been added, you will need to register a few properties in your lang file.
"achtabname": "Nat's Achievements",
"achievement-eatcheese": "Lovely cheese, Gromit!",
"achievement-eatcheese-desc": "Eat a slice of cheese.",
- achtabname - The name of the tab in the achievement log. This will usually just your mod name.
- achievement-{achievementID} - The name of your achievement.
- achievement-{achievementID}-desc - The description of your achievement.
- (optional) achievement-{achievementID}-desc-undiscovered - The description of your achievement when it has not yet been unlocked.
And you have registered your very own achievements! Open the achievement log and you should see your mod's tab containing your new achievements! Put a comment on what mod you used achievements in, and it'll be advertised on this page!
Version | For Game version | Downloads | Release date | Changelog | Download | 1-click mod install* |
---|---|---|---|---|---|---|
v1.1.0 | 2499 | Mar 22nd at 10:25 PM | Show | natsachievements_1.1.0.zip | Install now | |
v1.0.2 | 284 | Mar 13th at 6:02 PM | Show | natsachievements_v1.0.2.zip | Install now | |
v1.0.1 | 369 | Feb 21st at 5:12 PM | Show | natsachievements_v1.0.1.zip | Install now | |
v1.0.0 | 674 | Dec 20th 2023 at 4:17 PM | Show | natsachievements_v1.0.0.zip | Install now |
Nateonus
Hey o/ van you please add Czech translation (cs) ?
Stumbled across some (minor) issues:
(Not an issue but a reminder that my translation is still available. 🙂)
Love this mod... Just what the game needed. where do i put the AchievementsManager.cs file to register achievements for my server? was able to create achievements for myself but not other users
Hi, i translated the mod into german.
de.json
Nateonus
hey can you add that translate I mentoned down bellow please?
Hey o/ Nateonus can you please consider update with my translate to the Czech language? Thank you !
cs.json
An amazing mod! I had been wondering why there were no achievements in Vintage Story, and now there finally are.
I would like to know if you have plans to add more criteriaType. I'm developing a mod that includes many additional achievements and more criteriaType would be very useful. Also, as a suggestion, it would be great if clicking on an achievement showed the date it was earned, a more detailed description, and some additional information, like the coordinates where you were when you achieved it, for example.
As a token of gratitude, I am attaching the Spanish language file here. It is important to mention that the file name must be "es-es" and not simply "es", since Vintage Story differentiates between the Spanish of Spain and the Spanish of Latin America with "es-es" for Spain and "es-419 "for Latin America. In this case, it should be "es-es", since I am from Spain.
Contents of the language file "es-es"
Nateonus
impossible. Bot delete link which did not goes to https://mods.vintagestory.at/
so that´s why ask you. Need to find another way.
DejFidOFF thanks! You're welcome to upload it to google drive or some other file sharing website and link it as a comment on here :)
Nateonus
Hello o/ I really like that mod, using it at our server. I translete achievements to the Czech language. Is it possible to add that to this translate to the mod? Where I can catch you with the file? Thank you.
Nateonus
I have added achievements to one of my mods. Can I get it listed above please and thank you?
Primitive Survival
And thanks for the mod...very cool!
Shinji170981 Ahh, interesting.
I'm going to say that it's likely those mods that are causing an issue, but you've bought up an issue. In the next mod version, I shall add a command to manually unlock an achievement, for those ones that are not possible.
Nateonus sry, i forgot to mention that i am on 1.19.3 and i used a regular clay oven. I am using Culinary Artillery and Expanded Foods, which might have an impact on it.
Besides that, i am notsure what else it could be.
Shinji170981 Interesting...
What version are you using, and what oven did you use to bake the bread? Do you use any other mods that may alter ovens or bread?
For some reason, the "Bread baking" achievement doesn't work. I tried it with regular spelt dough. Tried to bake part baked, baked and charred but none of them triggered the achievement.
It works flawlessly now. You even added an in-game option to change the keybind. Cheers!
Brady_The no need for concern, it wasn't your fault. I have fixed it! Please redownload the newest version and it should work.
The issue is due to the cairosharp DLL being packed inside the zip file.
It's probably something on my end. I have to look into it further to see how, why, and what, but if I am honest I am currently in a bit of a VS exhaustion phase, so troubleshooting might take a while.
This is so rad! I downloaded the second I saw this. Super excited about this mod's future and hoping other mods join in. I'm surprised that I haven't seen an achievement mod before now. Thanks. :)
In reference to Brady_The's experience, I thought I'd add some info for game version 1.19.4, mod v1.1.0, running 50 other mods.
Upon load, I got the chat message and opened the achievement journal. Everything seems to be in working order on my end. The Stone Age achievement triggered after knapping a knife. There's also a config file available. I noticed that 1.19.5 just dropped, but I didn't upgrade yet. The logs didn't have any errors.
@Nateonus Got it. I only play Singleplayer and did some testing on a newly created world with only this mod enabled. Still nothing. I use a different control scheme, with "L" bound to an action. I assume this shouldn't break anything, though.
The only hints I currently have, are the following:
21.3.2024 15:52:04 [Notification] Mods, sorted by dependency: game, natsachievements, creative, survival
21.3.2024 15:52:04 [Error] [natsachievements] An exception was thrown when trying to load assembly:
21.3.2024 15:52:04 [Error] [natsachievements] Exception: Assembly with same name is already loaded
at System.Runtime.Loader.AssemblyLoadContext.g____PInvoke|5_0(IntPtr ptrNativeAssemblyBinder, UInt16* ilPath, UInt16* niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Vintagestory.Common.ModAssemblyLoader.LoadFrom(String path) in VintagestoryLib\Common\API\ModAssemblyLoader.cs:line 34
at Vintagestory.Common.ModContainer.<>c__DisplayClass35_0.b__0(String path) in VintagestoryLib\Common\API\ModContainer.cs:line 449
at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
at Vintagestory.Common.ModContainer.LoadAssembly(ModCompilationContext compilationContext, ModAssemblyLoader loader) in VintagestoryLib\Common\API\ModContainer.cs:line 448
The Seashells achievement troubled me a bit. I didn't want to take too much creative license in the translation, but the literal translation didn't translate too well. I am glad you like it! :-D
Brady_The Hey Brady, thanks for the comment!
To clarify a few things: The default key for opening the journal is 'L'. When you start a game, do you receive a chat message that notifies you of this? If not, the mod may not be loading correctly.
Are you using any other mods that would conflict with this key?
Are you playing on a server that doesn't have the mod?
Regarding rebinding the key, this must be done in the external config file, not the controls menu. This is located in your userdata folder. Mine is found in: "C:\Users\Nat\AppData\Roaming\VintagestoryData\ModConfig", and is called "achievementsconfig".
You should see a line that says "AchievementsJournalMenuKey": 94. This number can be changed to change what key is used. Some suggestions:
Thanks for the translation file! I love "Fisherman Fritze fished fresh... mussel shells" as an entry. I'll pop it in the next version and give you a special thanks!
As an achievement enjoyer this is good stuff!
I wanted to have a quick look, but unfortunately I am not even able to open the Achievement Journal; neither am I able to rebind the key due to a missing entry in the controls menu.
Game version: 1.19.3
Mod version: 1.1.0
I didn't want to come empty-handed, so have a language file: https://drive.proton.me/urls/BGF4TN7PCC#vs1wmHkKKXRV
Edit 04.10.2024: Language File on Github: https://gitlab.com/Brady_The/vintage-story-localization/-/blob/main/Achievements/de.json
Cheers!
Added a description of how to create achievements using JSON! Check out the "Mod Authors - Content/JSON Achievements" section!
Achievements have been updated to 1.1.0! This rather large update adds a few more achievements, the ability to view achievements by mod, and allows achievements to be added through JSON code for content mods!
More details on how to achieve that will be coming imminently, so if you're interested check back soon!
NiclAss that'd need a loooot of work and changes - It'd be an entire system of registering events through a JSON system to make it versatile enough.
What sort of events would you want to be able to call if I did do that?
Any chance for a content mod api via json file?
Makes this mod unusable for content mods atm.
Hi all, I've released a version for 1.19 with a couple of bug fixes too.
Seeing this error on repeat every second in console for days, surviving every reboot
[Server Fatal] System.NullReferenceException: Object reference not set to an instance of an object.
at Achievements.AchievementsPatches.CheckForDoubleHeadedDrifter(EntityAgent __instance, EnumDespawnReason reason, DamageSource damageSourceForDeath)
at Vintagestory.GameContent.EntityBehaviorDespawn.OnGameTick(Single deltaTime) in C:\Users\Tyron\Documents\vintagestory\game\VSEssentials\Entity\Behavior\BehaviorDespawn.cs:line 105
at Vintagestory.API.Common.Entities.Entity.OnGameTick(Single dt) in C:\Users\Tyron\Documents\vintagestory\game\VintagestoryApi\Common\Entity\Entity.cs:line 852
at Vintagestory.API.Common.EntityAgent.OnGameTick(Single dt) in C:\Users\Tyron\Documents\vintagestory\game\VintagestoryApi\Common\Entity\EntityAgent.cs:line 528
at Vintagestory.Server.ServerSystemEntitySimulation.TickEntities(Single dt) in C:\Users\Tyron\Documents\vintagestory\game\VintagestoryLib\Server\Systems\World\EntitySimulation.cs:line 326
at Vintagestory.Server.ServerSystemEntitySimulation.OnServerTick(Single dt) in C:\Users\Tyron\Documents\vintagestory\game\VintagestoryLib\Server\Systems\World\EntitySimulation.cs:line 165
at Vintagestory.Server.ServerMain.Process() in C:\Users\Tyron\Documents\vintagestory\game\VintagestoryLib\Server\ServerMain.cs:line 881
It could be a vanilla thing tbh
yay! I have been waiting for something like this :D
Very cool! :D
Wellaaron Thank you! I'm hoping to add in a fair few more achievements, let me know if you think of any you'd like to see!
awesome ! i love achievements purely for a checklist of what i've done to progress, amazing mod!