Jump to content

khzmusik

Members
  • Posts

    1,250
  • Joined

  • Last visited

  • Days Won

    7

Posts posted by khzmusik

  1. Hello, all.
     
    I was recently asked for advice about setting up and using Git. It is a subject that I think every mod developer should know about, so I decided to make this post.
     
    What is Git and why should you use it?
     
    Git is a version control system (VCS). A VCS includes a centralized repository ("repo") for source code, with tools and commands to organize it such that multiple developers can work on that source code at the same time. The centralized repo is called the "remote" repo, since it's usually hosted on a server somewhere. For most mod developers, the remote repo will be hosted on either GitHub or GitLab (though there are other choices, like Bitbucket, and large companies often host their own).
     
    It's not meant for the same kind of filesharing that Dropbox or Google Drive offer. But that is a good thing. Once you learn how to use Git (and it's really not that difficult), it will make your life a whole lot better.
     
    Version control systems have been around for decades. But unlike the older systems (like CVS or SVN), Git is distributed. This means when you copy the repo from remote to your local computer, you get a copy of the entire repository - including all its files, branches, and history. This is very useful. If the centralized repo goes down, you can still do your work. You can also work without the Internet, like on a plane or on vacation or something. And if you made a mistake with the repo itself (like committing something you shouldn't have), you can fix it locally, and only push to the remote repo when you're ready.
     
    Repos can be either public or private. In most cases, public is better. Users can download from them, you have more options for free Git hosts, and it's generally better if other people can see your source code. But you can use private repos if you really want; most Git hosts provide at least one private repo for free.
     
    Like most VCSs, Git is build around a model of branches and commits. A branch represents a set of code changes that are separate from the main line of development. A commit is a snapshot of the code at a particular moment in time. Commits are associated with one particular branch; the branch holds "indexes" that point to its commits. In Git, HEAD is the index of the latest commit on a branch.
     
    All Git repositories have a default branch. Nowadays, this is called "main". It used to be called "master", but most Git services stopped using that term years ago. In older version control systems, this was often called "trunk", so you will sometimes see that phrase used, but it's not common in Git.
     
    This is the branch that users will see when they navigate to the repo in the web browser, and it's the branch that will be checked out when the repo is cloned (unless specified otherwise). For most software teams, this is also the "production ready" branch - all work-in-progress code changes are done on other branches. (I'll talk about that later.)
     
    How do I set up and use a Git repo?
     
    The first thing you need to do is install Git client software on your computer. Git clients with a graphical user interface are easier to use, and there are many free options. I use, and recommend, GitKraken (it integrates directly with GitLab and GitHub repositories if they're public). But, if you're using GitHub, then it has its own Git client called GitHub Desktop, which is also pretty good (it's the first one I ever used). There are others; many are good but not free, like SmartGit. You can choose whichever one you want, but those are the ones I have used and can recommend.
     
    Also, many code editors (like Visual Studio Code) have plug-ins that integrate with Git. These plug-ins allow you to issue Git commands directly inside the code editor, without needing an additional tool. Personally, I prefer the graphical Git clients, but many people like the plug-ins because they don't require you to switch to another program.
     
    The clients and plug-ins are actually interfaces for Git commands issued on the command line, which means you'll need to install Git itself. Linux distros usually come with Git already, but for Windows you'll need to install it separately. The clients or plug-ins usually walk you through this process.
     
    Next, sign up for a free account at one of the Git services. I use both GitHub and GitLab (the latter also in my day job), and though I prefer GitLab, they're both very good. I have also used Bitbucket (again, in my day job), but its main appeal is that it integrates with other Atlassian tools like Jira (an issue-tracking system). I doubt that most 7D2D mod authors will be using those tools.
     
    Because it seems to be used by slightly more 7D2D mod authors, I'll use GitHub as the example Git host. But most Git hosts work basically the same.
     
    Once you're signed in, create a repository. If you want this repository to be tracked in the Mod Launcher (which I recommend), then you'll need a separate repository for each major 7D2D alpha version. So, I recommend including that version as part of the name for your repo ("A20" or "Alpha20" or whatever).
     
    I'm pretty sure SphereII still has to add Git repos to the Mod Launcher by hand, so once your code is ready, you should send him a message and ask him about it.
     
    GitHub will add a couple files to the repo by default (like a README and a .gitignore file). Leave those in, they're useful. It will also create the default branch ("main").
     
    Next, clone the repository. This will copy it to your local computer. Depending upon the Git client, this will be something like "Clone Repo", and it's usually in the "File" menu. You'll probably have to log in to the remote repo host (GitHub) and allow the Git client software to access your repo. This is usually painless, the client just opens a browser window which you can close afterwards.
     
    Clone the new repo to an empty folder. You don't want to clone it to a folder where you already have source code. (I tried that once and it just causes unnecessary issues.) If you do have existing source code, then once you create the folder with the repo, copy your existing code into it.
     
    When you're adding files for the first time, you should also update the README in the repo's root directory. In both GitHub and GitLab, these are written in Markdown. But if you don't want to learn that, you can just use normal text and it should still be readable. You might also want a LICENSE.txt file, especially if it's a standard license where the legal text is already written (like an MIT or CC license). But I usually put a link to the license in the README.
     
    Hosting multiple mods/modlets in one repository
     
    If you have (or plan to create) multiple mods or modlets, then I recommend hosting them all in the same repository.
     
    If you want to do this, then you would make a subdirectory in the repo for each mod or modlet (the same way it is structured in the Mods folder). The Mod Launcher is smart enough to look in subdirectories of the repo for different mods.
     
    There is a catch. GitHub provides a download option which creates a .zip file of the repo - click the "Code" button, choose "Local", and it's at the bottom. You can right-click on that link and share it. But that is only available for the entire repo - not for subdirectories.
     
    So if you want users to be able to download mods individually from GitHub, they'd have to use something like https://download-directory.github.io/ . An alternative is to manually create .zip files yourself of each of the sub-folers, host the .zip files in the repo, and provide users with links to those files. But this is a pain, and it's easy to forget to update those .zip files when you make code changes.
     
    None of this applies to GitLab. In GitLab, users can download individual subdirectories, hence individual modlets. They will be "wrapped" in an additional folder in the .zip file, but you can warn users about that. It's one of the reasons I prefer GitLab. If you decide to use that, then navigate to the sub-folder, go to the download button (next to the "Clone" button), and there will be a "Download this directory" option. Right click on the ".zip" link and share that.
     
    On the other hand, if you're only going to use Git for a single mod or modlet (like a mod pack or an overhaul), then I have seen plenty of mod authors devote one repo to it. In this case, the repo's root directory would be the root directory of the mod pack or overhaul. This also bypasses the issue with .zip files in GitHub.
     
    Committing and Pushing Changes
     
    Any changes to the source files should show up in your Git client. If you're happy with everything, then you should commit those files. This means you take the code changes and make them an "official" part of the repo.
     
    Git allows you to pick and choose which files you want to commit. To commit changes, you first need to stage those changes. This tells Git "yes, I want those changes to be included in the repo." You can also unstage changes if you change your mind, but only prior to making the commit. The conceptual "place" where changed files are marked to be committed, is usually called the staging environment.
     
    Whenever you commit anything, you should create a commit message. This can consist of a short summary and a longer description. If you don't need to provide details, you can omit the description, but you should always have a summary. The first time I commit code for a new mod or modlet, I use "Initial commit" as the summary.
     
    One thing to note - you can only commit to the branch you currently have checked out. If you haven't switched branches, you'll still be on the main branch. That's fine for the initial commit if you're adding existing code.
     
    Once you commit, your repo is updated - but it's only updated in your local copy of the repo. In order for it to be available on GitHub, you need to push those changes to the remote repo. In most graphical Git clients, there is a dedicated button for pushing.
     
    Most Git clients allow you to amend a commit - take some changes and include them in the previous commit. That works fine if the commit only exists on your local machine, but if it's already pushed to the remote repo, then you would have to actually replace the remote repo's branch with your own. This is called a force push and it's generally not recommended.
     
    If you totally screwed up a commit, and want to start over from a previous commit, then you can also reset your local branch to a previous commit. Resetting comes in three flavors - "hard" (discard all changes), "mixed" (keep the working copy and reset the branch's index), or "soft" (keep all working changes). Personally, I've only used "hard," because anything else can be done by amending the last commit or by making a new commit. And, if you already pushed your changes, then resetting also means you have to force push. So I use resetting only as a last resort.
     
    If you have committed and pushed your code, it should now be in the remote repo, and visible in the GitHub website. If that's all you want, then it's ready to go.
     
    So what do you do if you want to make changes?
     
    Branching and Merging
     
    Changing code is where branches come in. It's also where issues come in, which many people use to track work.
     
    Issues are basically "tickets" that say "This work needs to be done." They are often associated with bugs, but most people also use them for new features, updates, whatever. When you know you have to do something, you create a new issue. The issue has a title as a short summary, and usually a longer description of the work. The Git host will give the ticket a number when it's created.
     
    The nice thing about them is that both GitHub and GitLab allow you to create branches directly from issues. In GitHub, there is a link for this that says "Create a branch", on the right, in the "Development" section. The branch that is created will automatically be named after the ticket number and title. When you make a commit, you can put the ticket number in the commit summary (like "#3: Update entityclasses.xml") and the commits will be tracked on the issue page. Also, when that branch is merged to main, the ticket will be closed.
     
    If you're using GitLab, then by default, it will not just create a branch, it will also create a merge request. (See below for info about merge requests.) I don't find this useful, so I always choose the option to only create the branch. (That's also what we do where I work.)
     
    You can also create branches without tickets, if you want. In GitHub it's in the same drop-down where you select a branch, on the top left of the page when viewing the source code. I just never do this because tickets are so useful.
     
    These branches are usually called feature branches to distinguish them from the main branch.
     
    Once you've created the feature branch, you need to check out that branch on your local machine. In most Git clients, this is as simple as double-clicking on the branch name. But before you can do that, you need to fetch from the remote repo, so the local repo's index is updated, and it "knows" the branch exists. Some Git clients have a dedicated button for fetching, others use the same button you would use to pull code changes from the remote repo.
     
    Pulling, as opposed to fetching, gets the latest code changes for the branch that you have checked out. It is useful if there are code changes in an existing branch that aren't in your local repo (for example, changes in the main branch after a feature is completed).
     
    Once you are on the feature branch, do whatever code changes you need to do. You can commit periodically, and push to the remote branch, as you think appropriate. When you think the work is done, then do a final commit and push.
     
    To get the code from the feature branch into main, you should issue a pull request. In GitLab, these are called merge requests, and are basically the same thing. (GitLab also allows you to mark a merge request as "Draft," signifying that it isn't ready yet, probably because their default workflow is to create the merge request as soon as you start work.)
     
    These were designed for teams where one developer would make a change, and before that change makes it into production, all the other developers can take a look at the code. They could either approve it, or add comments that need to be addressed. In rare situations, they could reject the code changes altogether by closing the pull request without merging. GitLab and GitHub both have features related to this; for example, both allow only certain people (usually "maintainers") to merge to main, and they can name specific people that must approve the pull request.
     
    You're probably working by yourself, so you might think you don't need a pull request. But I find them very useful. It's one final set of eyes on the code, so that I don't accidentally commit something I didn't mean to, or leave in a TODO comment that should be removed, or whatever.
     
    Once approved, the branch can be merged by clicking a button on the pull request.
     
    You can also merge branches manually. In fact, you can even do away with feature branches altogether, and do all your work on the main branch. But I do not recommend this. You will end up making a mistake, and without feature branches and pull requests, that mistake will make it to "production" without getting caught.
     
    More complicated teams or software release schedules might require a more complicated Git branching model. For example, we use Gitflow at work. But that's almost certainly overkill for what most mod authors are doing.
     
    Further Reading
     
    These readings are online, and all are free.
     
  2. Here's an unusual modlet that some of you might be interested in.

     

    No Crafting

     

    Removes all crafting from the game. This includes cooking, so farming is also removed.

     

    This mod was inspired by the Lucky Looter series from Glock9.

     

    Features:

     

    • The only items the player can craft are the bedroll and land claim.
    • Removed all Basics of Survival quests except for crafting a bedroll. (After completion, players still get the skill points and Whiteriver Citizen quest.)
    • Most player-crafted workstations are removed from the game (destroyed versions are still in game). The exception is campfires, which cannot be crafted, but can be used for warmth if found in the wild.
    • Reworked perks:
      • Crafting recipes and bonuses are removed from all perks.
      • Master Chef, Living Off The Land, and Grease Monkey are removed completely.
    • Schematics, workstations, recipes, and parts for assembled weapons, tools, and vehicles are removed from loot containers, trader stashes, quest rewards, and Twitch actions.
    • Removed perk books that only give crafting recipes (e.g. Needle and Thread books). Completion bonuses that only unlock recipes (e.g. stacks of ammo) now give experience buffs instead.
    • Items or mods which could only be crafted (e.g. Fireman's Helmet) are added to loot containers and trader stashes.
    • Crafting-related loading screen tips are removed.
    • Localizations are updated to remove any mention of crafting, cooking, or forging (where possible, I'm sure I missed a lot).

     

    Repo: https://gitlab.com/karlgiesing/7d2d-a20-modlets/-/tree/main/khzmusik_No_Crafting 

    Download: https://gitlab.com/karlgiesing/7d2d-a20-modlets/-/archive/main/7d2d-a20-modlets-main.zip?path=khzmusik_No_Crafting

     

    I might make a variation of this modlet, which keeps cooking and farming in the game.

  3. 1 hour ago, Guppycur said:

    Change the faction of the horse to one that the NPCs don't attack?

     

    This is indeed the issue, but it is caused by NPC Core.

     

    Telric's horses extend "animalTemplateHostile". In vanilla, that template uses the "animals" faction, which has a "neutral" relationship to everything (including the player). However, NPC Core changes the faction of "animalTemplateHostile" to the NPC Core faction "aggressiveanimalsmedium", and that has a "hate" relationship with all non-animals except traders (including the player).

     

    When your NPCs are hired, they use your faction rather than their own. So they look at the horse's faction, see that it is hostile to their leader (you), and attack it. (They should attack if not hired as well, since all human factions have a "hate" relationship with "aggressiveanimalsmedium" too.)

     

    If you want to make the horses once again use the vanilla "animals" faction, add this XML to the horse entity classes:

    <property name="Faction" value="animals"/>

     

    You could also use one of the NPC Core animal factions, probably "passiveanimalslarge".

  4. Hey, I wanted to alert you to something. You can't install the Green Zone if you're in the middle of a game.

     

    The issue isn't with the Green Zone code itself. The issue is with NPC Core, and specifically with its new factions. Any mod that adds new factions to the game will screw up the game save.

     

    The thing players will usually notice is that they're being attacked by all the NPCs, even the "friendly" ones.

     

    I wanted to let you know, because I just had a user install this mod, and they were asking about this same issue in my thread.

     

    If you want to make a mod that is save-game safe, then you need to release a version that doesn't use NPC Core or its NPC Packs. Which is certainly do-able, but not as much fun. :) 

     

    EDIT: Also saw the notes about moving to Git. I use both GitHub and GitLab (the latter in my day job), so if you need help with any of that, feel free to message me.

  5. 2 hours ago, vonerich said:

    Apologies if this has already been asked - I installed Green Zone Quest (mod) that utilizes a few of your NPC packs. Every single NPC (civilian, raider, soldier, etc.) attacks me regardless of what I do. I found a section in your read me file (below) about resetting my reputation (this does not happen when I die in game). Could you explain this a bit more in-depth? I cannot locate the commented-out code in buffs.xml to confirm my reputation is supposed to be resetting.

     

    image.thumb.png.ee4a00c5bbd467ee63eaed6e42cf4096.png

     

    The "Reset Reputation On Death" feature is part of my Human Faction Reputation and Quests modlet, which is not part of the Green Zone Quest mod. You would need to install my modlet, and then uncomment the code in that modlet.

     

    But that probably won't solve your problem.

     

    Others have asked about that same thing happening, and in all those cases, the user didn't start a new game after installing the NPC Core mod (which is part of the Green Zone Quest mod). That won't work. You must start a new game after installing it.

     

    The tl;dr version is that adding factions to the game screws up game saves.

     

    The long version: Here's what I believe is happening.

     

    To make variable faction relationships work with individual players, TFP made it so each player has their own faction. In the game's C# code, factions are kept in an array. The faction ID of all entities, including players, is the index of their faction in this array. That faction ID is saved with the game.

     

    When the game restarts, it reloads the factions from the XML files and puts them in this array. So when factions are added to the game - as NPC Core does - new factions (like, say, "whisperers") will now be in the places where, previously, there was the ID of a player. When the game loads the player ID, the player no longer has their own faction, they're using one of the added ones.

     

    EDIT: Since you mentioned the Green Zone, I went to that thread and alerted people about it. I don't think that mod author knew about the issue. (Their own XML is save-game safe, so they probably thought NPC Core was too.)

  6. On 3/18/2023 at 6:57 PM, MarissaX said:

    Hi - This looks like a great mod so I tried it out.  I already had the NPC Mod files that you listed in my Mods folder, so I just put in the Green Zone folder and started a new game.  While loading, I got a red error message that entity.group.xml from the Green Zone mod failed.  Do you know if that will interfere with playing your mod and if so, could there be a fix for this?  I think this is the part of the log about this error (no clue what any of this stuff means other than there was an error of some sort) --

     

    2023-03-18T07:33:26 449.579 ERR XML loader: Loading XML patch file 'entitygroups.xml' from mod 'Green Zone Quest Powered by Score and NPCcore' failed:
    2023-03-18T07:33:26 449.585 EXC There are multiple root elements. Line 35, position 2.
      at System.Xml.XmlTextReaderImpl.Throw (System.Exception e) [0x00027] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlTextReaderImpl.Throw (System.String res, System.String arg) [0x00029] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlTextReaderImpl.Throw (System.Int32 pos, System.String res) [0x0000c] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlTextReaderImpl.ParseDocumentContent () [0x001e5] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlTextReaderImpl.Read () [0x0008c] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlLoader.LoadDocSequence (System.Xml.XmlDocument parentDoc) [0x0000d] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlLoader.Load (System.Xml.XmlDocument doc, System.Xml.XmlReader reader, System.Boolean preserveWhitespace) [0x000b4] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at System.Xml.XmlDocument.Load (System.Xml.XmlReader reader) [0x0002e] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at ICSharpCode.WpfDesign.XamlDom.PositionXmlDocument.Load (System.Xml.XmlReader reader) [0x0000c] in <ffc99a688d2b435db53bb46aed82ca49>:0
      at System.Xml.XmlDocument.LoadXml (System.String xml) [0x00018] in <0f9699188f0c414ea6fb5557f5c16d15>:0
      at XmlFile.toXml (System.String _data, System.String _filename, System.Boolean _throwExc) [0x0002c] in <ffc99a688d2b435db53bb46aed82ca49>:0
      at XmlFile..ctor (System.String _text, System.String _directory, System.String _filename, System.Boolean _throwExc) [0x00014] in <ffc99a688d2b435db53bb46aed82ca49>:0
      at XmlPatcher+<LoadAndPatchConfig>d__0.MoveNext () [0x001b9] in <ffc99a688d2b435db53bb46aed82ca49>:0
    UnityEngine.StackTraceUtility:ExtractStringFromException(Object)
    Log:Exception(Exception)
    <LoadAndPatchConfig>d__0:MoveNext()
    UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

     

    Either way, thanks for working on this mod.

     

    @work22 I just downloaded the mod from the Dropbox link to take a look at it. I can confirm that this error is caused by your "Green Zone Quest March 17 2023 Version 1" modlet.

     

    In entitygroups.xml, there are two <append> tags, and they're not inside a single root XML tag (like <configs> or whatever). That's malformed XML.

     

    EDIT: I also don't understand what the XPath is supposed to be doing. It's adding entities to entity groups called "GreenZoneSantaFeFemale" and "GreenZoneSantaFeMixed" but those entity groups don't exist.

     

    Also, you have a ModInfo.xml file inside the Configs folder, which does no harm but is useless (it matches the one in the modlet's root directory, which is necessary). And, the ModInfo.xml's "Name" value does not match the modlet's folder name (which I actually thought was necessary, but maybe TFP changed that).

     

    Is it possible that this is an older version of the mod? If not, those are pretty easy fixes.

  7. Since you don't want to touch the vanilla files (which is a good idea), I assume you want to use XPath in your own modlet - either the one you have now, or a new one.

     

    There are two solutions you could use:

    1. Insert the items from the other mod, into the vanilla "shamwayProduce" loot list.
    2. Change the vanilla produce basket blocks (the ones that start with "cntStoreProduceBasket") so they use a different loot group - either from the other mod, or from your own.

    I would personally go with the first option since it's easier. (But there are some limitations - see below.)

     

    Let's say the other mod had items named "foodApple", "foodGourd", "foodLettuce", and "foodMelon". Here's how you would add it to the existing, vanilla loot list.

     

    <!-- loot.xml -->
    <append xpath="//lootgroup[@name='groupShamwayProduce01']">
        <!-- Use whatever counts and probability templates you think are reasonable -->
        <item name="foodApple" count="2,4" loot_prob_template="low" />
        <item name="foodGourd" count="2,4" loot_prob_template="low" />
        <item name="foodLettuce" count="2,4" loot_prob_template="low" />
        <item name="foodMelon" count="2,4" loot_prob_template="low" />
    </append>

     

    But, remember that I said there were some limitations. And from the foods I chose, you can probably guess what it is.

     

    In vanilla, all the produce baskets use the same loot group - even though they ostensibly contained different kinds of produce. So if you want to put the other mod's foods into only some kinds of produce basket, then you're out of luck with this solution.

     

    If that doesn't bother you, then you should probably use this solution, since it's easier.

     

    If it's not what you want, you would have to go with the second solution. But instead of assigning each basket to the same loot group, you would create different loot groups for each kind of produce basket.

     

    <!--
        in loot.xml
    -->
    
    <!-- Loot groups -->
    <insertAfter xpath="//lootgroup[last()]">
        <lootgroup name="groupProduceBasketApples" count="all">
            <!-- Include the vanilla produce basket group -->
            <item group="groupShamwayProduce01" loot_prob_template="high" />
            <item name="foodApple" count="2,4" loot_prob_template="low" />
        </lootgroup>
        <lootgroup name="groupProduceBasketGourds" count="all">
            <item group="groupShamwayProduce01" loot_prob_template="high" />
            <item name="foodGourd" count="2,4" loot_prob_template="low" />
        </lootgroup>
        <lootgroup name="groupProduceBasketLettuce" count="all">
            <item group="groupShamwayProduce01" loot_prob_template="high" />
            <item name="foodLettuce" count="2,4" loot_prob_template="low" />
        </lootgroup>
        <lootgroup name="groupProduceBasketMelons" count="all">
            <item group="groupShamwayProduce01" loot_prob_template="high" />
            <item name="foodMelon" count="2,4" loot_prob_template="low" />
        </lootgroup>
    </insertAfter>
    
    <!--
        Loot containers - starting at ID 271 to not conflict with vanilla
        (but as long as they don't conflict it doesn't matter, they're not used)
    -->
    <insertAfter xpath="//lootcontainer[last()]">
        <!-- cntStoreProduceBasketApples -->
        <lootcontainer id="271" name="produceBasketApples" count="1" size="6,2" sound_open="UseActions/open_shopping_basket" sound_close="UseActions/close_shopping_basket" loot_quality_template="qualBaseTemplate">
            <item group="groupProduceBasketApples" />
        </lootcontainer>
        <!-- cntStoreProduceBasketGourds -->
        <lootcontainer id="272" name="produceBasketGourds" count="1" size="6,2" sound_open="UseActions/open_shopping_basket" sound_close="UseActions/close_shopping_basket" loot_quality_template="qualBaseTemplate">
            <item group="groupProduceBasketGourds" />
        </lootcontainer>
        <!-- cntStoreProduceBasketLettuce -->
        <lootcontainer id="273" name="produceBasketLettuce" count="1" size="6,2" sound_open="UseActions/open_shopping_basket" sound_close="UseActions/close_shopping_basket" loot_quality_template="qualBaseTemplate">
            <item group="groupProduceBasketLettuce" />
        </lootcontainer>
        <!-- cntStoreProduceBasketMelons -->
        <lootcontainer id="274" name="produceBasketMelons" count="1" size="6,2" sound_open="UseActions/open_shopping_basket" sound_close="UseActions/close_shopping_basket" loot_quality_template="qualBaseTemplate">
            <item group="groupProduceBasketMelons" />
        </lootcontainer>
    </insertAfter>
    
    <!--
        In blocks.xml
    -->
    <set xpath="//block[contains(@name, 'cntStoreProduceBasketApples')]/property[@name='LootList']/@value">produceBasketApples</set>
    <set xpath="//block[contains(@name, 'cntStoreProduceBasketGourds')]/property[@name='LootList']/@value">produceBasketGourds</set>
    <set xpath="//block[contains(@name, 'cntStoreProduceBasketLettuce')]/property[@name='LootList']/@value">produceBasketLettuce</set>
    <set xpath="//block[contains(@name, 'cntStoreProduceBasketMelons')]/property[@name='LootList']/@value">produceBasketMelons</set>

     

    That should be enough to get you going, I hope.

  8. On 1/20/2023 at 4:41 PM, Roland said:

    Soon AIs will use predictive algorithms to judge people before the crime is committed and Tom Cruise will have to sprint somewhere to save us all...

     

    Already happens.

    https://daily.jstor.org/what-happens-when-police-use-ai-to-predict-and-prevent-crime/

     

    (Sorry for the necro post, was searching for Glock9 on the forums and it brought me here. :) )

  9. 2 minutes ago, BFT2020 said:

    I personally like them separate as I have interest in a few but not all.  Like the food spoilage one, but not the gas one as I have gone a different route on that.  However, I know enough that if you were to release it as a package, I can prune the elements I don’t want.

     

    That's good to know. I figured that people who were interested in one, were probably interested in all of them. If that's not right, then I should keep them separate.

     

    As for the gas shortage - what is the other route that you went? I looked to see if there was another modlet like it, but didn't see one.

  10. New modlet added:

     

    Gas Shortage

     

    Makes gasoline scarce, and more difficult to craft.

    • Gasoline cannot be harvested from vehicles. (It can still be looted from vehicles.)
    • Each oil shale yields one can of gas (not 10).
    • Stacks of gasoline hold 1000 cans (not 10,000).

     

    ...And a question for you all:

     

    I have a few modlets that adjust the game to make the survival aspects harder and/or more "realistic." Aside from the Gas Shortage modlet, I also have the Slow Build modlet, the Bad Medicine modlet, and the Food Spoilage and Preserved Foods mod (which requires C# code).

     

    If possible, I am going to port those to A21 (whenever that comes out). When I do, should these be combined into a single "survival" mod?

     

    I could also combine only the mods that don't require C# if that would make people happier. Or I can just keep them separate, as they are now.

     

    Let me know what you think.

  11. On 3/11/2023 at 3:42 PM, Jessy said:

    Hello, I have a question about entitygroups

    What are the functions of these different groups?

     

    1/ wanderingHordeStageGS
    2/ FwanderingHordeStageGS
    3/ sleeperHordeStageGS
    4/ badassOnlyHordeStageGS
    5/ scoutHordeStageGS
    6/ feralHordeStageGS

     

    I don't know if you figured this out already, but most of this can be answered by looking in gamestages.xml.

     

    1/ and 2/ - These are used for wandering hordes. See the "WanderingHordes" spawner.

    3/ - These are some of the groups used for sleeper volumes in POIs. See the "SleeperGSList" spawner, which is used by the "S_-Group_Generic_Zombie" group.

    4/ - These are more groups used for sleeper volumes. See the "ZombieBadassOnlyHorde" spawner, which is used by the "S_-_Group_Zom_Badass_Only" group.

    5/ - These groups are used to spawn entities that respond to a screamer. See the "ScoutGSList" spawner.

    6/ - These are the groups used for blood moon hordes. See the "BloodMoonHorde" spawner.

     

    Hope that helps.

  12. I believe that you can't add textures using that mod, you can only replace textures.

     

    The reason is because the index into the texture array is kept in the block data. The number of bits used for the texture array index is not enough to reference more textures than is already in the game. So even if you add textures to the array, the block can't display them, because the index will be too large to fit.

     

    However - I'm basing this purely off of what someone in TFP said in one of the developer diaries (I think it was Faatal but don't remember for sure). Perhaps I misunderstood them, or things has changed since they said that, or maybe my memory is flat-out false.

     

    @ocbMaurice You are the author of that mod. Can you answer this? I looked at your code, but I don't have enough knowledge about the game's texture code to know the answer.

  13. @faatal Apologies, I looked back through the thread and didn't find it, but I believe you said you were working on some kind of "decal" system for things like bullet holes? Or am I imagining things?

     

    If you are - is there any chance this same technology could be used to make footprints in snow? (I've been watching playthroughs of Sons of the Forest and really like how that game does it.)

  14. The root cause is this error:

     

    Quote

    Unable to read header from archive file: C:/Users/JRVI/Desktop/7 Days To Die/7DaysToDie_Data/../Mods/1-NPCCreatures/Resources/zombieTank.unity3d

     

    It is probably caused by an incompatible version of Unity. You're using 2021.3 and the game is running on 2020.3. I personally use 2020.3.25f1 for my characters.

     

    If you try using that version of Unity, and it doesn't help, then I don't know the cause. If you figure it out, let us know here.

  15. 18 hours ago, zztong said:

     

    This kind of thing is usually handled in the "General Support" part of the forums. I think you'll find instructions there as to where to find those log files.

     

    The log file location is also in the page which is linked in the red "report a bug" banner at the top of the forums. Just in case it's easier to go there than the general support forum.

     

    Also, the general support forum isn't appropriate for modded games. If the game is modded, then here is appropriate, or in the thread started by the mod author.

     

    If you do ask here, make sure you say which mods are installed.

  16. 1 hour ago, Guppycur said:

    You can also just make "evil" copies for the bloodmoons, or find a way to disable them entirely.  That way, it appears the npc's turn viscous during the horde night.

     

    They don't even need to be "evil." "EntityEnemy" is just the name of the C# class, the entities themselves could be of any faction.

     

    For example, let's say you want to have versions of Darkstar Dragon's SoldierPack that can spawn into wandering hordes. You can create a new entity that extends the "basic" SoldierPack entity, but use the SCore "EntityEnemySDX" class. Like so:

    <entity_class name="survivorBMSoldier1RocketL" extends="survivorSoldier1RocketL">
        <!-- Tags don't extend, but everything else should -->
        <property name="Tags" value="UMA2,entity,male,npc,ranged" />
        <property name="Class" value="EntityEnemySDX, SCore" />
    </entity_class>

     

    If you're doing this with an "advanced" NPC (like the nurse) then you'll also need to change the entity class to not use any of the advanced features:

    <entity_class name="npcBMNurseClub" extends="npcNurseClub">
        <!-- Tags don't extend, but everything else should -->
        <property name="Tags" value="entity,female,npc,melee,cp,DRMid" />
        <property name="Class" value="EntityEnemySDX, SCore" />
        <!-- "Advanced" features to turn off -->
        <property name="Hirable" value="false" />
        <property name="LootListAlive" value="" />
        <property name="NPCID" value="" />
        <!-- The second AI package is determined by weapon type - see line 4240 in NPC Core entityclasses.xml -->
        <property name="AIPackages" value="NPCModBasicMeleeNoChat, NPCModNPCMeleeBasic" />
    </entity_class>

     

    I might have missed a couple properties, but you get the general idea. Those new entities will still be of the same faction, so they won't be hostile to players, but they'll still spawn into hordes.

     

    Of course... you can also make them "evil." :)  Just set their "Faction" property to "bandits" (or another hostile faction like "whisperers" - or even "undead"). Those factions are in npc.xml - "bandits" and "undead" are vanilla factions, "whisperers" is from NPC Core.

     

  17. 2 hours ago, MandyCMoore said:

    I currently have 2 7DTD series I am working on, both of which have the NPCs & all enemies on. I want to start a series that's a little different though. In this one I only want NPCs, no zombies & such. More of a situation where let's say the zombies have died off & the only threats left are the people & of course hunger & such. Is there a way to have the NPCs spawn with zombies turned off? Thanks!

     

    It can be done, but it is a long process. If you're not interested in learning how to create your own modlet, and spending a couple of days (or more) to create it, then the rest of this post probably won't interest you.

     

    It's basically a two step process:

    1. Spawn human NPCs into all the entity groups used for zombies
    2. Remove the zombies from those same entity groups

    But there are a number of catches.

     

    The first issue is hordes (blood moon hordes, wandering hordes). The horde spawner can only spawn entities that descend from the C# EntityEnemy class. If you try to spawn other entities, the game will spam red errors in the console and nothing will spawn.

     

    There are templates in NPC Core which use a custom SCore C# class that descends from EntityEnemy. But most NPC Pack authors don't use them, because that class lacks all but the most basic features. To my knowledge, my Whisperers and Rogues and Psychos packs are the only ones that do use those templates. So you would need to put only those entities into the entity groups used for hordes.

     

    This doesn't apply to the entity groups used to spawn entities into biomes, nor to the entity groups used to spawn entities into POIs. All of those should be able to support all NPCs.

     

    I don't know if this applies to "scout" spawn groups - the ones that spawn entities in response to a screamer. And that brings us to the next catch. If you want to get rid of screamers, I think that you can replace the screamer entity in the "zombieScreamer", "zombieScreamerFeral", and "zombieScreamerRadiated" entity groups with this:

    <entity name="none" />

     

    But I haven't tried it myself. It's possible that screamers are hard-coded to spawn when the heat map reaches a certain point. (Hopefully not but I don't know.)

     

    The next issue is balance. If you just add in NPCs without any probabilities, things will be completely unbalanced. You want to spawn tougher NPCs with probabilities that increase with gamestage, and weaker NPCs with probabilities that decrease with gamestage.

     

    There are a number of ways you could do this:

    • Match NPCs to vanilla zombies in terms of "difficulty," then insert the NPCs after those zombies at the same probability level (so, target probabilities containing "0.1", probabilities containing "0.2", etc.) and remove the zombies afterwards.
    • Look in my NPC packs, and copy what is there for entity groups used to spawn NPCs into NPC POIs ("npcBanditsAll", etc). For other packs I would recommend my "Progression" series of modlets (since the ones in the other NPC packs aren't gamestaged). But there are only six group stages used in NPC POIs, and vanilla uses a lot more than that (e.g. blood moons use over 300 gamestaged entity groups).
    • In each of my NPC packs (and also the "Progression" modlets), there is a "Scripts" directory, containing JavaScript files that I used to populate the entity groups. If you know how to code, you could modify those to automatically generate other entity group lists. (If you need help feel free to PM me.)

    ...Like I said, it is not easy. But if you still want to do it, I hope this helps.

  18. If anyone wants this for A20, I just finished a mod that will do it:

     

    The C# code was simple. The hard part was translating the names of POIs. I tried my best, but since I used automatic translation services, I'm sure I got a few things wrong.

     

    Even so, it should work with the English language, so hopefully folks will find it useful.

     

    EDIT: I realize that thread has a lot of mods. Here's a direct link to it on GitHub:

    modlet folder: https://gitlab.com/karlgiesing/7d2d-a20-modlets/-/tree/main/khzmusik_Localize_Prefabs

    download: https://gitlab.com/karlgiesing/7d2d-a20-modlets/-/archive/main/7d2d-a20-modlets-main.zip?path=khzmusik_Localize_Prefabs

    This should also work with custom POIs, by the way.

  19. I just added a mod that will use Localization.txt entries to display POI names for quests. It includes Localization.txt entries for all vanilla POIs that accept quests.

     

    Download the mod here:

    https://gitlab.com/karlgiesing/7d2d-a20-modlets/-/tree/main/khzmusik_Localize_Prefabs

     

    (It turns out the hardest part was translating the POI names, and I'm sure I didn't get it completely right.)

     

    It required C# changes, so must be installed on clients and servers. In theory it should be save-game safe, but you never know. You might be able to load this in an existing game, but it will be safer to start a new game.

     

    Hope this is helpful to people.

  20. On 3/2/2023 at 3:15 PM, Guppycur said:

    ...that then crashes, leaving you naked and alone on a deserted road, where you wake up with just a few supplies in your inventory... and a concussion that made you lose your memories... 😃

     

    7 Groundhog Days To Die

×
×
  • Create New...