1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2024-12-29 12:20:41 +00:00
OpenMW/docs/source/manuals/openmw-cs/tour.rst
AnyOldName3 0d0e80f2a1 Improve formatting after someone pointed out a problem on Discord
and then I noticed a bunch of other problems
2024-08-15 22:15:05 +00:00

377 lines
18 KiB
ReStructuredText

A Tour through OpenMW CS: making a magic ring
#############################################
In this first chapter we will create a mod that adds a new ring with a simple
enchantment to the game. The ring will give its wearer a permanent Night Vision
effect while being worn. You do not need previous Morrowind modding experience,
but you should be familiar with the game itself. There will be no
scripting necessary, we can achieve everything using just what the base game
offers out of the box. Before continuing make sure that OpenMW is properly
installed and playable.
Adding the ring to the game's records
*************************************
In this first section we will define what our new ring is, what it looks like,
and what it does. Getting it to work is the first step before we go further.
Starting up OpenMW CS
=====================
We will start by launching OpenMW CS, the location of the program depends on
your operating system. You will be presented with a dialogue with three
options: create a new game, create a new addon, edit a content file.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/opening-dialogue.png
:alt: Opening dialogue with three option and setting button (the wrench)
The first option is for creating an entirely new game, that's not what we want.
We want to edit an existing game, so choose the second option. When you save your
addon you can use the third option to open it again.
You will be presented with another window where you get to choose the content to
edit and the name of your project. Then we have to select at least the base game and
optionally a number of other addons we want to depend on. The name of the
project is arbitrary, it will be used to identify the addon later in the OpenMW
launcher.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/new-project.png
:alt: Creation dialogue for a new project, pick content modules and name
Choose Morrowind as your content file and enter `Ring of Night Vision` as the
name. We could also choose further content files as dependencies if we wanted
to, but for this mod the base game is enough.
Once the addon has been created you will be presented with a table. If you see
a blank window rather than a table choose *World**Objects* from the menu.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/new-project.png
:alt: The table showing all object records in the game.
Let's talk about the interface for a second. Every window in OpenMW CS has
*panels*, these are often but not always tables. You can close a panel by
clicking the small *X* on the title bar of the panel, or you can detach it by
either dragging the title bar or clicking the icon with the two windows. A
detached panel can be re-attached to a window by dragging it by the title bar
on top of the window.
Now let's look at the panel itself: we have a filter text field, a very large
table and a status bar. The filter will be very useful when we want to find an
entry in the table, but for now it is irrelevant. The table you are looking at
contains all objects in the game, these can be items, NPCs, creatures,
whatever. Every object is an entry in that table, visible as a row. The columns
of the table are the attributes of each object.
Morrowind uses something called a *relational database* for game data. If you
are not familiar with the term, it means that every type of thing can be
expressed as a *table*: there is a table for objects, a table for enchantments,
a table for icons, one for meshes and so on. Properties of an entry must be
simple values, like numbers or text strings. If we want a more complicated
property we need to reference an entry from another table. There are a few
exceptions to this though, some tables do have subtables. The effects of
enchantments are one of those exceptions.
Defining a new record
=====================
Enough talk, let's create the new ring now. Right-click anywhere in the objects
table, choose `Add Record` and the status bar will change into an input field.
We need to enter an *ID* (short for *identifier*) and pick the type. The
identifier is a unique name by which the ring can later be identified; I have
chosen `ring_night_vision`. For the type choose *Clothing*.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/add-record.png
:alt: Enter the ID and type of the new ring
The table should jump right to our newly created record, if not read further
below how to use filters to find a record by ID. Notice that the *Modified*
column now shows that this record is new. Records can also be *Base*
(unmodified), *Modified* and *Deleted*. The other fields are still empty since
we created this record from nothing. We can double-click a table cell while
holding Shift to edit it (this is a configurable shortcut), but there is a
better way: right-click the row of our new record and chose *Edit Record*, a
new panel will open.
We can right-click the row of our new record and select *Edit Record*, a
new panel will open. Alternatively we can also define a configurable shortcut
instead of using the context menu; the default is double-clicking while
holding down the shift key.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/edit-record.png
:alt: Edit the properties of the record in a separate panel
You can set the name, weight and coin value as you like, I chose `Ring of Night
Vision`, `0.1` and `2500` respectively. Make sure you set the *Clothing Type*
to *Ring*. We could set the other properties manually as well, but unless you
have an exceptional memory for identifiers and never make typos that's not
feasible. What we are going to do instead is find the records we want in their
respective tables and assign them from there.
Finding records using filters
=============================
We will add an icon first. Open the *Icons* table the same way you opened the
*Objects* table: in the menu click *Assets**Icons*. If the window gets too
crowded remember that you can detach panels. The table is huge and not every
ring icon starts with :code:`ring`, so we have to use filters to find what we want.
Filters are a central element of OpenMW CS and a major departure from how the
original Morrowind CS was used. In fact, filters are so important that they
have their own table as well. We won't be going that far for now though. There
are three types of filters: *Project filters* are part of the project and are
stored in the project file, *session filter* are only valid until you exit the
CS, and finally *instant filter* which are used only once and typed directly
into the *Filter* field.
For this tutorial we will only use instant filters. We type the definition of
the filter directly into the filter field rather than the name of an existing
filter. To signify that we are using an instant filter the have to use `!` as
the first character. Type the following into the field:
.. code::
!string("id", ".*ring.*")
A filter is defined by a number of *queries* which can be logically linked. For
now all that matters is that the `string(<property>, <pattern>)` query will check
whether `<property>` matches `<pattern>`. The pattern is a regular expression,
if you don't know about them you should learn their syntax. For now all that
matters is that `.` stands for any character and `*` stands for any amount,
even zero. In other words, we are looking for all entries which have an ID that
contains the word :code:`ring` somewhere in it. This is a pretty dumb pattern because
it will also match words like :code:`ringmail`, but it's good enough for now.
If you have typed the filter definition properly the text should change from
red to black and our table will be narrowed down a lot. Browse for an icon you
like and drag & drop its table row onto the *Icon* field of our new ring.
That's it, you have now assigned a reference to an entry in another table to
the ring entry in the *Objects* table. Repeat the same process for the 3D
model, you can find the *Meshes* table under *Assets**Meshes*.
Adding the enchantment
======================
Putting everything you have learned so far to practice we can add the final and
most important part to our new ring: the enchantment. You know enough to
perform the following steps without guidance: Open the *Enchantments* table
(*Mechanics**Enchantments*) and create a new entry with the ID `Cats Eye`.
Edit it so that it has *Constant Effect* enchantment type.
To add an effect to the enchantment right-click the *Magic Effects* table and
choose *Add new row*. You can edit the effects by right-clicking their table
cells. Set the effect to *NightEye*, range to *Self*, and both magnitudes to
`50`. The other properties are irrelevant.
Once you are done add the new enchantment to our ring. That's it, we now have a
complete enchanted ring to play with. Let's take it for a test ride.
Playing your new addon
======================
Launch OpenMW and in the launcher under *Data Files* check your addon. Load a
game and open the console. We have only defined the ring, but we haven't placed
any instance of it anywhere in the game world, so we have to create one. In the
console type:
.. code::
player->AddItem "ring_night_vision" 1
The part in quotation marks is the ID of our ring, you have to adjust it if you
chose a different ID. Exit the console and you should find a new ring in your
inventory. Equip it and you will instantly receive the *Night Vision* effect
for your character.
Conclusion
==========
In this tutorial we have learned how to create a new addon, what tables are and
how to create new records. We have also taken a very brief glimpse at the
syntax of filters, a feature you will be using a lot when creating larger mods.
This mod is a pure addition, it does not change any of the existing records.
However, if you want to actually present appealing content to the player rather
than just offering abstract definitions you will have to change the game's
content. In the next tutorial we will learn how to place the ring in the game
world so the player can find it legitimately.
Adding the ring to the game's world
***********************************
Now that we have defined the ring it is time add it to the game world so the
player can find it legitimately. We will add the ring to a merchant, place it
in a chest, and put it somewhere in plain sight. To this end we will have to
actually modify the contents of the game.
Adding to an NPC
================
The simplest way is probably to add it to the inventory of a shopkeeper.
An obvious candidate is Arrille in Seyda Neen - he's quick to find in a new game
and he's easy to find in the CS as his name comes early alphabetically.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/Ring_to_Arrille.png
:alt: Putting the ring into Arrille's inventory
Open the CS and open the *Objects* table (*World**Objects*).
Scroll down to Arrille, or use a filter like :code:`!string("ID","arrille")`.
Open another pane to edit him - either right click and select edit or use the
shortcut (default is shift double-click). Scroll down to the inventory section
and right click to add a new row. Type in the id of the ring (or find it in the
object pane, and drag and drop). Set the number of rings for him to stock - with
a negative number indicating that he will restock again to maintain that level.
However, it's an attractive item, so he will probably wear it rather than sell it.
So set his stock level too high for him to wear them all (3 works, 2 might do).
Another possibility, again in Seyda Neen making it easy to access, would be for
Fargoth to give it to the player in exchange for his healing ring.
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/Ring_to_Fargoth_1.png
:alt: Editing Fargoth to give ring to player
Open the *Topicinfo* Table (*Characters**Topic Infos*). Use a filter :code:`!string(Topic,ring)`
and select the row with a response starting with :code:`You found it!`. Edit the record,
firstly by adding a bit more to the response, then by adding a line to the script
to give the ring to the player - the same as used earlier in the console
.. code::
player->AddItem "ring_night_vision" 1
.. figure:: https://gitlab.com/OpenMW/openmw-docs/raw/master/docs/source/manuals/openmw-cs/_static/images/chapter-1/Ring_to_Fargoth_2.png
:alt: Editing Fargoth to give ring to player
Placing in a chest
==================
For this example we will use the small chest intended for lockpick practice,
located in the Census and Excise Office in Seyda Neen.
First we need the ID of the chest - this can be obtained either by clicking on it in the console
in the game, or by applying a similar process in the CS -
World/Cells
Select `Seyda Neen, Census and Excise Office`
Right-click and select *View*
Use mouse wheel to zoom in/out, and mouse plus WASD keys to navigate
Click on the small chest
Either way, you should find the ID, which is :code:`chest_small_02_lockprac`.
Open the *Objects* table (*World**Objects*) and scroll down to find this item.
Alternatively use the Edit/Search facility, selecting ID rather than text,
enter `lockprac` into the search box, press *Search*,
which should return two rows, then select the *Container* one rather than the *Instance*
Right-click and *Edit Record*.
Right-click the *Content* section and select *Add a row*
Set the Item ID of the new row to be your new ring - simplest way is probably to open the *Objects*
table if it's not already open, sort on the *Modified* column which should bring the ring,
with its status of *Added* to the top, then drag and drop to the chest row.
Increase the *Count* to :code:`1`.
Save the addon, then test to ensure it works - e.g. start a new game and lockpick the chest.
Placing in plain sight
======================
Let's hide the Ring of Night vision in the cabin of the `Ancient Shipwreck <https://en.uesp.net/wiki/Morrowind:Ancient_Shipwreck>`_, a derelict vessel
southeast of Dagon Fel. Open the list of Cells (*World**Cells*) and find
:code:`Ancient Shipwreck, Cabin`.
This will open a visualization of the cabin. You can navigate around the scene
just like you would when playing Morrowind. Use the WASD keys to move forward,
backwards, and sideways. Click and drag with the left mouse button to change the
direction you are looking. Navigate to the table in the cabin.
If you've closed the *Objects* table, reopen it via *World**Objects*. Navigate
to your Ring of Night Vision (you can find it easily if you sort by the *Modified*
column). Drag the ring from the *Objects* table onto the table in the Cell view.
Now let's move the ring to the precise location we want. Hover over the ring and
click the middle mouse button. If you don't have a middle mouse button, you can
select an alternative command by going to *Edit**Preferences…* (Windows, Linux)
or *OpenMW**Preferences…* (macOS). Go to the Key Bindings section and choose
*Scene* from the dropdown menu. Then click on the button for *Primary Select* and
choose an alternative binding.
After you have switched to movement mode, you will see several arrows. Clicking
and dragging them with the right mouse button will allow you to move the object
in the direction you want.
If you'd like an easy way to test this, you can start OpenMW with the `game
arguments <https://wiki.openmw.org/index.php?title=Testing>`_
:code:`--start="Ancient Shipwreck, Cabin" --skip-menu`. This will place you right in
the cell and allow you to pick up and equip the ring in order to check that it
works.
Navigation in the CS
====================
This is probably a suitable place to start talking about how navigation differs from TESCS
in vanilla Morrowind.
There is advice in Scripting for Dummies, the definitive manual for Morrowind Scripting:
"If you give your scripts a common tag, that will make it easier to jump between the
different scripts of your project, e.g. start every script name with AA_Scriptname
this will put them right at the beginning of the list and keep them neatly together."
This is valid for the rather poorer navigation facilities there, but it's not sensible for
the OpenMW CS. Some modders took it further, and started script names and object id with numbers,
typically :code:`1`, to bring the items even earlier in the default alphabetical sorts. In fact
the CS won't allow names/ids to start with numbers or to include :code:`.`.
There are better options available:
Filtering, which isn't available at all in TESCS - put in a filter like
.. code::
!string("ID",".*ring.*")
to find all IDs which contain the string :code:`ring`
Sorting, which is available in some parts of TESCS, but not for scripts (other than script names being
sorted in ascending order)- hence the recommendation
Typically the *Modified* column is useful here - most items will have *Base* status, unchanged from
the base game.
*Added* status will cover those items added in this addon.
*Modified* status will cover items from the base game which have been modified in this addon.
Click on the top of the column to toggle between ascending and descending order - thus between *Added*
and *Modified* at the top. Or put your desired modified status into a filter then sort alphabetically
on a different column.
Checking your new addon
=======================
Launch OpenMW and in the launcher under *Data Files* check your addon, if it's not
already checked. Load a game and make your way to Seyda Neen - or start a new game.
Check whether Arrille has one (or more) for sale, and whether Fargoth give you one
when you return his healing ring.