News:

Welcome to World of Banished!

Main Menu

Values in Citizen.rsc?

Started by tangent, November 15, 2018, 09:01:37 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

tangent

#15
Oh, I'm fairly positive that .crs file is created after compiling. The file extension convention suggests that too. If .rsc is resource, .crs strikes me as compiledResource.

Let me futz with this a tad and see. It's still 7 am here though, so I'm theorizing this from under my covers hahaha

EDIT:

As it turns out, Luke already breaks the aspects of Citizens apart:

Top of Citizen.rsc is:

ComponentDescription resource
{
// how often to update
UpdatePriority _updatePriority = Second;

// declare types that will be used
Description _descriptions
[
"ui",
"toolbar",

"model",
"picking",
"highlight",
"character",
"statusicon",
"storage",
"citizen",
"citizenai",
]
}


The array of strings there matches each 'description' for the sub-sections of the .rsc file:


ToolbarDescription toolbar
{
StringTable _stringTable = "Dialog/StringTable.rsc:objects";
String _stringName = "Citizen";
}

CharacterDescription character
{
float _headingOffset = 0.0;
float _turnFilter = 0.96;
float _defaultAnimationBlendTime = 0.5;

float _slowSpeed = 0.75;
float _fastSpeed = 1.2;
float _fastestSpeed = 1.4;
}


Wanna guess what those description strings map to? Check the attachment...

Yeah, that's where the compiled resources are built from.


Here's where my wild theory comes in. I'm thinking I can create a file called, idk, CitizenLifeValues.rsc.

Now we have a file that 'only' modifies marriage ages (I tweaked those values), death/life expectancy, health and happiness thresholds, disease, food, tools, cold resistance, clothing life, doctor effectiveness, and work selection values. (yeah, I know it's a lot)

What it DOESN'T include are which models are used, the animations used for picking up resources, how fast/slow citizens walk (on or off roads), or how many materials they can carry.

What this means:

We can make a base, required mod that replaces Citizen.rsc with an empty array(to overwrite vanilla). We then create new files that each have one string in the Descriptions array and build the .crs files separate from one another. Then you can add mods that modify those separate sections and build their individual .crs files

This file would pretty much be:

ComponentDescription resource
{
// how often to update
UpdatePriority _updatePriority = Second;

// declare types that will be used
Description _descriptions
[
"citizen"
]
}

CitizenDescription citizen
{
Profession _schoolingProfession = "Game/Profession/Profession.rsc:teacher";
Profession _churchProfession = "Game/Profession/Profession.rsc:priest";
Profession _doctorProfession = "Game/Profession/Profession.rsc:doctor";

// age at which children becomre adults
float _adultAge = 2.6;
float _marriageAge = 2.6;
float _marrigeRange = 4.0;
float _childMinAge = 3.0;
float _childMaxAge = 8.0;

float _maxAge = 15.0;
float _maxAgeTolerance = 3.0;
float _agePerSecond = 0.000277777;

float _childTerm = 900.0;
float _postChildTerm = 1800.0;
float _postChildTermTol = 5400.0;
float _childBirthHealthy = 0.00625;
float _childBirthUnhealthy = 0.025;

float _health = 10.0;
float _maxHealth = 10.0;
float _unhealthyLevel = 8.0;
float _healthUpdateInMonths = 3.0;

float _maxHappiness = 10.0;
int _minFoodForHappiness = 4;
int _maxFoodForHappiness = 12;
float _happinessUpdateInMonths = 3.0;
int _workForHappiness = 10;
float _unhappyLevel = 0.6;
float _depressedLevel = 0.25;
int _idleRange = 25;

// chance of disease, per year.
RandomSelection _diseaseChanceHealthy
{
float _years = 20;
float _population = 500;
}

RandomSelection _diseaseChanceUnhealthy
{
float _years = 1;
float _population = 400;
}

RandomSelection _diseaseChanceNomadTrade
{
float _years = 1;
float _population = 250;
}

// how long disease lasts in months +-
float _diseasePeriod = 1.0;
float _diseasePeriodTol = 0.5;

// how long immune to disease after recovering
float _immunityLength = 12.0f;

float _foodPerYear = 50;
float _foodLevel = 25.0;
float _hungerLevel = 7.5;
float _starvingLevel = 18.0;
float _maxHunger = 25.0;

float _retryInMonths = 0.1;

float _fuelLevel = 8.0;

float _coldnessLevel = 7.5;
float _freezingLevel = 15.0;
float _coldPerMonth [ 12.0, 8.0, 5.0 ]
float _maxColdness = 20.0;
float _minTemperature = 48.0;

int _toolQuality = 100;
float _toolPenalty = 5.0;

int _requiredEducation = 400;
float _educationTimeLength = 3.0;
float _educationWorkLength = 10.0;

float _doctorChanceOfDeathScalar = 2.0;
float _medicateWorkLength = 10.0;
float _medicineEffectivenessInMonths = 0.01;

float _clothingLengthInMonths = 48.0;

int _maxWaterForFireSearch = 64;

int _minDistanceForWork = 60;
int _maxDistanceForWork = 2000; // must encompass longest walk path!
int _timeUntilMaxDistanceForWorkInMonths = 6;
int _maxWalkInWinter = 200;
float _minTemperatureForWinterWalk = 45.0;

GraphicsMesh _tools
[
"Models\Citizen\ToolAxeMesh.rsc"
"Models\Citizen\ToolPickAxeMesh.rsc"
"Models\Citizen\ToolScytheMesh.rsc"
"Models\Citizen\ToolHoeMesh.rsc"
"Models\Citizen\ToolHammerMesh.rsc"
"Models\Citizen\ToolFishingMesh.rsc"
"Models\Citizen\ToolHammerMesh.rsc"
"Models\Citizen\ToolHandSawMesh.rsc"
"Models\Citizen\ToolBucketMesh.rsc"

"Models\Citizen\BarrowEmptyMesh.rsc"
"Models\Citizen\BarrowFullMesh.rsc"
]
}

[\code]

tangent

#16
Update:

So far, it looks like my theory is correct. I removed the UI from the Citizen.rsc file and added it to its own file. Then I used the Package.rsc file to load the new 'CitizenUi.rsc' and package it with the Citizen.rsc file.

It leads to some weird naming convention, but that's pretty much because Luke is using string interpolation when compiling the file names. You can see my compiled resources in the 'compiled.jpg' file, and a screenshot showing the game still running and loading UI for the citizens/bannies correctly.

God, I love coding.

I guess the next step from here is to break all the sections of Citizen.rsc out, then try modifying ONE of those files to see if the changes load correctly. After that, I need to make a separate .pkm to see if I change one of the Citizen sub-sections (like Cititzen_character) and overwrite my new library mod. If that last step works, we can use the same method on literally every resource file.

tldr; if I manage to make this work, we no longer have to pick a variation of a single .rsc, we can make variations of .crs instead. In layman's terms, WAY more customization.

RedKetchup

Quote from: tangent on November 17, 2018, 06:07:20 AM
God, I love coding.

awesome !!!

awesome cause you completly lost me when you started to break the citizens.rsc into replacement pieces ^^
i have 0 knowledge in programmation.

i really hope you can accomplish great things !!
> > > Support Mods Creation developments with Donations by Paypal  < < <
Click here to Donate by PayPal .

embx61

Not sure about this but are we all ready doing this?

This is what we call an override. Some segments of a file are changed and the rest stays as Vanilla.

Instead of after changing a value we define that changed segment as for example CitizenDescription: citizen

So the compiler only compiles the citizen part of the Citizen.rsc file.

The citizen part is where most changes happiness, tools, cold, marriage, etc. are done and I doubt that segment can be split up into more parts without having the source C++ code.
So everything in this segment get overwritten by another mod which changes the segment too and is higher in the Mod list.

I not think all of the code segment below can be split up. It is all in the citizen object.
CitizenDescription citizen
{
Profession _schoolingProfession = "Game/Profession/Profession.rsc:teacher";
Profession _churchProfession = "Game/Profession/Profession.rsc:priest";
Profession _doctorProfession = "Game/Profession/Profession.rsc:doctor";

// age at which children becomre adults
float _adultAge = 2.0;
float _marriageAge = 2.0;
float _marrigeRange = 4.0;
float _childMinAge = 2.2;
float _childMaxAge = 8.0;

float _maxAge = 15.0;
float _maxAgeTolerance = 3.0;
float _agePerSecond = 0.000277777;

float _childTerm = 900.0;
float _postChildTerm = 1800.0;
float _postChildTermTol = 5400.0;
float _childBirthHealthy = 0.00625;
float _childBirthUnhealthy = 0.025;

float _health = 10.0;
float _maxHealth = 10.0;
float _unhealthyLevel = 8.0;
float _healthUpdateInMonths = 3.0;

float _maxHappiness = 10.0;
int _minFoodForHappiness = 4;
int _maxFoodForHappiness = 12;
float _happinessUpdateInMonths = 3.0;
int _workForHappiness = 10;
float _unhappyLevel = 0.6;
float _depressedLevel = 0.25;
int _idleRange = 25;

// chance of disease, per year.
RandomSelection _diseaseChanceHealthy
{
float _years = 20;
float _population = 500;
}

RandomSelection _diseaseChanceUnhealthy
{
float _years = 1;
float _population = 400;
}

RandomSelection _diseaseChanceNomadTrade
{
float _years = 1;
float _population = 250;
}

// how long disease lasts in months +-
float _diseasePeriod = 1.0;
float _diseasePeriodTol = 0.5;

// how long immune to disease after recovering
float _immunityLength = 12.0f;

float _foodPerYear = 100;
float _foodLevel = 25.0;
float _hungerLevel = 10.0;
float _starvingLevel = 18.0;
float _maxHunger = 25.0;

float _retryInMonths = 0.1;

float _fuelLevel = 8.0;

float _coldnessLevel = 7.5;
float _freezingLevel = 15.0;
float _coldPerMonth [ 12.0, 8.0, 5.0 ]
float _maxColdness = 20.0;
float _minTemperature = 48.0;

int _toolQuality = 100;
float _toolPenalty = 5.0;

int _requiredEducation = 400;
float _educationTimeLength = 3.0;
float _educationWorkLength = 10.0;

float _doctorChanceOfDeathScalar = 2.0;
float _medicateWorkLength = 10.0;
float _medicineEffectivenessInMonths = 0.01;

float _clothingLengthInMonths = 48.0;

int _maxWaterForFireSearch = 64;

int _minDistanceForWork = 60;
int _maxDistanceForWork = 2000; // must encompass longest walk path!
int _timeUntilMaxDistanceForWorkInMonths = 6;
int _maxWalkInWinter = 200;
float _minTemperatureForWinterWalk = 45.0;

GraphicsMesh _tools
[
"Models\Citizen\ToolAxeMesh.rsc"
"Models\Citizen\ToolPickAxeMesh.rsc"
"Models\Citizen\ToolScytheMesh.rsc"
"Models\Citizen\ToolHoeMesh.rsc"
"Models\Citizen\ToolHammerMesh.rsc"
"Models\Citizen\ToolFishingMesh.rsc"
"Models\Citizen\ToolHammerMesh.rsc"
"Models\Citizen\ToolHandSawMesh.rsc"
"Models\Citizen\ToolBucketMesh.rsc"

"Models\Citizen\BarrowEmptyMesh.rsc"
"Models\Citizen\BarrowFullMesh.rsc"
]
}


Maybe you are talking about something else and I missed the point of what you are want to do.
[size=8pt][color=teal]My beloved Kathy
As you were you will always be
Treasured forever in my memory[/color][/size]

[size=10pt]For my list of Mods with download links go here[/size]

tangent

@embx61 So, I'm overriding the Citizen.rsc file, since that is actually just an index of objects used to define various attributes of the Citizen class. I'm actually a Ruby/Javascript developer, so I'm just pinching my nose and hoping that basic principles of OOD/OOP apply here :)

With that said, I've only broken down index into the description objects:

HighligtDescription highlight {}


With the library in place, the vanilla index for Citizen.rsc is replaced with an empty file


// layout of the entity
ComponentDescription resource
{
// how often to update
UpdatePriority _updatePriority = Second;

// declare types that will be used
Description _descriptions
[]
}

StateMachineDescription statemachine { }


I'm a little worried about performance since there are now 11 calls to statemachine {}, but I'm guessing that's just an initalizer/constructor function and that it won't cause lasting harm.

As for breaking down the description citizen object down further... I have ideas for that:


CitizenDescription citizen
{
Profession _schoolingProfession = "Game/Profession/Profession.rsc:teacher";
Profession _churchProfession = "Game/Profession/Profession.rsc:priest";
Profession _doctorProfession = "Game/Profession/Profession.rsc:doctor";

...


At the beginning of this object, Luke imports Profession objects and points the variables (_schoolingProfession) to path resources. Those resources are child classes of the Profession Parent class.

We may (MAY) be able to define child classes of the citizen object and break the large Citizen class into smaller objects. That would give us independent customization of those values. With that, we can have a separate mod for aging and food.

The issue there isn't with the code... it's with end users. We'd have to make a SUPER thorough walkthrough describing load orders, required vanilla-valued library mods, and probably some computer science lessons built in to help non-dev's understand what is actually going on...


With that said:
Screenshots prove that fully breaking apart the Citizen.rsc into sub-resources correctly compiles and allows the game to function normally.

kid1293

I agree to what EB said. We do it all the time with overrides.
And your method would still be dependent on who's mod is on top.

A way to add more options to existing paragraphs would be nice but probably impossible.

Like have 3 trees and a modder adds a 4th. Then next modder could add 5 and 6.

tangent

#21
@kid1293 oh totally. The library pkm would have to be the first loaded, so that any sub-mod could overwrite the one crs they wanted to, but still have vanilla values for the other aspects of the library. For instance, we could have a mesh replacement for how citizens render AND a 1:1 aging mod load without having to code them together.

A community library would mean maintaining a Github repo with the base library, and modders would have to fork the repo or do PRs to add their content...

Additionally, I don't know how C++ handles nil/null/NoMethodErrors. If it fails silently but doesn't crash the program, then modders building off the community library would do pull requests adding a call to their rsc/crs files within the parent class object.

If, when loading mods, the game tries searching for tree 'foo' under the foliage class, but doesn't find it, will it continue to compile the other assets? Will it throw an error, but compile the rest anyway? Or will it just crash?

Oh, here's what the compiled resources look like with this method:

embx61

I understand that the segments like UI, citizen, highlight, etc. can be compiled one at a time and lots of us do this with overrides.

But if Kid and I both change something in the same segment in that file one of ours will be overwritten if both mods are loaded.

Spitting up the citizen part into more parts which would be awesome because then it is possible what you are after but is in my view not possible unless the structure in the C++ source code can be edited and we not have the source code.

[size=8pt][color=teal]My beloved Kathy
As you were you will always be
Treasured forever in my memory[/color][/size]

[size=10pt]For my list of Mods with download links go here[/size]

kid1293

One minor/major objection is - Do we want to incorporate a completely new system
that is not automatic? We (modders) are a lazy bunch if we can.


tangent

#24
Quote
Spitting up the citizen part into more parts which would be awesome because then it is possible what you are after but is in my view not possible unless the structure in the C++ source code can be edited and we not have the source code.

Yeah, without the source code there's a LOT of guesswork involved. Not having access to functions is particularly frustrating, but completely understandable. Still, there are examples within the resource files (namely Profession) that suggest we'd be able to set up really basic inheritance to handle that.

...in fact, I'll give that a go either this weekend or Monday. If it works, I'll upload it so that we can try each making different values and cobbling them together :)

QuoteBut if Kid and I both change something in the same segment in that file one of ours will be overwritten if both mods are loaded.
True, but that happens anyway. It's up to the end user to decide which mod to use or which mod to load first

Quote
One minor/major objection is - Do we want to incorporate a completely new system
that is not automatic? We (modders) are a lazy bunch if we can.

Yeah... that's a daunting thought. The worst part would be fragmenting the resources files initially. 1 typo and BLAM! Compile error. I guess this experiment was mostly just proof of concept?

Yet... if we were to implement a system like this... think about the ramifications! Fully customizable Banished (at least in the sense of the variables it uses to load assets). It'd take a sizeable cabal of the more influential modders within the community to agree to a framework.

Anyway, here's the pkm with the library. I can also provide the folder with the uncompiled assets if anyone wants to mess with it some.

tangent

So doing some learning on C++ and rereading some replies, I've learned some stuff. Particularly that fragmenting the .rsc isnt too useful since a new mod can just call one of the child objects directly (thanks, emb!).

That said, my focus now is to split apart the citizen description object into child components that can be molded independently. Wish me luck

Gatherer

There's never enough deco stuff!!!
Fiat panis.

Tom Sawyer

Maybe Red was not really awake yet or needed a coffee first.^^ As Kid and EB said, you just figured out the standard way of modding, where we change a section of a resource file and compile it into its crs. I loaded your library pkm but can't see how this could work. I would like to see the source to try to understand, if you did not reject this idea. Keep going. Maybe it will lead to something! :)

embx61

Yeps, sadly Banished not really have a SDK (Software Development Kit)
I remember Civilization Game had a SDK and some good stuff was taken out of the Exe and compiled into a DLL and the source of that DLL was given for free.

Knowledge of the C++ language was a must because some real C++ stuff could be changed and the DLL recompiled.
So beside graphics/xml/Python changes direct changes to some of the source could be changed too like even some AI behavior.

All the stuff which is listed in the citizen part are in the source code defined in the object citizen.
So splitting up/delete/add to this is not possible without the source code.

But we appreciate your efforts on this and who knows which (other) stuff you can come up with.
Some stuff what we deemed was not possible was unlocked by some members by digging through the mod kit files over the years.
Flowing water and real transparent glass are two of them.

Good luck in your quest to hopefully unlock some more stuff even if it will not be what you were after because of just too much restrictions in the Mod Kit.
[size=8pt][color=teal]My beloved Kathy
As you were you will always be
Treasured forever in my memory[/color][/size]

[size=10pt]For my list of Mods with download links go here[/size]

tangent

Civilization! That's where I first cut my teeth with programming! Changing XML values.

@Tom Sawyer Here's the zip with the source files for the pkm. Maybe I actually did something useful and just misunderstood something?

I was under the impression that changing 1 value in Citizen.rsc would recompile ALL crs (which it does), but that those crs assets would overwrite another mod that changed something in the same rsc as you.

In other words, if I changed something with the citizen toolbar, and you changed something with the mesh, if your mod was loaded after mine, it would overwrite my toolbar changes even though the toolbar was a different crs.

My idea with the library was that we could use the library as a base mod (which overwrites vanilla indexes with vanilla-valued sub-files) and that you could create your template/CitizenModels mod and I could create my template/CitizenToolbar mod and they wouldn't overwrite one another.

Anyway, I attached a zip with the source files.