Caves of Qud

Caves of Qud

More Modding Goodies!
 This topic has been pinned, so it's probably important
Tyrir  [developer] 9 Mar @ 6:06pm
Documentation
This thread contains additional documentation and code examples.
Last edited by Tyrir; 9 Mar @ 6:29pm
< >
Showing 1-4 of 4 comments
Tyrir  [developer] 9 Mar @ 6:08pm 
How To Add More Modding Goodies as a Dependency
  1. Make this mod a dependency on your mod's workshop item page in steam. Under the Owner Controls panel on the right, click Add/Remove Required Items. Add this mod to your mod's list so that steam will install it along with your mod when your users subscribe.

  2. Add this mod as a dependency to your mod's manifest.json:
    { "ID": "MyMod", "Title": "My Mod", "Dependencies": { "moremoddinggoodies": ">=1.4.0" } }
Last edited by Tyrir; 9 Mar @ 6:12pm
Tyrir  [developer] 9 Mar @ 6:09pm 
[RequiredGameSystem] Attribute
using tyrir.lib; [tyrir.lib.RequiredGameSystem] [HasModSensitiveStaticCache] [HasOptionFlagUpdate] public class MyMod : IScribedSystem { static int MyIntOption; [OptionFlagUpdate] public static void OnOptionFlagUpdate() { MoreOptions.TryParseOption("OptionMyIntOpt", out MyIntOption, defaultValue: 5); MoreOutput.Debug("my option is now " + MyIntOption); } [ModSensitiveCacheInit] public static void OnModSensitiveCacheInit() { MoreOutput.LoadAndDisplayMessage("Initializing...", Init); } public static void Init() { // do slow, static initialization stuff here e.g. parsing files } public void OnGameStart(GameObject player, bool isNewGame, bool isInitialGameSystemCreation) { // [tyrir.lib.RequiredGameSystem] will automatically construct MyMod at game start/load. // do non-static initialization here e.g. adding IParts to player } }
Tyrir  [developer] 9 Mar @ 6:10pm 
Events
using tyrir.lib; public class MySkill : ScribedBaseSkill , IModEventHandler<GetIsSkilledWithMissileWeaponEvent> { public override bool WantEvent(int ID, int cascade) { return ID == GetIsSkilledWithMissileWeaponEvent.ID || base.WantEvent(ID, cascade); } public bool HandleEvent(GetIsSkilledWithMissileWeaponEvent E) { if (E.Actor == ParentObject && E.MissileWeapon.Skill == "MySkill") E.IsSkilled = true; return base.HandleEvent(E); } }
Last edited by Tyrir; 26 Apr @ 3:38am
Tyrir  [developer] 29 Apr @ 11:33am 
MoreCrafting: Crafting Made Easy
MoreCrafting is an XML-based system that lets you define custom interactions on GameObjects, with no C# scripting required. Want to let players "make furniture" at a workbench? Or "coat a weapon" in poison? MoreCrafting makes that easy.

Overview
MoreCrafting is designed to let modders add crafting and other custom actions to objects without writing scripts. It supports defining recipes with customizable ingredients and products, conditional action availability based on game context or player state (such as skills, stats, proximity, and more), dynamic content from population tables, and it provides basic, menu-based player UIs for crafting recipe/ingredient selection. While focused on crafting, it's flexible enough to support a wide range of object interactions, including scripted effects, or utility actions for modding or debugging.

Key Features
  • XML defined interactions: Add named actions (e.g. "make arrows") to GameObjects.
  • Familiar user experience: Actions and their hotkeys appear in the existing action menus that appear when clicking on or interacting with objects.
  • Flexible targeting: Apply actions to a specific blueprint, a list of blueprints, or blueprint hierarchies e.g. to all walls.
  • Dynamic visibility: Show/hide actions or recipes based on player state (e.g. understood ingredients, intelligence, mutations, distance, telekinesis).
  • Recipes: Enables crafting via xml-defined recipes with input ingredients and output products.
  • Ingredients: Zero or more ingredients can be associated with a recipe.
    • Can be one or more blueprints, or blueprint hierarchies e.g. to accept any type of arrow as input.
    • Supports liquid specification e.g. "acid", "water-500,oil-500".
    • Charge consumption, including specific types of charge (e.g. biological).
    • Optional inclusion/exclusion of broken/rusted items
    • Consumed quantities of zero or more, or dice rolls e.g. "2d3", "0-10", "1d5-1". Liquids support partial dram quantities e.g. "1.5".
    • Items within reach of the player character (supports telekinesis), including those in legally accessible containers, are considered for use as ingredients.
  • Products: Zero or more products can be associated with a recipe.
    • Outputs can be objects from a single blueprint, population tables, including non-takeables such as for constructing walls.
    • Generate a population table, randomly roll one from a population table, or use dynamic tables.
    • Population tables support variables e.g. {zonetier}, {zonetier+1}, {ownertier}, {ownertechtier}.
    • Each product can specify a quantity. Dice rolls are supported e.g. "2d3", "0-10", "1d5-1".
    • Bonus mod chance, mod number, and automods.
    • Products can be generated with a specified liquid and liquid amount, including dice rolls e.g. "2d3".
  • Customizable UI: Choose how/if recipes are displayed, selected, and filtered.
    • Tiles, render strings, colors, and display names are supported where recipe are displayed.
    • Recipe visibility and usability based on whether ingredients or products have been seen or understood.
    • Names of not-yet-understood ingredients and products can be hidden from the player, displaying instead "something unknown".
    • Recipes can be selected by the player from a full recipe list.
    • Recipes can be selected by the player from a list of nearby ingredients (e.g. to select which poison to apply to a weapon)
    • Recipes can be selected automatically as the first recipe, or can be selected randomly.
    • Batch recipes are configurable.
    • Ingredients can be configured to be selected individually by the player or automatically selected.
  • Ongoing actions: Crafting takes time! Configurable action duration and handles interruptions gracefully.
  • Script integration (optional): Custom logic via adding C# hooks to actions.

Getting Started: A Basic Example
Here's a simple example that lets the player craft a Steel Arrow from a Wooden Arrow and Scrap Metal at a Workbench.

Save this XML as MoreCrafting.xml inside your mod folder:

<?xml version="1.0" encoding="utf-8"?> <MoreCrafting> <category Name="Fletching"> <recipe Name="tyrir_fletching_steelarrow"> <ingredient Name="ingredient 1" Blueprints="Wooden Arrow" /> <ingredient Name="ingredient 2" Blueprints="Scrap Metal" /> <product Name="product 1" Blueprint="Steel Arrow" /> </recipe> </category> <craft Name="tyrir_fletching" Blueprints="Workbench"> <addrecipe Name="tyrir_fletching_steelarrow" /> </craft> </MoreCrafting>

When the player interacts with a Workbench, they'll see a new "craft" action. When the player selects that action, the game will:
  1. Let the player select the recipe.
  2. Prompt the player to select which items to use from their vicinity, including containers in reach.
  3. Ask how many batches to make.
  4. Begin crafting — if interrupted before completion, for example if attacked or an ingredient has become lost or inaccessible, the player will see an interruption message with the reason e.g. "You stopped crafting because you are frozen".

Those 3 player prompts, selecting a recipe, selecting ingredients, selecting the number of batches, can each be configured via XML to create a more streamlined player experience, for example for situations where you only have a single option/recipe you may not want to prompt the player.

Improving the Example: Display Name, More Recipes
Let's:
  1. Rename the action to "make arrows", rather than the generic "craft".
  2. Use "fletching" as the descriptive noun, rather than the generic "crafting".
  3. Add a second recipe that combines an arrow with a grenade.
  4. Use <addcategory/>, instead of <addrecipe/>, to add all recipes in the "Fletching" category to the craft

<category Name="Fletching"> <recipe Name="tyrir_fletching_steelarrow"> <ingredient Name="i1" Blueprints="Wooden Arrow" /> <ingredient Name="i2" Blueprints="Scrap Metal" /> <product Name="p1" Blueprint="Steel Arrow" /> </recipe> <recipe Name="tyrir_fletching_boomrosearrow" EnergyCost="20000" CraftableWhenHaveAttributes="Intelligence::18"> <ingredient Name="i1" Blueprints="Wooden Arrow" /> <ingredient Name="i2" Blueprints="HEGrenade1" /> <product Name="p1" Blueprint="Boomrose Arrow" /> </recipe> </category> <craft Name="tyrir_fletching" Blueprints="Workbench" DisplayName="make arrows" DescriptiveNounPhrase="fletching"> <addcategory Name="Fletching" /> </craft>

This setup:
  1. Shows the action as "make arrows" in the interaction UI.
  2. Displays "You stop fletching..." if interrupted.
  3. Requires 18 Intelligence to make a boom arrow.
  4. Takes ~20 turns (20000 energy).

Next Steps
MoreCrafting is highly configurable. From here you can:

  • Add liquid-based ingredients (e.g. coat weapon in acid)
  • Use population tables to generate random or dynamic outputs
  • Add conditions or filters to control when actions show up
  • Hook in C# callbacks for custom effects


Advanced Features
These features allow you to take MoreCrafting beyond basic recipes — enabling dynamic item generation, conditional crafting, scripting, and deeper game integration.

[h4]🧠 Conditional Crafting[/h4]
You can control whether a recipe appears or is usable based on game conditions.

Under construction!
Last edited by Tyrir; 30 Apr @ 4:00am
< >
Showing 1-4 of 4 comments
Per page: 1530 50