Jump to content

Recommended Posts

Posted

I made some new bread but its crashing on the handbook. Not 100% sure why just yet, hoping someone can point it out. I assume its a one liner.

 

base game bread file:

{
	code: "bread",
	maxstacksizeByType: {
		"*-charred": 48,
		"*": 32,
	},
	variantgroups: [
		{ code: "type", states: ["spelt", "rye", "flax", "rice", "cassava", "amaranth", "sunflower" ] },
		{ code: "state", states: ["partbaked", "perfect", "charred" ] }
	],
	behaviors: [
		{ name: "GroundStorable", properties: { layout: 'Quadrants', collisionBox: { x1: 0, y1: 0, z1: 0, x2: 1, y2: 0.125, z2: 1 } } }
	],
	shape: { base: "item/food/bread/{type}bread" },
	texturesbytype: {
		"*-partbaked": { "bread": {base: "item/food/grain/{type}bread2" }},
		"*-perfect": { "bread": {base: "item/food/grain/{type}bread" }},
		"*-charred": { "bread": {base: "item/food/grain/{type}bread1" }}
	},
	creativeinventory: { "general": ["*"], "items": ["*"] },
	attributes: {
		displaycaseable: true,
		shelvable: true,
		handbook: {
			extraSections: [
				{ title: "bread-handbook-help-title", text: "bread-handbook-help-text" }
			]
		},
		bakingPropertiesByType: {
			"*-partbaked": {
				temp: 160,
				levelFrom: 0.25,
				levelTo: 0.5,
				startScaleY: 0.95,
				endScaleY: 1.10,
				resultCode: "bread-{type}-perfect",
				initialCode: "dough-{type}"
			},
			"*-perfect": {
				temp: 160,
				levelFrom: 0.5,
				levelTo: 0.75,
				startScaleY: 1.10,
				endScaleY: 1.13,
				resultCode: "bread-{type}-charred",
				initialCode: "bread-{type}-partbaked"
			},
			"*-charred": {
				temp: 160,
				levelFrom: 0.75,
				levelTo: 1,
				startScaleY: 1.13,
				endScaleY: 1.10,
				initialCode: "bread-{type}-perfect"
			}
		},
	},
	combustiblePropsByType: {
		"*-partbaked": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		},
		"*-perfect": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		}
	},
	nutritionPropsByType: {
		"*-flax-partbaked": { saturation: 70, foodcategory: "Grain" },
		"*-flax-perfect": { saturation: 160, foodcategory: "Grain" },
		"*-flax-charred": { saturation: 100, foodcategory: "Grain" },
		
		"*-rice-partbaked": { saturation: 160, foodcategory: "Grain" },
		"*-rice-perfect": { saturation: 330, foodcategory: "Grain" },
		"*-rice-charred": { saturation: 220, foodcategory: "Grain" },
		
		"*-partbaked": { saturation: 150, foodcategory: "Grain" },
		"*-perfect": { saturation: 300, foodcategory: "Grain" },
		"*-charred": { saturation: 210, foodcategory: "Grain" }
	},
	transitionablePropsByType: {
		"*-partbaked":  [{
			type: "Perish",
			freshHours: { avg: 120 },
			transitionHours: { avg: 24 },
			transitionedStack: { type: "item", code: "rot" },
			transitionRatio: 1
		}],
		"*-perfect":  [{
			type: "Perish",
			freshHours: { avg: 192 },
			transitionHours: { avg: 36 },
			transitionedStack: { type: "item", code: "rot" },
			transitionRatio: 1
		}],
		"*-charred":  [{
			type: "Perish",
			freshHours: { avg: 420 },
			transitionHours: { avg: 60 },
			transitionedStack: { type: "item", code: "rot" },
			transitionRatio: 1
		}]
	},
	materialDensity: 200,
	guiTransform: {
		translation: { x: 0, y: 0, z: 0 },
		rotation: { x: -30, y: 26, z: 180 },
		origin: { x: 0.52, y: 0.07, z: 0.5 },
		scale: 4.9
	},
	groundTransform: {
		translation: { x: 0, y: 0, z: 0 },
		rotation: { x: 0, y: 0, z: 1 },
		origin: { x: 0.5, y: 0, z: 0.5 },
		scale: 4.5
	},
	tpHandTransform: {
		translation: { x: -0.54, y: -0.16, z: -0.4 },
		rotation: { x: 88, y: -85, z: 2 },
		origin: { x: 0.5, y: 0.13, z: 0.5 },
		scale: 1
	},
	fpHandTransform: {
		translation: { x: 0, y: 0.24, z: 0.3 },
		rotation: { x: 104, y: 0, z: 71 },
		origin: { x: 0.5, y: 0.1, z: 0.5 },
		scale: 2.5
	}
}

 

 

My code:

{
	code: "craftsmanship:bread",
	maxstacksizeByType: {
		"*-charred": 48,
		"*": 32
	},
	variantgroups: [
		{ code: "type", states: ["corn", "wheat", "wholegrain", "white", "sour-dough", "tortilla" ] },
		{ code: "state", states: ["partbaked", "perfect", "charred" ] }
	],
	behaviors: [
		{ name: "GroundStorable", properties: { layout: 'Quadrants', collisionBox: { x1: 0, y1: 0, z1: 0, x2: 1, y2: 0.125, z2: 1 } } }
	],
	shapeByType: { 
		"*corn*": 
		{ 
			base: "block/food/bread/generic/bread" 
		}, 
		"*wheat*": 
		{ 
			base: "block/food/bread/generic/bread" 
		},
		"*wholegrain*": 
		{ 
			base: "block/food/bread/generic/bread" 
		},
		"*white*": 
		{ 
			base: "block/food/bread/generic/bread" 
		},
		"*sour-dough*": 
		{ 
			base: "block/food/bread/{type}/bread" 
		},
		"*tortilla*": 
		{ 
			base: "block/food/bread/{type}/bread" 
		}
	},
	texturesbytype: {
		"*corn-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*corn-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*corn-charred": { "bread": {base: "item/food/bread/{type}/charred" }},

		"*wheat-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*wheat-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*wheat-charred": { "bread": {base: "item/food/bread/{type}/charred" }},

		"*wholegrain-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*wholegrain-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*wholegrain-charred": { "bread": {base: "item/food/bread/{type}/charred" }},

		"*white-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*white-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*white-charred": { "bread": {base: "item/food/bread/{type}/charred" }},

		"*sour-dough-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*sour-dough-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*sour-dough-charred": { "bread": {base: "item/food/bread/{type}/charred" }},

		"*tortilla-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*tortilla-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*tortilla-charred": { "bread": {base: "item/food/bread/{type}/charred" }},		
		
		"*-partbaked": { "bread": {base: "item/food/bread/{type}/partbaked" }},
		"*-perfect": { "bread": {base: "item/food/bread/{type}/perfect" }},
		"*-charred": { "bread": {base: "item/food/bread/{type}/charred" }}
	},
	creativeinventory: { "general": ["*"], "items": ["*"] },
	attributes: {
		displaycaseable: true,
		shelvable: true,
		handbook: {
			extraSections: [
				{ title: "bread-handbook-help-title", text: "bread-handbook-help-text" }
			]
		},
		bakingPropertiesByType: {
			"*-partbaked": {
				temp: 160,
				levelFrom: 0.25,
				levelTo: 0.5,
				startScaleY: 0.95,
				endScaleY: 1.10,
				resultCode: "bread-{type}-perfect",
				initialCode: "dough-{type}"
			},
			"*-perfect": {
				temp: 160,
				levelFrom: 0.5,
				levelTo: 0.75,
				startScaleY: 1.10,
				endScaleY: 1.13,
				resultCode: "bread-{type}-charred",
				initialCode: "bread-{type}-partbaked"
			},
			"*-charred": {
				temp: 160,
				levelFrom: 0.75,
				levelTo: 1,
				startScaleY: 1.13,
				endScaleY: 1.10,
				initialCode: "bread-{type}-perfect"
			}
		},
	},
	combustiblePropsByType: {
		"*-partbaked": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		},
		"*-perfect": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		}
	},
	nutritionPropsByType: {
		"*-corn-partbaked": { saturation: 130, foodcategory: "Grain" },
		"*-corn-perfect": { saturation: 280, foodcategory: "Grain" },
		"*-corn-charred": { saturation: 210, foodcategory: "Grain" },

		"*-wheat-partbaked": { saturation: 150, foodcategory: "Grain" },
		"*-wheat-perfect": { saturation: 400, foodcategory: "Grain" },
		"*-wheat-charred": { saturation: 300, foodcategory: "Grain" },

		"*-wholegrain-partbaked": { saturation: 180, foodcategory: "Grain" },
		"*-wholegrain-perfect": { saturation: 350, foodcategory: "Grain" },
		"*-wholegrain-charred": { saturation: 220, foodcategory: "Grain" },

		"*-white-partbaked": { saturation: 145, foodcategory: "Grain" },
		"*-white-perfect": { saturation: 300, foodcategory: "Grain" },
		"*-white-charred": { saturation: 215, foodcategory: "Grain" },

		"*-sour-dough-partbaked": { saturation: 200, foodcategory: "Grain" },
		"*-sour-dough-perfect": { saturation: 325, foodcategory: "Grain" },
		"*-sour-dough-charred": { saturation: 240, foodcategory: "Grain" },

		"*-tortilla-partbaked": { saturation: 150, foodcategory: "Grain" },
		"*-tortilla-perfect": { saturation: 310, foodcategory: "Grain" },
		"*-tortilla-charred": { saturation: 220, foodcategory: "Grain" },
		
		"*-partbaked": { saturation: 150, foodcategory: "Grain" },
		"*-perfect": { saturation: 300, foodcategory: "Grain" },
		"*-charred": { saturation: 210, foodcategory: "Grain" }
	},
	transitionablePropsByType: {
		"*-partbaked":  [{
			type: "Perish",
			freshHours: { avg: 120 },
			transitionHours: { avg: 24 },
			transitionedStack: { type: "item", code: "game:rot" },
			transitionRatio: 1
		}],
		"*-perfect":  [{
			type: "Perish",
			freshHours: { avg: 192 },
			transitionHours: { avg: 36 },
			transitionedStack: { type: "item", code: "game:rot" },
			transitionRatio: 1
		}],
		"*-charred":  [{
			type: "Perish",
			freshHours: { avg: 420 },
			transitionHours: { avg: 60 },
			transitionedStack: { type: "item", code: "game:rot" },
			transitionRatio: 1
		}]
	},
	materialDensity: 200,
	guiTransform: {
		translation: { x: 0, y: 0, z: 0 },
		rotation: { x: -30, y: 26, z: 180 },
		origin: { x: 0.52, y: 0.07, z: 0.5 },
		scale: 4.9
	},
	groundTransform: {
		translation: { x: 0, y: 0, z: 0 },
		rotation: { x: 0, y: 0, z: 1 },
		origin: { x: 0.5, y: 0, z: 0.5 },
		scale: 4.5
	},
	tpHandTransform: {
		translation: { x: -0.54, y: -0.16, z: -0.4 },
		rotation: { x: 88, y: -85, z: 2 },
		origin: { x: 0.5, y: 0.13, z: 0.5 },
		scale: 1
	},
	fpHandTransform: {
		translation: { x: 0, y: 0.24, z: 0.3 },
		rotation: { x: 104, y: 0, z: 71 },
		origin: { x: 0.5, y: 0.1, z: 0.5 },
		scale: 2.5
	}
}

I think the issue is in here but base game has same code so im not 100%:

combustiblePropsByType: {
		"*-partbaked": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		},
		"*-perfect": {
			meltingPoint: 200,
			meltingDuration: 15,
			smeltedRatio: 1,
			smeltingType: "bake",
			smeltedStack: { type: "item", code: "bread-{type}-charred" },
			requiresContainer: false
		}
	},

Attributes also feels suspect since its happening in the handbook only:

attributes: {
		displaycaseable: true,
		shelvable: true,
		handbook: {
			extraSections: [
				{ title: "bread-handbook-help-title", text: "bread-handbook-help-text" }
			]
		},
		bakingPropertiesByType: {
			"*-partbaked": {
				temp: 160,
				levelFrom: 0.25,
				levelTo: 0.5,
				startScaleY: 0.95,
				endScaleY: 1.10,
				resultCode: "bread-{type}-perfect",
				initialCode: "dough-{type}"
			},
			"*-perfect": {
				temp: 160,
				levelFrom: 0.5,
				levelTo: 0.75,
				startScaleY: 1.10,
				endScaleY: 1.13,
				resultCode: "bread-{type}-charred",
				initialCode: "bread-{type}-partbaked"
			},
			"*-charred": {
				temp: 160,
				levelFrom: 0.75,
				levelTo: 1,
				startScaleY: 1.13,
				endScaleY: 1.10,
				initialCode: "bread-{type}-perfect"
			}
		},
	},

Error log:

Running on 64 bit Linux (Linux Mint 22.1) [Kernel 6.8.0.90] with 31965 MB RAM
Game Version: v1.21.6 (Stable)
1/3/2026 9:17:10 PM: Critical error occurred
Loaded Mods: craftsmanship@1.0.0, game@1.21.6, creative@1.21.6, survival@1.21.6
System.Exception: Can't create itemstack without collectible!
   at Vintagestory.API.Common.ItemStack..ctor(CollectibleObject collectible, Int32 stacksize) in VintagestoryApi\Common\Collectible\ItemStack.cs:line 200
   at Vintagestory.GameContent.CollectibleBehaviorHandbookTextAndExtraInfo.addCreatedByInfo(ICoreClientAPI capi, ItemStack[] allStacks, ActionConsumable`1 openDetailPageFor, ItemStack stack, List`1 components, Single marginTop, List`1 containers, List`1 fuels, List`1 molds, Boolean haveText) in VSSurvivalMod\Systems\Handbook\CollectibleBehaviorHandbookTextAndExtraInfo.cs:line 1922
   at Vintagestory.GameContent.CollectibleBehaviorHandbookTextAndExtraInfo.GetHandbookInfo(ItemSlot inSlot, ICoreClientAPI capi, ItemStack[] allStacks, ActionConsumable`1 openDetailPageFor) in VSSurvivalMod\Systems\Handbook\CollectibleBehaviorHandbookTextAndExtraInfo.cs:line 109
   at Vintagestory.GameContent.GuiHandbookItemStackPage.GetPageText(ICoreClientAPI capi, ItemStack[] allStacks, ActionConsumable`1 openDetailPageFor) in VSSurvivalMod\Systems\Handbook\Gui\GuiHandbookItemStackPage.cs:line 119
   at Vintagestory.GameContent.GuiHandbookItemStackPage.ComposePage(GuiComposer detailViewGui, ElementBounds textBounds, ItemStack[] allstacks, ActionConsumable`1 openDetailPageFor) in VSSurvivalMod\Systems\Handbook\Gui\GuiHandbookItemStackPage.cs:line 113
   at Vintagestory.GameContent.ModSystemSurvivalHandbook.onComposePage(GuiHandbookPage page, GuiComposer detailViewGui, ElementBounds textBounds, ActionConsumable`1 openDetailPageFor) in VSSurvivalMod\Systems\Handbook\SurvivalHandbook.cs:line 128
   at Vintagestory.GameContent.GuiDialogHandbook.initDetailGui() in VSSurvivalMod\Systems\Handbook\Gui\GuiDialogHandbook.cs:line 258
   at Vintagestory.GameContent.GuiDialogHandbook.onLeftClickListElement(Int32 index) in VSSurvivalMod\Systems\Handbook\Gui\GuiDialogHandbook.cs:line 348
   at Vintagestory.GameContent.GuiElementFlatList.OnMouseUpOnElement(ICoreClientAPI api, MouseEvent args) in VSSurvivalMod\Systems\Handbook\Gui\GuiElementFlatList.cs:line 95
   at Vintagestory.GameContent.GuiElementFlatList.OnMouseUp(ICoreClientAPI api, MouseEvent args) in VSSurvivalMod\Systems\Handbook\Gui\GuiElementFlatList.cs:line 174
   at Vintagestory.API.Client.GuiComposer.OnMouseUp(MouseEvent mouse) in VintagestoryApi\Client\UI\GuiComposer.cs:line 448
   at Vintagestory.API.Client.GuiDialog.OnMouseUp(MouseEvent args) in VintagestoryApi\Client\UI\Dialog\GuiDialog.cs:line 593
   at Vintagestory.Client.NoObf.GuiManager.OnMouseUp(MouseEvent args) in VintagestoryLib\Client\Systems\Gui\GuiManager.cs:line 423
   at Vintagestory.Client.NoObf.ClientMain.UpdateMouseButtonState(EnumMouseButton button, Boolean down) in VintagestoryLib\Client\ClientMain.cs:line 1996
   at Vintagestory.Client.HotkeyManager.TriggerHotKey(KeyEvent keyEventargs, IWorldAccessor world, IPlayer player, Boolean allowCharacterControls, Boolean isGlobal, Boolean fallBack, Boolean keyup) in VintagestoryLib\Client\HotkeyManager.cs:line 403
   at Vintagestory.Client.HotkeyManager.TriggerHotKey(KeyEvent keyEventargs, IWorldAccessor world, IPlayer player, Boolean allowCharacterControls, Boolean keyUp) in VintagestoryLib\Client\HotkeyManager.cs:line 394
   at Vintagestory.Client.HotkeyManager.OnMouseButton(ClientMain game, EnumMouseButton button, Int32 modifiers, Boolean buttonDown) in VintagestoryLib\Client\HotkeyManager.cs:line 574
   at Vintagestory.Client.NoObf.ClientMain.OnMouseUpRaw(MouseEvent args) in VintagestoryLib\Client\ClientMain.cs:line 2026
   at Vintagestory.Client.GuiScreenRunningGame.OnMouseUp(MouseEvent args) in VintagestoryLib\Client\MainMenu\Screens\GuiScreenRunningGame.cs:line 359
   at Vintagestory.Client.ScreenManager.OnMouseUp(MouseEvent e) in VintagestoryLib\Client\ScreenManager.cs:line 921
   at Vintagestory.Client.NoObf.ClientPlatformWindows.Mouse_ButtonUp(MouseButtonEventArgs e) in VintagestoryLib\Client\ClientPlatform\Input.cs:line 213
   at OpenTK.Windowing.Desktop.NativeWindow.OnMouseUp(MouseButtonEventArgs e)
   at OpenTK.Windowing.Desktop.NativeWindow.MouseButtonCallback(Window* window, MouseButton button, InputAction action, KeyModifiers mods)
--- End of stack trace from previous location ---
   at OpenTK.Windowing.Desktop.NativeWindow.RethrowCallbackExceptionsIfNeeded()
   at OpenTK.Windowing.Desktop.GameWindow.Run()
   at Vintagestory.Client.ClientProgram.Start(ClientProgramArgs args, String[] rawArgs) in VintagestoryLib\Client\ClientProgram.cs:line 347
   at Vintagestory.Client.ClientProgram.<>c__DisplayClass10_0.<.ctor>b__1() in VintagestoryLib\Client\ClientProgram.cs:line 131
   at Vintagestory.ClientNative.CrashReporter.Start(ThreadStart start) in VintagestoryLib\Client\ClientPlatform\ClientNative\CrashReporter.cs:line 95

 

  • Solution
Posted
On 1/4/2026 at 4:17 AM, Micah Holmes said:
bakingPropertiesByType: {
			"*-partbaked": {
				temp: 160,
				levelFrom: 0.25,
				levelTo: 0.5,
				startScaleY: 0.95,
				endScaleY: 1.10,
				resultCode: "bread-{type}-perfect",
				initialCode: "dough-{type}"
			},
			"*-perfect": {
				temp: 160,
				levelFrom: 0.5,
				levelTo: 0.75,
				startScaleY: 1.10,
				endScaleY: 1.13,
				resultCode: "bread-{type}-charred",
				initialCode: "bread-{type}-partbaked"
			},
			"*-charred": {
				temp: 160,
				levelFrom: 0.75,
				levelTo: 1,
				startScaleY: 1.13,
				endScaleY: 1.10,
				initialCode: "bread-{type}-perfect"
			}
		},

It's because of the attributes yes, the game automatically generally adds your domain as a default when loading an `AssetLocation` field... problem being that the attributes are not loaded as `AssetLocation` but as a `JsonObject` and then later read by other code which often does not do this, like in this case.

You should be able to fix the error by prepending `craftsmanship:` to your `initialCode` and `resultCode`.
(I don't have your `dough` itemtype so I can't test that)
 

  • Thanks 1
×
×
  • Create New...

Important Information

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