Modding:Intro - Zones and Worlds

From Caves of Qud Wiki
Jump to navigation Jump to search
This page is about modding. See the modding overview for an abstract on modding.
This page is about modding. See the modding overview for an abstract on modding.

Terminology

The game (and the modding wiki pages) use a few terms to describe different parts of Caves of Qud's world:

  • Zone: a "screen" of the game, consisting of an 80 x 25 rectangular grid of cells.
  • Cell: a specific location within a zone. Objects in the game typically occupy one cell at a time.
  • World: a collection of zones[1]. The default world that players start in is JoppaWorld; other examples include Tzimtzlum, Thin World, and Interior (used to model vehicle interiors).
  • Parasang: a 3 x 3 grid of zones. Each cell of the [world map] corresponds to a parasang.

The following terminology is also occasionally used:

  • Map: a .rpm file specifying a static zone, such as YdFreehold.rpm (used by Yd Freehold). "Map" is sometimes used as a synonym for the word "zone". However, for the purpose of clarity we will only use the former term when describing .rpm files.
  • World map: the overworld zone that the player enters when ascending from a surface zone; see the [world map] page for more details.
  • Zone templates: a post-processing system used by the game to add dynamic encounters to zones at the end of their build procedure. See Modding:Zone Templates.

What can be modded

Caves of Qud exposes an fairly large API for creating your own zones and worlds. Most complex zone generation requires scripting in C#, but even the XML-only interface exposes a lot of functionality that modders can hook into.

XML-only modding

Maps

Caves of Qud's files include a data file, Worlds.xml, which defines each of the different worlds that are included in the game and how zones within those worlds should be constructed. You can merge into Worlds.xml to use a static map for your zone; see Modding:Maps for more details.

More generally, you can merge into Worlds.xml to use any combination of zone builders that you feel like for a given zone. However, most of the zone builders provided by the game are difficult to use generically, and defining new zonebuilders requires scripting. Nonetheless, see Modding:Worlds to get an overview of how Worlds.xml is structured, and Modding:Zone Builders can also be consulted for a list of some of the more useful zone builders.

Interiors

This system also allows you to define custom interior zones, which are used in-game by the Golem and temple mechas such as temple mecha mk Ia. To define an interior zone in XML, you need to merge a new cell into the Interior world in Worlds.xml. Then you need to attach a Interior part to the object that you want to give an interior to, and specify the cell for that interior.

See Modding:Interior Zones for more details.

Dynamic zone generation

Finally, there is limited support for creating dynamic zones using XML through the use of the MapChunkPlacement part. This can be attached to a widget object to have it spawn objects from a map file when the widget is placed in a zone. A design pattern used by mods such as Mycogrigoric Alcoves (Steam Workshop page) is to define many different widgets, each of which uses a different map chunk, and then spawn these widgets from a population table to randomly generate different maps.

Note that as of version 207.80, MapChunkPlacement (and related parts, such as DeployWith) is bugged for interior zones[2]. It is possible, albeit tedious, to hack around this issue; see Mycogrigoric Alcoves for one potential solution.

Script modding

Script mods have significantly more flexibility in the kinds of zones that they can generate. In addition to the static zone generation utilities available to XML-only mods, script mods have a large set of utilities they can use to procedurally generate zones, as well as to refine zone geometry, define dynamic encounters, and more. Check out Modding:Zone Builders and Modding:Zone Procedural Generation to get started on reviewing the tools that are available to you.

In addition, script mods can hook into the world generation process and even define new worlds altogether. These topics are covered in Modding:Worlds.

Starter code for zone builder examples

The following pages present several code examples that you can use to experiment with zone builders locally:

All of these pages assume that you start from a mod with the following code. This code will create a custom world, ZBWorld, that you can use for testing. You can teleport into this world with the wish goto:ZBWorld.40.12.1.1.10.

  • Worlds.xml
<?xml version="1.0" encoding="utf-8" ?>
<worlds>                                           
  <world Name="ZBWorld" ZoneFactory="ZBWorldZoneFactory" DisplayName="zone builder test world">
    <cell Name="ExampleCell">
      <zone Level="10" x="1" y="1" Name="test zone">
        <!-- Leave empty for now -->
      </zone>
    </cell>
  </world>
</worlds>
  • ZoneFactories.cs
namespace XRL.World.ZoneFactories {
    public class ZBWorldZoneFactory : IZoneFactory {
        public override bool CanBuildZone(ZoneRequest Request) => false;

        public override Zone BuildZone(ZoneRequest Request) {
            var zone = new Zone(80, 25);
            zone.ZoneID = Request.ZoneID;
            return zone;
        }

        public override void AddBlueprintsFor(ZoneRequest Request) {
            var cb = Blueprint.CellBlueprintsByName["ExampleCell"];
            Request.Blueprints.Add(cb.LevelBlueprint[1, 1, 10]);
        }

        public override void AfterBuildZone(Zone zone, ZoneManager zoneManager) {
            ZoneManager.PaintWalls(zone);
            ZoneManager.PaintWater(zone);
        }
    }
}

References

  1. More technically, a collection of zones sharing a common IZoneFactory and some additional properties specified via Worlds.xml.
  2. Issue #9582