Install Steam
login
|
language
简体中文 (Simplified Chinese)
繁體中文 (Traditional Chinese)
日本語 (Japanese)
한국어 (Korean)
ไทย (Thai)
Български (Bulgarian)
Čeština (Czech)
Dansk (Danish)
Deutsch (German)
Español - España (Spanish - Spain)
Español - Latinoamérica (Spanish - Latin America)
Ελληνικά (Greek)
Français (French)
Italiano (Italian)
Bahasa Indonesia (Indonesian)
Magyar (Hungarian)
Nederlands (Dutch)
Norsk (Norwegian)
Polski (Polish)
Português (Portuguese - Portugal)
Português - Brasil (Portuguese - Brazil)
Română (Romanian)
Русский (Russian)
Suomi (Finnish)
Svenska (Swedish)
Türkçe (Turkish)
Tiếng Việt (Vietnamese)
Українська (Ukrainian)
Report a translation problem
Did you enable both the asset and the mod extension in Content Manager?
It is useful to know that the Asset Data API is unfortunately broken. Please see my bug report here:
https://forum.paradoxplaza.com/forum/index.php?threads/cities-skylines-steam-bugs-in-the-asset-data-api.1101710/
Especially the OnAssetSaved problem is a serious one. I am already seeing many assets on the workshop that contain UserAssetData although the asset author does not know anything about it. It is literally like a virus that is spreading inside the game.
So, if you publish something with the Asset Data API, you should ensure that your OnAssetLoaded runs fast because the base game will call it many times. My mod fixes that bug and calls it just once. But my mod does not fix OnAssetSaved.
I open the game, open the DNSpy debugger and create a breakpoint on the first line of OnAssetLoaded method in my mod. If I load a game without LSM enabled, everything runs fine. The method is called once for every asset. If I run it with LSM, the breakpoint is never hit.
I will check that link you gave me. In short, what are the risks of incorrect usage of the userData?
There is the pull for the TMPE which I am working on and where I encounter the bug - https://github.com/krzychu124/Cities-Skylines-Traffic-Manager-President-Edition/pull/288
If you have time we can try to solve it over skype/discord or whatever.
Compare that to the ILoadingExtension. It wouldn't make sense if the OnLevelLoaded(...) method was called for a single mod.
When the asset is saved the same thing happens - all mods that extend the IAssetDataExtension are called. Each mod can pass its dictionary with userData, but watch out, these dictionaries are merged into single one in the AssetDataWrapper.AddData(Dictionary<string, byte[]> data) method! So then when the asset is loaded all the mods receive the same dictionary which contains all the data.
By the way, I made a quick scan of the LSM mod, but I didn't find the place in the code where you invoke the OnAssetLoaded methods? (Maybe you use reflection or call some higher level methods instead)
In any case, maybe I understand it wrong.
"I didn't find the place in the code where you invoke OnAssetLoaded" : AssetLoader.cs.
"In short, what are the risks of incorrect usage of the userData" : The problem is not incorrect usage. The problem is the serious bug in the base game that has not been fixed.
I have created three test assets, each published with an IAssetDataExtension.
With LSM enabled, each OnAssetLoaded is invoked once, with the correct userData as argument.
Without LSM, each OnAssetLoaded is invoked three times, for all combinations of userData. So there are a total of 3*3=9 invocations. You can see where this leads with a large number of userDatas.
Because of the save bug I explained in my forum post, there are already many orphan userDatas in workshop assets.
Let's assume your asset with an IAssetDataExtension becomes very popular so that everyone subscribes to it. Because of the save bug, eventually all new and updated assets on the workshop will contain your userData, plus userDatas from other popular IAssetDataExtensions. That's crazy.
It doesn't make any sense to ship the IAssetDataExt with every asset, when they are all the same. Imagine you have 10 mods, each of them them needs to be copied to every asset. Isn't this the bloating you are afraid of? This is even worse because you have to load extra files, which greatly reduces performance. All this userData thing was made so that you didn't have to load no extra files. This completly turns it around.
I think you understood it wrong. What alternative do I have now when I want to save data with assets than to save and load them from extra files which takes x times longer? (As for example RICO mod does)
There still could be the save bug you were talking about, could you be then more concrete and name the classes and methods which are responsible for it?
at PloppableRICO.PloppableCommercial.GetConstructionCost () [0x00000] in <filename unknown>:0
at BuildingAI.GetLocalizedTooltip () [0x00000] in <filename unknown>:0
at PrefabInfo.GetLocalizedTooltip () [0x00000] in <filename unknown>:0
at RealTime.Simulation.Statistics.RefreshBuildingsButtons () [0x00000] in <filename unknown>:0
at RealTime.Simulation.Statistics.RefreshUI () [0x00000] in <filename unknown>:0
at RealTime.Simulation.Statistics.RefreshUnits () [0x00000] in <filename unknown>:0
at RealTime.Core.RealTimeCore.Run (SkyTools.Configuration.ConfigurationProvider`1 configProvider, System.String rootPath, ILocalizationProvider localizationProvider, Boolean setDefaultTime, RealTime.Core.Compatibility compatibility) [0x00000] in <filename unknown>:0
at RealTime.Core.RealTimeMod.OnLevelLoaded (LoadMode mode) [0x00000] in <filename unknown>:0
at LoadingWrapper.OnLevelLoaded (UpdateMode mode) [0x00000] in <filename unknown>:0
have any ppl know how to fix it?
Please don't assume userData will be good for performance. Asset deserialization is based on reflection. Most new assets now have userData, almost all of them are empty, yet they need to be decoded. This solution does not beat the RICO way.
The obvious bug in this API is the dictionary (with strings as keys) that collects data from all mods by iterating over them. There will be key collisions. The API does not warn against using simple keys such as "data". No developer would propose an API like that on purpose.
About the strings as keys - I completely understand your point, but on the other hand the same thing happens when saving data to savegame files (which is there for years already). In my opinion developers made it on purpose, putting the responsibility on the shoulders of modders. You can think about it whatever you want, but I must admit that the game code is not of the prettiest things ever created - when I was working on the Smart Intersection Builder mod and had to deal with a method that had over 1100 lines I wasn't too happy either (NetTool.CreateNode). But this is a topic for another day. (And who am I to say anything about it?)
Finally, modders who would use simple keys as "data" wouldn't cause much harm to anyone else than themselves, would they? To inflict a significant damage to the integrity of the game itself would require a much greater blunder.
Either way I respect your decision on how you'll approach this, (of course I'd prefer if you could make it more closely resemble vanilla so that I don't have to do extra work :P) and I'm looking forward to future releases of LSM.