Jump to content

Is it possible to have external variables affect crops during their growth cycle?


Recommended Posts

I'm in the beginning stages of making a farming mod.  I'd like to remove busywork and introduce player action only when it involves player decisions and resource tradeoffs, in order to keep farming interesting.  A requirement of this mod is that it is XML and runs only on the server (no client install required).

 

I love the concept presented by this mod: https://7daystodiemods.com/crop-growth-by-weather/.  However, that one was made using DMT.  Though when I look at the forum page for DMT it says DMT is being sunset because A20 XML modding can do the things DMT used to be needed for.  So I'm hoping I can recreate some of the functionality presented there in an XML-only modlet.

 

I would like to affect crops, either with a random preset path when planted, or preferably during the growth cycle, based on any of the following:

  • Temperature
  • Biome
  • Elevation
  • Rain
  • Sunlight
  • Time of day
  • Day of week

 

Is it possible to do any of those?  I can't find any other mod that does so to work from example.  Has anyone found a way to have external variables have an effect?

 

I did find the H7SB farming mod (https://7daystodiemods.com/h7sb-farming/) which is pretty awesome, and it's been very instructive.  However, that mod's approach is to send every planted crop down a preset path (plant > fertilize > water > grow (wait) > water > grow (wait) > harvest).  I want variation so players need to react and think during the farming process, preferably based on external stimuli.  If I need to create 100 preset paths for the game to choose from when a seed is planted that's fine, but I can't find any way to do even that.

 

Any thoughts or suggestions are appreciated.

Link to comment
Share on other sites

External sources can't really affect blocks, but you can do more than a preset path like H7SB... You can have:

Planted Plant grows into a placeholder block. This placeholder could spawn the next stage block, a block that requires water, or a block that is infested. The player would have to react to whatever spawns there. So if its infected, spray it with pesticides (using a tool item to upgrade the plant). This would upgrade the block back to the planted stage, allowing it to regrow and choose what blockplaceholder it grows into again.

This is something I use in my rpg mod, though not quite in this context, but the idea is the same.

Here is the blocks. What this does is, I place the HELPER block into a poi. When world gen starts, it randomly picks something from that placeholder (linked further down). Player can break it, it downgrades into the AIR block. This block then regrows back into the helper, which will then choose between placeholders again. If this placeholder chooses the tier1air block to spawn, it repeats the process as that block grows.  A cyclical loop.  Hopefully this makes sense to ya.
 

<block name="DepositTier1Air">
	<property name="Material" value="Mair"/>
	<property name="Shape" value="Invisible"/>
	<property name="Texture" value="250"/>
	<property name="FilterTags" value="fterrain"/>
	<property name="SortOrder1" value="d0j0"/>
	<property name="SortOrder2" value="0050"/>
	<property name="Class" value="PlantGrowing"/>
	<property name="PlantGrowing.FertileLevel" value="0"/>
	<property name="PlantGrowing.Next" value="DepositTier1Helper"/>
	<property name="PlantGrowing.GrowthRate" value="5"/>
	<property name="PlantGrowing.IsRandom" value="false"/>
	<property name="PlantGrowing.LightLevelStay" value="0"/>
	<property name="PlantGrowing.LightLevelGrow" value="0"/>
	<property name="PlantGrowing.IsGrowOnTopEnabled" value="false"/>
</block>
<block name="DepositTier1Helper">
	<property name="AllowAllRotations" value="true"/>
        <property name="CustomIcon" value="OreBlueIcon" /> 
        <property name="Material" value="Mmetal"/>
        <property name="IsTerrainDecoration" value="true"/>
        <property name="Shape" value="ModelEntity"/>
        <property name="Model" value="#@modfolder:Resources/TelricsQuestWorld.unity3d?DepositIronOrePrefab"/>
        <property name="Collide" value="melee,movement"/>
        <property name="CreativeMode" value="Player"/>
        <property name="Stacknumber" value="500"/>
        <property name="Group" value="Building,Building2"/>
        <property name="EconomicValue" value="300"/>
        <property name="FilterTags" value="fdecor"/>
        <property name="SortOrder2" value="0050"/>
        <property name="MaxDamage" value="125"/>
		<property name="Place" value="TowardsPlacer"/>
	<drop event="Destroy" count="0"/>
</block>
<block name="DepositCopperOreBlock"><!-- tier 1 ore -->
	<property name="AllowAllRotations" value="true"/>
        <property name="CustomIcon" value="OreBlueIcon" /> 
        <property name="Material" value="Mmetal"/>
        <property name="IsTerrainDecoration" value="true"/>
	<property name="DisplayInfo" value="Name"/>
        <property name="Shape" value="ModelEntity"/>
        <property name="Model" value="#@modfolder:Resources/TelricsQuestWorld.unity3d?DepositCopperOrePrefab"/>
        <property name="Collide" value="melee,movement"/>
        <property name="CreativeMode" value="Player"/>
        <property name="Stacknumber" value="500"/>
        <property name="Group" value="Building,Building2"/>
        <property name="EconomicValue" value="300"/>
        <property name="FilterTags" value="fdecor"/>
        <property name="SortOrder2" value="0050"/>
        <property name="MaxDamage" value="125"/>
		<property name="Place" value="TowardsPlacer"/>
	<drop event="Destroy" count="0"/>
	<drop event="Harvest" name="resourceCopperOre" count="1,2" tool_category="DepositTier1Harvesting" tag="tier1gathering"/>
	<drop event="Harvest" name="resourceFlint" count="1,2" tool_category="DepositTier1Harvesting" tag="tier1gathering"/>
	<property name="DowngradeBlock" value="DepositTier1Air"/>
</block>



Blockplaceholders:
 

	<placeholder name="DepositTier1Helper"> <!-- tier 1 -->
		<block name="DepositTier1Air" prob=".2"/>
		<block name="DepositCopperOreBlock" prob="1"/>
		<block name="DepositIronOreBlock" prob=".2"/>
	</placeholder>

 

Link to comment
Share on other sites

Thanks Telric!  This is awesome!  It doesn't make sense to me yet, but it will when I have time to sit down and really work through it.

 

If that mod is public, could you link it please?  I'd love to see all of this in context.

 

Are the probabilities something that can be worked into the skills system?  So as a player ups their skill they are more likely to require less cycles to complete the process?  Specifically looking to integrate with the action skills mod: https://7daystodiemods.com/action-skills/

Link to comment
Share on other sites

3 hours ago, Aesirkin said:

Thanks Telric!  This is awesome!  It doesn't make sense to me yet, but it will when I have time to sit down and really work through it.

 

If that mod is public, could you link it please?  I'd love to see all of this in context.

 

Are the probabilities something that can be worked into the skills system?  So as a player ups their skill they are more likely to require less cycles to complete the process?  Specifically looking to integrate with the action skills mod: https://7daystodiemods.com/action-skills/

The rpg mod is not out yet and wont be for a long long time. Already around 2 years spent on this project lol. As for requiring player skill, the only way i can think of right now is to have multiple versions of the plant that can only be planted with certain skills or something. Very sketchy stuff. Maybe one day blocks will be able to take buffs, but I doubt it. lol. If that was the case, this would be sorted very easily.

Link to comment
Share on other sites

On 5/19/2022 at 5:59 PM, Aesirkin said:

I love the concept presented by this mod: https://7daystodiemods.com/crop-growth-by-weather/.  However, that one was made using DMT.  Though when I look at the forum page for DMT it says DMT is being sunset because A20 XML modding can do the things DMT used to be needed for.  So I'm hoping I can recreate some of the functionality presented there in an XML-only modlet.

 

I'm the one who wrote that modlet, so I can tell you the technical details.

 

DMT is being sunsetted, but not because XML modding can do the things DMT could do. DMT used to be used for C# patching using Harmony, and that is now supported natively by the game. But it's still C# code, so requires both client and server installation.

 

The main reason I haven't updated that modlet to A20 is not because of DMT, it's because weather itself was totally revamped in A20, and none of the A19 code can be used. Another reason is that A20 severely nerfed farming, so making crops be able to die - thus making farming even more difficult - is something I thought was unnecessary, and not something I thought anyone else would be interested in.

 

The placeholder block idea from Telric is probably your best bet if you want an XPath-only modlet.

Link to comment
Share on other sites

14 hours ago, khzmusik said:

 

I'm the one who wrote that modlet, so I can tell you the technical details.

 

DMT is being sunsetted, but not because XML modding can do the things DMT could do. DMT used to be used for C# patching using Harmony, and that is now supported natively by the game. But it's still C# code, so requires both client and server installation.

 

The main reason I haven't updated that modlet to A20 is not because of DMT, it's because weather itself was totally revamped in A20, and none of the A19 code can be used. Another reason is that A20 severely nerfed farming, so making crops be able to die - thus making farming even more difficult - is something I thought was unnecessary, and not something I thought anyone else would be interested in.

 

The placeholder block idea from Telric is probably your best bet if you want an XPath-only modlet.

 

Thanks so much for the response, khzmusik!  It's a little disappointing, but having that explanation and confirmation from you is invaluable.

 

I think you're right that the placeholder idea is a great baseline for where I want to go with this, and provides the RNG that I need in order to accomplish much of anything.  I was so glad to see that's possible.

 

I think the other thing that I really need to make this work is a way to introduce player choice.  Optimally, this would be done through multiple upgrade paths (https://community.7daystodie.com/topic/28883-can-a-block-have-multiple-upgrade-paths/).  If a crop begins to wilt do you use murky water to get it going quickly, or do you wait for rain which may add an hour or two onto the growth cycle?  Or maybe boiled water will speed it along more or add to the harvest!

 

If that's not possible I'm not really sure where to go with this.  But if you have any thoughts on that I'd love to hear them.

 

Really appreciate you guys helping me to think it through!  I feel like I'm close to having everything I need to carve out a general scope for the project and get started.  :)

Link to comment
Share on other sites

On 5/19/2022 at 7:43 PM, Telric said:

External sources can't really affect blocks, but you can do more than a preset path like H7SB... You can have:

Planted Plant grows into a placeholder block. This placeholder could spawn the next stage block, a block that requires water, or a block that is infested. The player would have to react to whatever spawns there. So if its infected, spray it with pesticides (using a tool item to upgrade the plant). This would upgrade the block back to the planted stage, allowing it to regrow and choose what blockplaceholder it grows into again.

This is something I use in my rpg mod, though not quite in this context, but the idea is the same.

Here is the blocks. What this does is, I place the HELPER block into a poi. When world gen starts, it randomly picks something from that placeholder (linked further down). Player can break it, it downgrades into the AIR block. This block then regrows back into the helper, which will then choose between placeholders again. If this placeholder chooses the tier1air block to spawn, it repeats the process as that block grows.  A cyclical loop.  Hopefully this makes sense to ya.
 

<block name="DepositTier1Air">
	<property name="Material" value="Mair"/>
	<property name="Shape" value="Invisible"/>
	<property name="Texture" value="250"/>
	<property name="FilterTags" value="fterrain"/>
	<property name="SortOrder1" value="d0j0"/>
	<property name="SortOrder2" value="0050"/>
	<property name="Class" value="PlantGrowing"/>
	<property name="PlantGrowing.FertileLevel" value="0"/>
	<property name="PlantGrowing.Next" value="DepositTier1Helper"/>
	<property name="PlantGrowing.GrowthRate" value="5"/>
	<property name="PlantGrowing.IsRandom" value="false"/>
	<property name="PlantGrowing.LightLevelStay" value="0"/>
	<property name="PlantGrowing.LightLevelGrow" value="0"/>
	<property name="PlantGrowing.IsGrowOnTopEnabled" value="false"/>
</block>
<block name="DepositTier1Helper">
	<property name="AllowAllRotations" value="true"/>
        <property name="CustomIcon" value="OreBlueIcon" /> 
        <property name="Material" value="Mmetal"/>
        <property name="IsTerrainDecoration" value="true"/>
        <property name="Shape" value="ModelEntity"/>
        <property name="Model" value="#@modfolder:Resources/TelricsQuestWorld.unity3d?DepositIronOrePrefab"/>
        <property name="Collide" value="melee,movement"/>
        <property name="CreativeMode" value="Player"/>
        <property name="Stacknumber" value="500"/>
        <property name="Group" value="Building,Building2"/>
        <property name="EconomicValue" value="300"/>
        <property name="FilterTags" value="fdecor"/>
        <property name="SortOrder2" value="0050"/>
        <property name="MaxDamage" value="125"/>
		<property name="Place" value="TowardsPlacer"/>
	<drop event="Destroy" count="0"/>
</block>
<block name="DepositCopperOreBlock"><!-- tier 1 ore -->
	<property name="AllowAllRotations" value="true"/>
        <property name="CustomIcon" value="OreBlueIcon" /> 
        <property name="Material" value="Mmetal"/>
        <property name="IsTerrainDecoration" value="true"/>
	<property name="DisplayInfo" value="Name"/>
        <property name="Shape" value="ModelEntity"/>
        <property name="Model" value="#@modfolder:Resources/TelricsQuestWorld.unity3d?DepositCopperOrePrefab"/>
        <property name="Collide" value="melee,movement"/>
        <property name="CreativeMode" value="Player"/>
        <property name="Stacknumber" value="500"/>
        <property name="Group" value="Building,Building2"/>
        <property name="EconomicValue" value="300"/>
        <property name="FilterTags" value="fdecor"/>
        <property name="SortOrder2" value="0050"/>
        <property name="MaxDamage" value="125"/>
		<property name="Place" value="TowardsPlacer"/>
	<drop event="Destroy" count="0"/>
	<drop event="Harvest" name="resourceCopperOre" count="1,2" tool_category="DepositTier1Harvesting" tag="tier1gathering"/>
	<drop event="Harvest" name="resourceFlint" count="1,2" tool_category="DepositTier1Harvesting" tag="tier1gathering"/>
	<property name="DowngradeBlock" value="DepositTier1Air"/>
</block>



Blockplaceholders:
 

	<placeholder name="DepositTier1Helper"> <!-- tier 1 -->
		<block name="DepositTier1Air" prob=".2"/>
		<block name="DepositCopperOreBlock" prob="1"/>
		<block name="DepositIronOreBlock" prob=".2"/>
	</placeholder>

 

 

Telric, could you please help me understand this better?

 

I think it's a little clearer to me now.  I understand exactly what it does, and it's awesome functionality that's going to be the core of my new farming mod.  But I don't actually understand how it does what it does yet.

 

I see where DepositTier1Air has the property PlantGrowing.Next set to DepositTier1Helper.  This makes sense to me.  After 5 minutes the air block should 'grow' into the helper block.

 

But then you have two entities named DepositTier1Helper.  You have a block in blocks.xml, and then a placeholder in in Blockpaceholders.xml.  I don't understand what the placeholder does or how it is used.  If you showed me this code and asked me to guess, I'd say that DepositTier1Air would always turn into a DepositTier1Helper block (as defined in block.xml) after 5 minutes, and that's it.

 

What causes 7DTD to know that there's a placeholder and to use that placeholder?  Does any block that has an identically named placeholder immediately roll against the placeholder list and then turn into whatever block is chosen?

 

 

Also, what is the point of the air block?  Why not just bounce between the ore blocks and the placeholder blocks?

 


Thanks again!  :)

 

Link to comment
Share on other sites

3 hours ago, Aesirkin said:

 

Telric, could you please help me understand this better?

 

I think it's a little clearer to me now.  I understand exactly what it does, and it's awesome functionality that's going to be the core of my new farming mod.  But I don't actually understand how it does what it does yet.

 

I see where DepositTier1Air has the property PlantGrowing.Next set to DepositTier1Helper.  This makes sense to me.  After 5 minutes the air block should 'grow' into the helper block.

 

But then you have two entities named DepositTier1Helper.  You have a block in blocks.xml, and then a placeholder in in Blockpaceholders.xml.  I don't understand what the placeholder does or how it is used.  If you showed me this code and asked me to guess, I'd say that DepositTier1Air would always turn into a DepositTier1Helper block (as defined in block.xml) after 5 minutes, and that's it.

 

What causes 7DTD to know that there's a placeholder and to use that placeholder?  Does any block that has an identically named placeholder immediately roll against the placeholder list and then turn into whatever block is chosen?

 

 

Also, what is the point of the air block?  Why not just bounce between the ore blocks and the placeholder blocks?

 


Thanks again!  :)

 

Blockplaceholders are defined by a matching name of the block in blocks.xml in the blockplaceholders.xml.. So if you have a block named OMGIMABLOCK in blocks.xml, in order to use it as a helper style block, it needs a matching OMGIMABLOCK blockplaceholder. Then, any block you wish for that OMGIMABLOCK to become when that placeholder is called, you put in blockplaceholders.xml. This is why my deposittier1helper is named the same in placeholders.xml, but you can see the list of possible blocks it will become. In my example, there is a chance for it to spawn air again, so for your purpose you can remove that.

As for why air blocks, in my rpg mod, ores are in specific areas. Once you mine them, they will come back in that same spot, but have a chance to become different ores. You can only have one timer for plant growth, so to counter that a bit, the ore has a chance to respawn as air, which will then regrow. The effect would be adding more time on that plantgrowth timer. Instead of just 5 mins or w/e i have it at, it could spawn an air block so it would be 10 mins.. At this point in time, the mod hasn't been balanced, so times and what not are subject to change, but the essence of the idea is there which is all that im after at this point. lol

Link to comment
Share on other sites

Thanks; that cleared things up!

 

16 hours ago, Telric said:

As for why air blocks, in my rpg mod, ores are in specific areas. Once you mine them, they will come back in that same spot, but have a chance to become different ores. You can only have one timer for plant growth, so to counter that a bit, the ore has a chance to respawn as air, which will then regrow. The effect would be adding more time on that plantgrowth timer. Instead of just 5 mins or w/e i have it at, it could spawn an air block so it would be 10 mins.. At this point in time, the mod hasn't been balanced, so times and what not are subject to change, but the essence of the idea is there which is all that im after at this point. lol

 

Apparently great minds think alike, because I was actually testing something similar with a helper block when you wrote this.  :)

 

Thanks so much for all your help; I'm on my way to creating something pretty cool...

Link to comment
Share on other sites

On 5/23/2022 at 4:45 PM, Telric said:

Blockplaceholders are defined by a matching name of the block in blocks.xml in the blockplaceholders.xml.. So if you have a block named OMGIMABLOCK in blocks.xml, in order to use it as a helper style block, it needs a matching OMGIMABLOCK blockplaceholder. Then, any block you wish for that OMGIMABLOCK to become when that placeholder is called, you put in blockplaceholders.xml. This is why my deposittier1helper is named the same in placeholders.xml, but you can see the list of possible blocks it will become. In my example, there is a chance for it to spawn air again, so for your purpose you can remove that.

 

Have you found any way to make certain block possibilities dependent on books?

 

For example, suppose that I have:

 

				<placeholder name="place1">
					<block name="block1" prob=".4"/>
					<block name="block2" prob=".2"/>
					<block name="block3" prob=".8"/>
				</placeholder>

 

But I only want block3 to be included in the rotation if the player has read the book that unlocks it.

 

I looked at the default blockplaceholders.xml and gameevents.xml files, but don't see any option to do this.  the placeholders appear to be straightforward with no logic allowed, and the "requirements" listed at the bottom of gameevents.xml don't include the possibility to look at a cvar.

 

Any ideas on a creative way to do this?

Link to comment
Share on other sites

2 hours ago, Aesirkin said:

 

Have you found any way to make certain block possibilities dependent on books?

 

For example, suppose that I have:

 

				<placeholder name="place1">
					<block name="block1" prob=".4"/>
					<block name="block2" prob=".2"/>
					<block name="block3" prob=".8"/>
				</placeholder>

 

But I only want block3 to be included in the rotation if the player has read the book that unlocks it.

 

I looked at the default blockplaceholders.xml and gameevents.xml files, but don't see any option to do this.  the placeholders appear to be straightforward with no logic allowed, and the "requirements" listed at the bottom of gameevents.xml don't include the possibility to look at a cvar.

 

Any ideas on a creative way to do this?

Only way using xml only would be having multiple blocks that the player gets that follow different lines. So by default player can craft place1 which has block1 and block2 as possible outcomes, then player gets the book and that book inverts recipes so player can no longer craft place1, but can now craft place2, which will have all 3 blocks as possible outcomes. Wouldn't affect blocks already placed, so they'd have to re plant the seeds or w/e you're doing. Blocks have no way of tracking player information besides what's hard coded (like ownership and what not, for certain blocks)

Link to comment
Share on other sites

On 5/27/2022 at 10:32 PM, Telric said:

Only way using xml only would be having multiple blocks that the player gets that follow different lines. So by default player can craft place1 which has block1 and block2 as possible outcomes, then player gets the book and that book inverts recipes so player can no longer craft place1, but can now craft place2, which will have all 3 blocks as possible outcomes. Wouldn't affect blocks already placed, so they'd have to re plant the seeds or w/e you're doing. Blocks have no way of tracking player information besides what's hard coded (like ownership and what not, for certain blocks)

 

Thanks.  Unfortunately, that's not viable for me because the plants always return seeds, so there will be no point where they would swap out the old seed for the new.  That's okay, though.  I'll just keep the books unlocking the tools that allow them to take action on the blocks and that will work well enough.

 

 

Link to comment
Share on other sites

1 hour ago, Aesirkin said:

 

Thanks.  Unfortunately, that's not viable for me because the plants always return seeds, so there will be no point where they would swap out the old seed for the new.  That's okay, though.  I'll just keep the books unlocking the tools that allow them to take action on the blocks and that will work well enough.

 

 

Doesn't always have to drop seeds, unless you're making it downgrade to the planted version.

 


        <effect_group name="Allow Drop Rates">
			<requirement name="PlayerItemCount" item_name="questItemTrainingDummyParts" operation="LT" value="4"/>
			<passive_effect name="HarvestCount" operation="base_set" value="1" tags="TrainingDummyParts"/>
		</effect_group>



I use this quite a bit in my rpg mod. A certain quest will give the player an item that changes a cvar or just sets the harvest count amount like this one. So if a player is on this quest and has less than 4 training parts, they will be able to harvest them from my training dummies. Once they have over 4, or are not on the quest, those training parts do not drop from the block.

You could do that with seeds. Have a master buff that would set the harvest count to 0 / 1 based on what perk. So if no perk, they can only harvest seedlingtype1... but if they perk into or read a book, that buff then makes it so they harvest 0 of seedlingtype1, but now harvest 1 seedlingtype2.

For this to work, i have:

<passive_effect name="HarvestCount" operation="base_set" value="0" tags="TrainingDummyParts"/>

on the player in entities.xml, then when the player gets on the quest to get these parts, they are given an item which gives them a buff (the stuff from earlier). You could make this happen in a master buff via progressionlevel check requirements.

Link to comment
Share on other sites

Ah, that's smart!  I'll keep it in mind for a possible update.  I'm thinking it may be about time to release my current progress as v1.0 and take a break for a while.

 

Thanks for all the help Telric; I couldn't have completed this without you, and I think it came out pretty awesome.  :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...