Help needed with adding a new helmet to the game

Started by Daros, May 27, 2017, 11:11:17 AM

Previous topic - Next topic

Daros

I'm trying to add a new helmet to the game, but I've ran into couple of problems.

With the mod enabled, I get an error I can't understand. The error code is pastied at the end of this message.

This is the first time I've ever tried any modding. To understand how to add the item in the first place, I looked at the files of a mod I had downloaded from Steam Workshop, deleted all the extras and modifed the ones I thought I'd need for my mod to work. This error is probably leftover from it..?

That is, the helmet graphics show up in-game and that part works as intended, but other than that, I've no idea what I'm doing..

Second, I can barely understand all the codetalk, so how would I go about adding the helmet to be craftable in-game from Machining Table?
If anyone is able to help me out, I would appreciate it.


Error:
RimWorld 0.17.1546 rev887
Verse.Log:Message(String)
RimWorld.VersionControl:LogVersionNumber()
Verse.Root:CheckGlobalInit()
Verse.Root:Start()
Verse.Root_Entry:Start()

Could not resolve cross-reference to Verse.ThingDef named
Verse.Log:Error(String)
Verse.DirectXmlCrossRefLoader:TryResolveDef(String, FailMode)
Verse.WantedRefForList`1:TryResolve(FailMode)
Verse.DirectXmlCrossRefLoader:ResolveAllWantedCrossReferences(FailMode)
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Cannot call ItemFromXmlFile with resolveCrossRefs=true while loading is already in progress.
Verse.Log:Error(String)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
RimWorld.PlayerKnowledgeDatabase:ReloadAndRebind()
RimWorld.PlayerKnowledgeDatabase:.cctor()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Could not resolve cross-reference to Verse.ThingDef named
Verse.Log:Error(String)
Verse.DirectXmlCrossRefLoader:TryResolveDef(String, FailMode)
Verse.WantedRefForList`1:TryResolve(FailMode)
Verse.DirectXmlCrossRefLoader:ResolveAllWantedCrossReferences(FailMode)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
RimWorld.PlayerKnowledgeDatabase:ReloadAndRebind()
RimWorld.PlayerKnowledgeDatabase:.cctor()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Cannot call ItemFromXmlFile with resolveCrossRefs=true while loading is already in progress.
Verse.Log:Error(String)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
RimWorld.PlayerKnowledgeDatabase:ReloadAndRebind()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Could not resolve cross-reference to Verse.ThingDef named
Verse.Log:Error(String)
Verse.DirectXmlCrossRefLoader:TryResolveDef(String, FailMode)
Verse.WantedRefForList`1:TryResolve(FailMode)
Verse.DirectXmlCrossRefLoader:ResolveAllWantedCrossReferences(FailMode)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
RimWorld.PlayerKnowledgeDatabase:ReloadAndRebind()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Cannot call ItemFromXmlFile with resolveCrossRefs=true while loading is already in progress.
Verse.Log:Error(String)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
Verse.KeyPrefs:Init()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

Could not resolve cross-reference to Verse.ThingDef named
Verse.Log:Error(String)
Verse.DirectXmlCrossRefLoader:TryResolveDef(String, FailMode)
Verse.WantedRefForList`1:TryResolve(FailMode)
Verse.DirectXmlCrossRefLoader:ResolveAllWantedCrossReferences(FailMode)
Verse.DirectXmlLoader:ItemFromXmlFile(String, Boolean)
Verse.KeyPrefs:Init()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__853()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__851()

jamaicancastle

Actually, by happenstance, your two questions both deal with the same code. The relevant line is in your Apparel_RS.xml file. Lines 26-32 run as follows:

    <recipeMaker>
      <unfinishedThingDef>UnfinishedTechArmor</unfinishedThingDef>
      <researchPrerequisite></researchPrerequisite>
      <recipeUsers>
        <li></li>
      </recipeUsers>
    </recipeMaker>


This block is used by the recipe maker, a piece of code that automatically creates recipes according to certain patterns. What this means is that rather than have to manually code a recipe for each item, and then assign it to a workbench, you can feed the recipe maker some data and it will generate the recipe for you when the game is launched.

Lines 29-31 are the "recipe users", the workbench(es) that you want to use to create the item. Because you could have one or more of them, this is implemented as a list. In XML, open-ended lists use <li></li> (for "list item") to mark the members of lists. For instance, in the core "shiv" melee weapon, that section looks like this:
  <recipeUsers>
    <li>ElectricSmithy</li>
    <li>FueledSmithy</li>
    <li>CraftingSpot</li>
  </recipeUsers>

This means that the recipe is added to the fueled smithy, the electric smithy, and the crafting spot. It could also be added to just one table; alternatively, it could list every crafting table in the game if you really wanted it to.

However, your code has just <li></li>, where you removed the previous table. Because of this, it still thinks that you're trying to attach the recipe to a table, and furthermore that the name of that table should be blank. Obligingly, it goes off to find a thingDef with a blank name and can't find one. This is what produces this error:
Could not resolve cross-reference to Verse.ThingDef named

Normally, that error would look like this:
Could not resolve cross-reference to Verse.ThingDef named UnfindableThingDef'sName
which is easier to track down, but here it put in a blank because that was the name it was looking for.

By the same token, in line 28, the empty researchPrerequisite tag is looking for a research project with no name.

The recipe maker block should look like this:
    <recipeMaker>
      <unfinishedThingDef>UnfinishedTechArmor</unfinishedThingDef>
      <researchPrerequisite>MilitaryHelmets</researchPrerequisite>
      <recipeUsers>
        <li>TableMachining</li>
      </recipeUsers>
    </recipeMaker>

If you don't want the helmet to have a research prerequisite, delete that line entirely, including both tags.

Daros

Thank you!

You linked the code of the vanilla shiv. Where can I find the vanilla tables myself? I think looking those over might give me a bit more insight.

jamaicancastle

All of the vanilla XML can be found in Steam/SteamApps/common/Rimworld/Mods/Core/Defs

Work tables specifically are in /ThingDefs_Buildings/Building_Production.xml
Helmets, if you're curious, are in /ThingsDefs_Misc (not ThingDefsItems for reasons unknown to me), in Apparel_Hats.xml

Daros

#4
EDIT: Alright, so I got the helmets working as I wanted, thank you for the help.

A question if you could help though. I tried a test to see if I could manage to add armors as well. I copied some armor textures from another mod and tried to add the necessary parameters to get it to work. However, when I try to add the armor in Prepare Carefully, it says it cannot find textures?

In-game, it looks like its just a pink square. I found another forum post from a year or two ago who had the same problem. (https://ludeon.com/forums/index.php?topic=27477.0)

In there it was explained that  "adding the acking abstract/base (armormakeable_base): NEW FILES added : apparel_base.xml" solved the issue. What exactly is this? I couldn't find anything like this from the base mod I tried to use as a guide.

Thank you if anyone is able to help, appreciated.

jamaicancastle

You shouldn't need any special bases or abstracts or anything, just use the default ApparelMakeableBase. I haven't tried adding armor per se, but I did mod in some extra shirts and it worked fine.

From reading the other thread, I think the problem was in the layers tag. This determines both how the item is drawn and where it fits in inventory. For armor, you would normally want the Shell layer. For helmets, you need the Overhead layer. In the code as written, trying to do both is not allowed (which is why the default power armor has a separate helmet).

The other thing I would suggest is to make sure you included all 15 textures you need for the armor, and that it's pointing to the right folder. (Note that this is controlled by the WornGraphicPath tag, not the ordinary graphicData, which is only used for the item when not worn.)

Daros

#6
Thank you for the reply and time taken to help.

I tried to add the armor just by using default values, as you suggested. However, the problem still persists. The graphics for when the item is on the ground work as normal, however, as soon as it is equipped by anyone, no matter the gender or shape, it gives an error and a pink square.

The armor graphics are taken from another mod, so it should include all of them. And the ThingDefs should also be almost the same, except some stats have been changed. So I really cannot understand why it doesn't work..

If you could take a look, I'd appreciate it a ton...

EDIT: Removed mod from the dropbox for now.

This is the error code:
Failed to find any texture while constructing Multi(initPath=Things/Apparel/PowerArmorA_Male, color=RGBA(0.627, 0.698, 0.710, 1.000), colorTwo=RGBA(1.000, 1.000, 1.000, 1.000))
Verse.Log:Error(String)
Verse.Graphic_Multi:Init(GraphicRequest)
Verse.GraphicDatabase:GetInner(GraphicRequest)
Verse.GraphicDatabase:Get(String, Shader, Vector2, Color)
RimWorld.ApparelGraphicRecordGetter:TryGetGraphicApparel(Apparel, BodyType, ApparelGraphicRecord&)
Verse.PawnGraphicSet:ResolveApparelGraphics()
RimWorld.Pawn_ApparelTracker:<ApparelChanged>m__34A()
Verse.LongEventHandler:ExecuteToExecuteWhenFinished()
Verse.LongEventHandler:ExecuteWhenFinished(Action)
RimWorld.Pawn_ApparelTracker:ApparelChanged()
RimWorld.Pawn_ApparelTracker:Notify_ApparelAdded(Apparel)
Verse.ThingOwner:NotifyAdded(Thing)
Verse.ThingOwner`1:TryAdd(Thing, Boolean)
RimWorld.Pawn_ApparelTracker:Wear(Apparel, Boolean)
RimWorld.<MakeNewToils>c__Iterator54:<>m__111()
Verse.AI.JobDriver:TryActuallyStartNextToil()
Verse.AI.JobDriver:ReadyForNextToil()
Verse.AI.JobDriver:DriverTick()
Verse.AI.Pawn_JobTracker:JobTrackerTick()
Verse.Pawn:Tick()
Verse.TickList:Tick()
Verse.TickManager:DoSingleTick()
Verse.TickManager:TickManagerUpdate()
Verse.Game:UpdatePlay()
Verse.Root_Play:Update()


This is the ThingDef code for the armor:    <ThingDef ParentName="ArmorMakeableBase">
    <defName>Apparel_PowerArmorA</defName>
    <label>A1 Power Armor</label>
    <description>Designated paramilitary armor A1-B2 Ranger Power Armor. Offers extreme protection against the hostiles and enviroment.</description>
    <techLevel>Spacer</techLevel>
    <recipeMaker>
      <recipeUsers>
        <li>TableMachining</li>
      </recipeUsers>
      <unfinishedThingDef>UnfinishedTechArmor</unfinishedThingDef>
      <researchPrerequisite>PoweredArmor</researchPrerequisite>
    </recipeMaker>
    <graphicData>
      <texPath>Things/Apparel/PowerArmorA</texPath>
      <graphicClass>Graphic_Single</graphicClass>
    </graphicData>
<stuffCategories>
<li>Metallic</li>
</stuffCategories>
    <statBases>
      <WorkToMake>32500</WorkToMake>
      <MaxHitPoints>450</MaxHitPoints>
      <MarketValue>3200</MarketValue>
      <Mass>15</Mass>
      <ArmorRating_Blunt>0.63</ArmorRating_Blunt>
      <ArmorRating_Sharp>0.70</ArmorRating_Sharp>
      <ArmorRating_Heat>0.45</ArmorRating_Heat>
  <ArmorRating_Electric>0.33</ArmorRating_Electric>
      <Insulation_Cold>-30</Insulation_Cold>
  <Insulation_Heat>30</Insulation_Heat>
    </statBases>
    <equippedStatOffsets>
<MoveSpeed>0.05</MoveSpeed>
<WorkSpeedGlobal>0.05</WorkSpeedGlobal>
<MiningSpeed>0.15</MiningSpeed>
<ToxicSensitivity>-0.33</ToxicSensitivity>
<Comfort>0.1</Comfort>
    </equippedStatOffsets>
    <thingCategories>
      <li>Apparel</li>
    </thingCategories>
<costStuffCount>50</costStuffCount>
    <costList>
      <Steel>150</Steel>
      <Component>10</Component>
      <Plasteel>50</Plasteel>
    </costList>
    <generateCommonality>0.2</generateCommonality>
    <apparel>
      <bodyPartGroups>
        <li>Torso</li>
        <li>Shoulders</li>
        <li>Arms</li>
        <li>Legs</li>
      </bodyPartGroups>
      <worngraphicPath>Things/Apparel/PowerArmorA</worngraphicPath>
      <layers>
        <li>Middle</li>
        <li>Shell</li>
      </layers>
      <tags>
        <li>Military</li>
      </tags>
      <defaultOutfitTags>
        <li>Soldier</li>
      </defaultOutfitTags>
    </apparel>
  </ThingDef>


I can't figure out for the life of me what's wrong with it. As far as I can tell, it should be correct. What causes the pink square and failure to load the texture? Given that the helmet works just fine..

Imgur picture for the pink square: http://imgur.com/a/EPnKh

kaptain_kavern

#7
From my personal experience you have to be extra cautious with capitalization when playing with textures. Check your path and filenames in your XML files AND the name and path of the files themselves as well.

Apparel_back.png is good, but Apparel_Back.png will throw errors for instance.
I took this example because it's what I'm suspecting as you said the pink square only show when worn

I'm on my phone right now, but I will look at your files later today

kaptain_kavern

#8
Bingo ! It was that.

I just renamed some files and folders and everything is working. I haven't have to change code !

Et voila!





You have another error related to the unfinished items for the armor
<unfinishedThingDef>UnfinishedTechArmor</unfinishedThingDef>

Either you change it for one of the vanilla ones, or you'll have to add a modded unfinished Tech Armor

jamaicancastle

Quote from: kaptain_kavern on May 29, 2017, 09:44:50 PMI just renamed some files and folders and everything is working. I haven't have to change code !
That would explain it then. The worngraphicpath:
      <worngraphicPath>Things/Apparel/PowerArmorA</worngraphicPath>
has subfolders in it: Textures -> Things -> Apparel -> all the different power armor files

Therefore, your mod structure needs to have the same folder structure. So you'll want to either duplicate the folder structure it describes in the path in your actual textures folder, or change the path to point to where your files are in the actual folder, if that makes sense.

Quote from: kaptain_kavern on May 29, 2017, 09:44:50 PMYou have another error related to the unfinished items for the armor
<unfinishedThingDef>UnfinishedTechArmor</unfinishedThingDef>

Either you change it for one of the vanilla ones, or you'll have to add a modded unfinished Tech Armor
Is it actually throwing an error for you? UnfinishedTechArmor is one of the core unfinished item defs, it's used by the power armor components if I understand correctly.

Daros

Oooh, thank you! They finally work! To be honest, I don't think I would've realised what the correct format was, never thought it was case sensititive.
Thanks bunches!

kaptain_kavern

in order to catch the right format and all, I used this, the pack with all vanilla textures and I compared with how powerArmor was done.

Quote from: jamaicancastle on May 30, 2017, 12:44:57 AM
Is it actually throwing an error for you? UnfinishedTechArmor is one of the core unfinished item defs, it's used by the power armor components if I understand correctly.

Correct. I must have messed up some of my vanilla files again .....  Thx for letting me know ;)