Difference between revisions of "Arcane University:World space synchronization"

The Beyond Skyrim Wiki — Hosted by UESP
Jump to: navigation, search
(WIP)
(No difference)

Revision as of 16:48, 4 November 2021

In this article, world space synchronization refers to the process of copying a part of one world space into another, so that the borders match up in both. This is needed for Beyond Skyrim projects whose provinces border each other. Once a project has their border region more or less finalized, it needs to be copied over to the other project so that they can level design their border region while accounting for what's directly on the other side; and once that's done, this border region needs to be copied back the other way.

This article will demonstrate how to do one such copying operation using xEdit, without the larger-scale project management involved; it is also useful for other situations where this may have to be done, and not just in Beyond Skyrim (many scripts discussed here were originally created for Skywind).


Preparation

You need two world spaces, one containing the landscape to copy (henceforth origin world space) and one to copy to (destination world space). For clarity's sake, this article will assume that they are contained in masters (.esm) to distinguish them from plugins (.esp), but the process is the same if they are in plugins. The two world spaces may be part of the same master file, which makes the process a bit simpler, but often will be in separate masters.

The copy happens in two passes that are independent and can be done in any order: copying of landscape, and copying of references. Both methods work on rectangular regions in a world space, so you must figure out what those rectangular regions are (there can be multiple that combine into a more complex shape, even just one cell large if necessary). Write down the cell coordinates of the northeast and southwest corners of every rectangle according to the origin world space's coordinate system. Then, also calculate what those coordinates amount to in Units (precise formulas forthcoming). It helps to have a grid map or similar on hand.

Next, find out the difference between the coordinate systems of the two world spaces. Pick a location that can be pinpointed in both world spaces, note its cell coordinates in the origin world spaces, and its cell coordinates in the destination world space. Subtract the X and Y coordinates in the origin world space from the X and Y coordinates in the destination world space, respectively. This will give you the offset, or the number of cells to move the copy by along the X and Y axes. Also calculate the X and Y offsets in units by multiplying them with 4096 (as that is the number of units comprising the edge of a Skyrim world space cell). If the offset is not a clean multiple of a cell, then the method for copying landscape will not work, as the method for that works cell by cell. The method for copying references is unit-based, but will be of little use if the landscape cannot be accurately copied.

If the two world spaces belong to different masters, and the destination world space's file is not a master of the origin world space's file, then the copied area must be free of land textures and references whose base objects come from the origin world space's file. This can be resolved in advance (such as by re-implementing any non-vanilla assets in a shared master, and switching all references to use those shared base objects; for Beyond Skyrim, this is BSAssets) but can also be arranged at the end of the process; this article will show how to contain the copy in a patch plugin which can be tweaked before being sent off to be merged into the destination world space's master.

To redirect all references of a certain base object in the origin file to a base object that is compatible with the destination file, one can use the "Search and replace" function in the Creation Kit, or the following xEdit script by Zilav, which has the advantage of also covering land textures (just replace OldFormID and NewFormID as needed):

unit UserScript;

const
  OldFormID = $01012345;
  NewFormID = $01054321;

function Process(e: IInterface): integer;
begin
  CompareExchangeFormID(e, OldFormID, NewFormID);
end;

end.


Landscape

References

Final checks