Jump to content

JSON Validity/Superset?


Twizzle

Recommended Posts

👋 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

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 by Twizzle
Link to comment
Share on other sites

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

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

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 by Spear and Fang
Link to comment
Share on other sites

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

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 by Spear and Fang
Link to comment
Share on other sites

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

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.