Twizzle Posted November 2 Report Share Posted November 2 I started taking a look at modding after spending some time in the game; is there a particular reason why the JSON files are not actually valid JSON? Is VS using a superset like JSON5 or RJSON? This is nitpicky for sure, but more just curious  For example, assets\survival\blocktypes\wood\bed.json: { code: "bed", class: "BlockBed", entityClassByType: { "*-head-*": "Bed", }, According to the JSON standard (see the RFC if you're keen) keys must be strings, and later clarifies (section 7 of that RFC) that strings must be surrounded by quotation marks. Given that "*-head-*" is surrounded and the others aren't, I would assume some sort of superset...? Link to comment Share on other sites More sharing options...
Spear and Fang Posted November 2 Report Share Posted November 2 JSON5 yeah. Tyron says it saves him time - a lot less keystrokes. Regular JSON works fine too, and the consensus is that it's a little more performant. It's the newtonsoft json framework being used. https://www.newtonsoft.com/json Link to comment Share on other sites More sharing options...
Twizzle Posted November 2 Author Report Share Posted November 2 (edited) Interesting reasoning! I don't appear to be able to find that the newtonsoft package supports JSON5? Guess I could just try it out and see. The issue I see is trying to programmatically use the JSON files, for example, iterating beds somehow rather than listing all different types of beds one by one - maybe I am missing a key piece of the puzzle as the API documentation is a bit difficult to read, although I also understand that it's generated, and nobody wants to do documentation my early idea was to get the bed.json file with AssetLocation, then prepend "bed-", get the variantgroups, shapebytype, and compile an array with a bunch of string manipulation. It all seems a bit tedious to not have some way to do it programmatically, but like I said maybe I am missing some knowledge here? Edited November 2 by Twizzle Link to comment Share on other sites More sharing options...
DArkHekRoMaNT Posted November 3 Report Share Posted November 3 19 hours ago, Twizzle said: Interesting reasoning! I don't appear to be able to find that the newtonsoft package supports JSON5? Guess I could just try it out and see. The issue I see is trying to programmatically use the JSON files, for example, iterating beds somehow rather than listing all different types of beds one by one - maybe I am missing a key piece of the puzzle as the API documentation is a bit difficult to read, although I also understand that it's generated, and nobody wants to do documentation my early idea was to get the bed.json file with AssetLocation, then prepend "bed-", get the variantgroups, shapebytype, and compile an array with a bunch of string manipulation. It all seems a bit tedious to not have some way to do it programmatically, but like I said maybe I am missing some knowledge here? You shouldn't work with json files directly as you would with strings. Either use a ready-made block/item from the game, or a patch. Patches are made through a fork of the Tavis.JsonPatch library using other json or C# code. Link to comment Share on other sites More sharing options...
DArkHekRoMaNT Posted November 3 Report Share Posted November 3 (edited) What do you even want to do? What is the goal? Edited November 3 by DArkHekRoMaNT Link to comment Share on other sites More sharing options...
Twizzle Posted November 3 Author Report Share Posted November 3 I'm assuming you mean specifically with this game/engine? Working with JSON files is very common, especially to read from to get data. I guess, like I said, I am missing some key concepts in regard to the VS API. To be clear, I am not looking to make a patch/JSON mod, I am using .NET as I'll have to make a GUI, etc. My main goal right now is to programmatically get a list of all possible bed blocks, to then add logic/GUI to interaction with one. I could do something like: serverAPI.World.GetBlock(new AssetLocation("bed-hay-head-north")).BlockId; serverAPI.World.GetBlock(new AssetLocation("bed-hay-head-south")).BlockId; //repeat for every bed type and direction Instead of doing this, my idea was to read the JSON file for beds and extract the values in "variantgroups" and "shapebytype", and do some string manipulation (in .NET, not modifying the JSON, to clarify) and add all of them to an array for later event handling, something like: // class field private List<int> bedIdentifiers; // [...] public override void StartServerSide(ICoreServerAPI api) { base.StartServerSide(api); string bedJson; // get bed.json here and use the values in it for the following lists List<string> bedTypes = new List<string>(); // populate with types from JSON file, i.e., "wood", "hay", etc. List<string> bedParts = new List<string>{ "head", "feet" }; List<string> directions = new List<string>{"north", "east", "south", "west"}; foreach (string bedType in bedTypes) { foreach (string direction in directions) { foreach (string bedPart in bedParts) { // compile bed array bedIdentifiers.Add(serverAPI.World.GetBlock(new AssetLocation($"bed-{bedType}-{bedPart}-{direction}")).BlockId); } } } } Might seem like a ridiculous way to go about this, but if more bed types were added, the mod wouldn't work properly. Hope that was clearer, and I hope there's an easier way to do this via API! Link to comment Share on other sites More sharing options...
Spear and Fang Posted November 3 Report Share Posted November 3 (edited) I am also a little confused as to your end goal here. In general I'd say to approach it differently - don't collect an array of all bed variants, but rather attach a c# class of some sort to the bed block itself - so that that class impacts all beds, regardless of the variant - especially the rather irrelevant direction variant . Or use harmony to attach your code to one of the existing bed classes. On the API documentation front - if you're referring to this https://apidocs.vintagestory.at/api/index.html I'd highly recommend using DNSpy or ILSpy or Visual Studio and opening the games shipped DLL's with that instead. It's much more searchable and just as informative.  Edited November 3 by Spear and Fang Link to comment Share on other sites More sharing options...
Twizzle Posted November 3 Author Report Share Posted November 3 1 minute ago, Spear and Fang said: but rather attach a c# class of some sort to the bed block itself I guess this would be what I was looking for - I'm not sure how I would go about that though. I will also take a look at harmony, and perusing the DLLs, thanks! Link to comment Share on other sites More sharing options...
Spear and Fang Posted November 3 Report Share Posted November 3 (edited) I'm not near a VS installation so I may make some mistakes, but.... I typically start by 1. locating the json asset that I want to change, so if it's the bed ...assets/game/blocktypes/wood/bed.json 2. look at keys like "class", "entityclass", "behaviour(s)", "entityBehaviors", that sort of thing.  These are attaching c# code to the json asset 3. track those classes down on the anegostudio github, i.e. https://github.com/search?q=org%3Aanegostudios bed&type=code and familiarize yourself with the bed 4. Now you decide if you want to do a. something heavy handed like add or replace one of those classes entirely (class or entityclass) via a json patch i.e. - replace an existing class https://github.com/SpearAndFang/primitive-survival/blob/main/PrimitiveSurvival/PrimitiveSurvival/assets/primitivesurvival/patches/ps-oreminingbomb.json - add where one doesn't exist https://github.com/SpearAndFang/primitive-survival/blob/main/PrimitiveSurvival/PrimitiveSurvival/assets/primitivesurvival/patches/ps-pelt.json b. something much more light touch like extend one of those classes by adding a behavior or entitybehavior (or append one to a list of already existing behaviors) via a jjson patch i.e. https://github.com/SpearAndFang/buzzwords/blob/main/assets/buzzwords/patches/bebwildbeehive.json c. or circumvent all of that by using a harmony patch. https://harmony.pardeike.net/articles/patching.html https://github.com/SpearAndFang/wildfarmingrevival/blob/main/WildFarmingRevival/ModSystem/WildFarmingRevivalSystem.cs#L109 note: definitely check out other people's harmony patches, mine are well blech. In the case of a. and b. above, you then register your new classes in c# when your mod first starts, several i.e. https://github.com/SpearAndFang/primitive-survival/blob/main/PrimitiveSurvival/PrimitiveSurvival/ModSystem/PrimitiveSurvivalSystem.cs#L108 and then do the same sorts of things that the vanilla game does inside your new classes, or entirely different things ;). Plenty of examples of this on the wiki, the anego studios github, the moddb. The modding section of the VS wiki is where I started. It's a little outdated at times but contains a lot of invaluable information. Edited November 3 by Spear and Fang Link to comment Share on other sites More sharing options...
DArkHekRoMaNT Posted November 4 Report Share Posted November 4 20 hours ago, Twizzle said: I'm assuming you mean specifically with this game/engine? Working with JSON files is very common, especially to read from to get data. I guess, like I said, I am missing some key concepts in regard to the VS API. To be clear, I am not looking to make a patch/JSON mod, I am using .NET as I'll have to make a GUI, etc. My main goal right now is to programmatically get a list of all possible bed blocks, to then add logic/GUI to interaction with one. I could do something like: serverAPI.World.GetBlock(new AssetLocation("bed-hay-head-north")).BlockId; serverAPI.World.GetBlock(new AssetLocation("bed-hay-head-south")).BlockId; //repeat for every bed type and direction Instead of doing this, my idea was to read the JSON file for beds and extract the values in "variantgroups" and "shapebytype", and do some string manipulation (in .NET, not modifying the JSON, to clarify) and add all of them to an array for later event handling, something like: // class field private List<int> bedIdentifiers; // [...] public override void StartServerSide(ICoreServerAPI api) { base.StartServerSide(api); string bedJson; // get bed.json here and use the values in it for the following lists List<string> bedTypes = new List<string>(); // populate with types from JSON file, i.e., "wood", "hay", etc. List<string> bedParts = new List<string>{ "head", "feet" }; List<string> directions = new List<string>{"north", "east", "south", "west"}; foreach (string bedType in bedTypes) { foreach (string direction in directions) { foreach (string bedPart in bedParts) { // compile bed array bedIdentifiers.Add(serverAPI.World.GetBlock(new AssetLocation($"bed-{bedType}-{bedPart}-{direction}")).BlockId); } } } } Might seem like a ridiculous way to go about this, but if more bed types were added, the mod wouldn't work properly. Hope that was clearer, and I hope there's an easier way to do this via API! Iterate api.World.Block and get all with code "game:bed-*". Or attach custom BlockBehavior/BlockEntityBehavior via patch bed blocktype json and do code there Link to comment Share on other sites More sharing options...
DArkHekRoMaNT Posted November 4 Report Share Posted November 4 (edited) Usually you don't need to work with json directly from C# code. The game itself does this Edited November 4 by DArkHekRoMaNT Link to comment Share on other sites More sharing options...
Twizzle Posted November 6 Author Report Share Posted November 6 Meant to thank you both for the hints! Thank you Spear for that writeup as well - that is exceptionally helpful. 1 Link to comment Share on other sites More sharing options...
Recommended Posts