Difference between revisions of "Modding Guide"

From Legends of Aria Admin and Modding Wiki
Jump to: navigation, search
(Capabilities)
 
(67 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 +
== Disclaimer ==
 +
 +
This guide is mostly intended to non-professional Unity3D developers & designers, i.e. beginners who are motivated to mod using the LoA engine.<br />
 +
Actually, current contributors of this guide are relatively new to Unity3D and Lua/C#, with little to no experience with those before starting to work on a Legends of Aria server.<br />
 +
The concepts and details given in this guide are mostly the basics to get you up-and-running on a first mod. As you will want to improve your mod, you will certainly have to go further into the details and complexity of Unity3D editing and Lua, or even C#, programming ... which won't necessarily be covered here as the capabilities of modding are quite large, and you might even try something nobody tried before.<br />
 +
As Citadel Studios still is making a great deal of changes to map creation, parts of this guide may at times become out of date. For that matter, do not hesitate to give us feedback on this guide (what need to be clarified, detailed, updated/corrected, etc), or even to edit it yourself to keep the momentum going.
 +
 +
=== Tips for Beginners ===
 +
 +
''Backup Regularly.''
 +
Be sure to always back up your complete unity project on a regular basis.
 +
 +
''Ask For Help.''
 +
We can not stress this enough. Ask for help.
 +
Unity has a steep learning curve. You are working in a professional game engine. If you encounter issues, do not try to figure it out yourself for hours on end. Instead, ask for help.
 +
On top of that, you might actually be doing everything right. The LoA toolkit still has quite it's share of bugs, and you do not want to be spending time kicking yourself because you think you screwed up. So, you guessed it, ask for help.
 +
If you are worried your question might be dumb, still ask for help. You are a modder, not a professional game developer. We all have to start somewhere.
 +
There are currently 2 Discord communities dealing with LoA server & modding, do not hesitate to request joining them: "Shards Online Admins" and "Community Projects - LoA"
 +
 +
''Start Small.''
 +
For your first project, start with a very small map and work on it from start to finish. That is the best way to familiarize you with all of the steps, know how everything interacts, and get a sense of how much time what takes.
 +
 +
=== List of current Issues & Bugs ===
 +
 +
We're trying to maintain a list of current issues and bugs you might encounter [[Modding Issues|here]].
 +
 +
== Capabilities ==
 +
 +
'''What can I mod? What can't I mod?'''
 +
* The Official Map is currently moddable in a very limited way. You can not change the terrain mesh geometry or textures, nor remove any static objects.
 +
* Custom Equipment is currently not moddable in Unity.
 +
* Custom Maps can be made in Unity and run in game.
 +
* Custom Assets (such as custom objects) can already be added and set up for the client to properly use.
 +
** This includes adding '''object''' or '''surface collision''', '''transparency colliders''' or '''collapsible roofs''' for houses, as well as '''object bounds''' and '''picker boxes''' for support players to be able to interact with them.
 +
* Custom Maps currently do not support a proper SFX set up. Both music and environment effects can be placed in the scene for testing and they will play in the client. However, you can not lower or increase the volume in the client properties.
 +
 
== Necessary Tools ==
 
== Necessary Tools ==
  
 
For the time being, modding is only feasible on Windows machines.
 
For the time being, modding is only feasible on Windows machines.
  
# Unity 3D editor: Download [https://unity3d.com/get-unity/download/archive Unity3D Installer version 2018.1.9] (at least version 5.6). You will need to create an account.
+
# Unity 3D editor: Download [https://unity3d.com/get-unity/download/archive Unity3D Installer version 2018.3.4f1]. You will need to create an account.<br />
# Lua editor: Download [[Sublime Text]] or any other editor with syntax highlighting, e.g. [https://notepad-plus-plus.org/download/ Notepad++].
+
#* ''Note: When you download and install Unity, to be sure to also download and install the standard assets. It is possible to install unity without these. If you do, then you will need to manually add them to be able to import.''
 +
# Editing Lua scripts and XML files: Download [[Sublime Text]] or any other editor with syntax highlighting, e.g. [https://notepad-plus-plus.org/download/ Notepad++].
 
# The latest [https://www.legendsofaria.com/forums/discussion/1249/admin-download-links-and-patch-notes/p1 Legends of Aria Toolkit].
 
# The latest [https://www.legendsofaria.com/forums/discussion/1249/admin-download-links-and-patch-notes/p1 Legends of Aria Toolkit].
 +
 +
Note: Unity3D useful tip to move the camera: Press right-clight to enter "WASD" camera control mode. Add 'SHIFT' to accelerate camera movement.
  
 
== Creating a new project, based or not on the Celador map ==
 
== Creating a new project, based or not on the Celador map ==
 +
Watch the video on the right, introducing the setup.
 +
{{#evt:
 +
service=youtube
 +
|id=https://www.youtube.com/watch?v=rm-0EvSgiz8
 +
|alignment=right
 +
}}
 +
 +
[[File:Folder Structure.png|right|Mod Folder Structure]]
  
Cf. this [https://www.youtube.com/watch?v=rm-0EvSgiz video] introducing the setup
 
 
'''NOTE''': You must have first [[Installation_Instructions|installed a LoA server]] before to proceed with the direction below.
 
'''NOTE''': You must have first [[Installation_Instructions|installed a LoA server]] before to proceed with the direction below.
  
 
# Launch Unity3D, create a "New" "3D" project, assigning it with a name, preferably in a folder of your choice. No Unity Analytics is needed.
 
# Launch Unity3D, create a "New" "3D" project, assigning it with a name, preferably in a folder of your choice. No Unity Analytics is needed.
 
# Import assets: in "Assets" menu, "Import Package" and import both "Effects" and "Environment" (Press "Import" for each new window opening).
 
# Import assets: in "Assets" menu, "Import Package" and import both "Effects" and "Environment" (Press "Import" for each new window opening).
# From the Assets store (in "Window" menu, select "Asset Store"), search for the "Post Processing Stack" package ("Unity Essentials" from "Unity Technologies").
+
#* Do not import any other standard packages. A common mistake is that new map creators believe it is better to import all of the standard assets. It is not. It may break your project. I will get into that a little further down the road when we cover custom assets.
 +
#* The Standard Assets package from the asset store is not the same as the one you import here. The one from the asset store can actually break your project. If you do not see them, the unity download you used does not include the files. You will need to download them manually and add them. The guide for this is at the end of this chapter.
 +
# From the Assets store (in "Window" menu, select "Asset Store"), search for the "Post Processing Stack" package ("Unity Essentials" from "Unity Technologies"), install and import it.
 +
#* The Post Processing Stack is made by Unity and is free. It combines a complete set of image effects into a single post-process pipeline. As Legends of Aria recently began to use post-processing profiles on it's camera, you want to have this for everything to function properly.
 
# in "Assets" menu, "Import Package", import "Custom Package" and select the Legends of Aria Toolkit you previously downloaded. Click "Import" on the new widow, this will take several minutes.
 
# in "Assets" menu, "Import Package", import "Custom Package" and select the Legends of Aria Toolkit you previously downloaded. Click "Import" on the new widow, this will take several minutes.
 
# You should now have a new "LoA Toolkit" menu item in Unity3D.
 
# You should now have a new "LoA Toolkit" menu item in Unity3D.
Line 23: Line 72:
 
# If you are editing a mod that you already created, select the consistent mod name in the "Mod" pull-down list (You might have to "save" first and reopen the Settings).
 
# If you are editing a mod that you already created, select the consistent mod name in the "Mod" pull-down list (You might have to "save" first and reopen the Settings).
 
# If you are starting a new mod, select "Create Mod" under the "LoA Toolkit" menu.
 
# If you are starting a new mod, select "Create Mod" under the "LoA Toolkit" menu.
 +
 +
Your Mods folder under <server> should then reflect the structure displayed on the right.
 +
 +
=== Compatible Unity Assets ===
 +
 +
Citadel Studio currently does not provide a list of the content they use for their official server.
 +
 +
Here under is a list of assets that have been tested by members, and are available on the Unity Asset Store (under "Window", "Asset Store").
 +
Besides for the "Post Processing Stack", they are optional.
 +
 +
We are not listing here Object assets, since there are certainly plenty out there and they shall all be compatible, but rather utility assets which are helping design better-looking maps.
 +
Be aware that while there are plenty of free assets out there, many come at a cost and will depend on your willingness to spend money to get a better-looking world. You could certainly avoid using those if you're a professional 3D game designer, but for the most of us, using such assets is a necessity (unless you're willing e.g. to spend days/weeks manually editing your terrain).
 +
Do not feel however pressured to spend money to get tools or content for your project. There is a good amount of content provided by Citadel Studios.
 +
The biggest difference in the quality of your maps you will get out of actual experience of making them. There is also a great deal of free content available online, and there are regular sales every few months on the Unity Asset Store if you do want to get some custom content.
 +
 +
{| class="wikitable"
 +
|-
 +
! Asset Name !! Editor !! Cost
 +
|-
 +
| Post Processing Stack || Unity Technologies || Free
 +
|-
 +
| Terrain Toolkit 2017 || Heparo || Free
 +
|-
 +
| Relief Terrain Pack || Tomasz Stobierski || $40
 +
|-
 +
| Vegetation Studio || Awesome Technology || $75
 +
|-
 +
| SpeedTree || SpeedTree || $19/mo (a few free assets in the store, can also just buy trees packages)
 +
|}
  
 
=== Modding the Celador maps ===
 
=== Modding the Celador maps ===
Line 28: Line 106:
 
# Look in Unity's "Project" widget, select the "Legends of Aria Toolkit" folder and double-click on the "ShardsToolkit.unity" Unity asset (It's a scene map loader helper).
 
# Look in Unity's "Project" widget, select the "Legends of Aria Toolkit" folder and double-click on the "ShardsToolkit.unity" Unity asset (It's a scene map loader helper).
 
# Select the "Game" above the viewer window and press the "Play" button on the top right of that same window.
 
# Select the "Game" above the viewer window and press the "Play" button on the top right of that same window.
# You can select any scene map to be loaded by pressing its button. For "New Celador", there is an exception: The map is split into sub-scene because it is very big.
+
# You can select any scene map to be loaded by pressing its button.
# Open "LoA Toolkit" then "Utils" then "World Streamer Manager" and you can select a "Preset" selection of scene respective to the area you are looking to edit. You can alternatively load individual scenes by clicking on them.
+
#* For "New Celador", there is an exception: the map is split into sub-scenes because it is very big: Under the "LoA Toolkit" menu, select "Utils" then "World Streamer Manager". You can then select a "Preset" selection of scene respective to the area(s) you are looking to edit. You can alternatively load individual scenes by clicking on them.
 
# Switch to the "Scene" view by pressing the "#Scene" button above the Unity viewer (from the "Game" view you currently are on).
 
# Switch to the "Scene" view by pressing the "#Scene" button above the Unity viewer (from the "Game" view you currently are on).
 +
# You can add [[Modding_Guide#Prefabs|Prefabs]] to the map, as well as [[Modding_Guide#Dynamic_Game_Objects_.28GameObj.29|Seed Objects]] (cf. below).
 +
 +
Make sure you [[Modding_Guide#Saving_your_mod|save your mod]] after edition.
 +
 +
''Modder Tip: Not all files in the base folder are overridable (moddable). Here is a full list of these files:''
 +
* ''ClientIdReference.txt''
 +
* ''ObjectCollisionData.xml''
 +
* ''ObjectTagDefinitions.xml''
 +
* ''mapdata/MAPNAME/StaticCollision.xml''
  
 
=== Starting a new map ===
 
=== Starting a new map ===
 +
Watch the video for on the right for more detail.
  
See this [https://www.youtube.com/watch?v=5vHuc-ccNro video] for more detail.
+
{{#evt:
 +
service=youtube
 +
|id=https://www.youtube.com/watch?v=5vHuc-ccNro
 +
|alignment=right
 +
}}
  
# From the "LoA Toolkit" menu, select "Custom Assets", then "Create New Custom Map". You can choose either it's an exterior or interior map. A new "MapData" asset will be create under your new "Untitled" (a least until you save it) unity scene in Unity's "Hierarchy" widget.
+
# From the "LoA Toolkit" menu, select "Custom Assets", then "Create New Custom Map". You can choose either it's an exterior or interior map. A new "MapData" asset will be created under your new "Untitled" (a least until you save it) unity scene in Unity's "Hierarchy" widget.
 +
#* The reason we are creating our new scene this way and not the way you would normally in Unity is that this will add a couple of important things to your scene for you. These are the MapData object, the DefaultOutdoorLighting or DefaultIndoorLighting objects, and the DefaultOutdoorCamera or DefaultIndoorCamera objects. You should always have these in your scene. If you do not, something went wrong.
 
# Create a new terrain, either by right clicking in the "Hierarchy" widget or under the "GameObject" menu, then "3D Object" and "Terrain".
 
# Create a new terrain, either by right clicking in the "Hierarchy" widget or under the "GameObject" menu, then "3D Object" and "Terrain".
# You can edit the terrain properties (size, center, texture, etc.) from Unity's "Inspector" widget. You can also use some Unity Terrain generators to help you create terrains easily.
+
#* Note: It is important to position the Terrain object in the "Hierarchy" widget as a top node, i.e. not under any other object (including not under the "MapData" object). Drag the Terrain object if needed.
# You can add Prefabs to the map, as well as Seed Objects (cf. below).
+
# You can edit the terrain properties (size, center, texture, etc.) from Unity's "Inspector" widget. You can also use some Unity Terrain generators to help you create terrains easily (some are free in Unity's asset store)
# When done, select "MapData" in Unity's "Hierarchy" widget. Select "Reset Permanent IDs" in Unity's "Inspector" widget and press "Build".
+
# You can now add [[Modding_Guide#Prefabs|Prefabs]] to the map, as well as [[Modding_Guide#Dynamic_Game_Objects_.28GameObj.29|Seed Objects]] (cf. below).
# Check the "Saving your mod" section below. If you haven't saved the project yet, Unity will require you to save it first.
+
 
 +
Make sure you [[Modding_Guide#Saving_your_mod|save your mod]] after edition.
 +
 
 +
=== Useful Map Features ===
 +
 
 +
* [https://docs.unity3d.com/Manual/terrain-WindZones.html How to add wind to your map].
 +
* [https://docs.unity3d.com/Manual/LightingOverview.html How to add lighting to your scene].
 +
** At some point you will begin to look into how to do the lighting for your scene. You will hear terms like Linear and Gama Color Space, as well as baked lighting and real time lighting. You may also want to look into giving your map that extra polish by creating post-processing profiles for your scene.
 +
 
 +
=== Map Controllers & Regions ===
 +
Watch the video on the right for a tutorial.
 +
 
 +
{{#evt:
 +
service=youtube
 +
|id=https://www.youtube.com/watch?v=st-eEGe_CrE
 +
|alignment=right
 +
}}
 +
 
 +
Controllers are invisible objects that are managing the normal functioning of a map, like day/night cycle, weather, spawns, protection of the area, etc.
 +
 
 +
# You first need to create a new template for the controller.
 +
## Under Windows Explorer, go to your <server>\YOUR MOD NAME\templates\ folder and create a new XML file for your controller. Optionally, the template file can be created in any sub-folders, which is a good practice to stay organized. A good practice as well is to split controllers by category (weather, day/night, spawns, etc.)
 +
## Fill the file with some controller data. Check an example here under, and the templates from the Celador controllers, which can be found in <server>\Build\base\templates\celador
 +
# Back in Unity3D, under the "LOA Toolkit" menu, select "Dynamic Editors" then "Region Editor" (usually have to retry, since it doesn't load correctly the first time).
 +
# Select your Mod Name. Click "Create a new Region". A "Regions" parent object will appear in Unity's "Hierarchy" widget (if there wasn't one already), with a "New Region" object underneath. You can rename it.
 +
#* Naming the newly created region "GuardZoneLarge" will make the area guard protected.
 +
# Selecting that new Region object in "Hierarchy", you can now press "Add Node". A new "RegionArea" object will be created under the Region object. In "GameObject" menu, select "Move To View" when your camera points at the location you want that object to be positioned.
 +
# Change the size of this new "RegionArea" object to match the zone you want to cover on the map.
 +
#* For certain controllers, e.g. weather, you will need to create very big Regions.
 +
# Press "Save Regions" to make sure you save your work. You can optionally delete the "Regions" parent node now (or press the "Reset Regions" button).
 +
# If you haven't loaded your [[Modding_Guide#Dynamic_Game_Objects_.28GameObj.29|Seed Objects]] yet, reload them.
 +
# Click on "Create a New Seed Object" and "Select" to assign it the template you created above (If you created folders, look for the folder name first).
 +
# In "GameObject" menu, select "Move To View" when your camera points at the location you want that object to be positioned.
 +
# Once done, save your Seed Objects (and remove them) and [[Modding_Guide#Saving_your_mod|save your mod]].
 +
 
 +
An example of XML content for a day/night time controller:
 +
<syntaxhighlight lang="xml">
 +
<ObjectTemplate>
 +
        <ClientId>2</ClientId>
 +
        <Color>0xFF00FF00</Color>
 +
        <Name>Time Controller</Name>
 +
        <Tag>TimeController</Tag>
 +
        <ObjectVariableComponent/>
 +
        <ScriptEngineComponent>
 +
                <LuaModule Name="shard_time_controller">
 +
                        <Initializer>
 +
                                {
 +
                                        DaylightDurationSecs = 45 * 60,
 +
                                        NighttimeDurationSecs = 15 * 60,
 +
                                }
 +
                        </Initializer>
 +
                </LuaModule>
 +
        </ScriptEngineComponent>
 +
</syntaxhighlight>
 +
 
 +
=== Static Map Collision ===
 +
 
 +
''While this section is early in the guide, you shouldn't do this step before your map is pretty much complete.''
 +
In order to block player from getting to some areas, e.g. cliffs, map borders, river beds, etc, you want to add some static map collisions.
 +
This tool is pretty rudimentary, and is using a painted 2D map. Collision maps are a 2d plane you can texture paint with the texture brush.
 +
Black is traversable (and does not display), white represents collision and is not traversable (and displays).
 +
 
 +
Watch the video on the right for a tutorial.
 +
{{#evt:
 +
service=youtube
 +
|id=https://www.youtube.com/watch?v=TtSsw-uowb4
 +
|alignment=right
 +
}}
 +
 
 +
# To paint your collision map, go to to the "LoA Toolkit" drop-down menu, select "Dynamic Editors", then "Collision Editor"
 +
#* Make sure the "Current Mod" is your mod, otherwise re-select your mod from the "LoA Toolkit" Menu, "Settings".
 +
# Switch to top down isometric view, by pressing the green 'Y' axis locator then the cube at the top right of the scene window (should then display "Top" underneath), and reposition your camera to have a full view of your map.
 +
# Press the "New Static Collision" button. A new scene with a set of 4 planes will be created in Unity's "Hierarchy" (names starting with "Collision").
 +
#* If you map is pretty elevated, you might want to change the height of those planes to have a better view on them using the "Collision Terrain Y" positioner.
 +
# Press the "Show Selected Area" checkbox to be able to visualize which plane you are editing (yellow highlight).
 +
# Repeat the next sub-steps here under for each plane
 +
## Select the plane in the "Hierarchy". In its "Inspector" widget, select "paint texture" button (the 4th one). Select the white color and the hard border round brush (the 4th one). You can reduce the size of the brush if needed.
 +
## Zoom as needed on your map and move the plane's Y to adjust as close to the map as you can. In the scene, draw the parts that players will collide against.
 +
# When done, press the "Save Static Collision" button, and delete the scene that was created during step 3 (select "Don't Save").
 +
# Make sure you [[Modding_Guide#Saving_your_mod|save your mod]] after edition.
  
 
=== Saving your mod ===
 
=== Saving your mod ===
  
Make sure you have save your Unity project, built your map data (if applies, cf. above), and saved all your seed objects (see below).
+
# First, make sure you have saved your Unity project, [[Modding_Guide#Saving|saved all your seed objects]] (if any), built your custom objects library (if any).
 +
# When done, select "MapData" in Unity's "Hierarchy" widget. Select "Reset Permanent IDs" (unless you have a script that refers to any Permanent IDs) in Unity's "Inspector" widget and press "Build". If you haven't saved the Unity project or scene yet, Unity will require you to save it first.
 +
# To make sure your server loads your modifications, make sure you consistently edit the "<Mod>" section of the ClusterConfig.xml file, i.e. put your mod name there.
 +
# If you have created a new map, make sure you add a "<ClientBundle>" subsection in that section and add or edit the consistent "<Region>".
 +
# Also, make sure you clean up all your server backups before to reload it (careful of what you delete as well, like characters' data, if you're in production).
  
To make sure your server loads your modifications, make sure you consistently edit the "<Mod>" section of the ClusterConfig.xml file, i.e. put your mod name there.
+
==== Potential issues ====
If you have created a new map, make sure you add a "<ClientBundle>" subsection in that section and add or edit the consistent "<Region>".
 
  
Also, make sure you clean up all your server backups before to reload it (careful of what you delete as well, like characters' data, if you're in production).
+
Here is a list of potential issues you might encounter when testing your mod, and ways to fix those:
 +
* Custom objects collision not working properly, especially on custom maps, even though you are 100% sure your collision is set up correctly.
 +
** This might be a "Terrain" issue. Make sure your Terrain object isn't under another object, i.e. is at the top level of the Hierarchy, and that it doesn't contain any child object.
 +
** This might also be a cache issue. You can try to delete the folders related to your mod (usually starting with your mod name) in <C:\Users\'''YOUR WINDOWS ACCOUNT NAME'''\AppData\LocalLow\Unity\Citadel Studios Inc__Legends of Aria>
 +
*** A cache issue impacting Collision will usually return some "Invalid client path" warnings on the server shell and the server will "bump" the char to a correct location. This is because the server collision detection works and the client isn't because its cache hasn't been updated.
 +
* Weather not playing properly when you're sure the weather is active and the player is in the correct area:
 +
** You need to have a region called "NoWeather" in your custom map. You can put it inside e.g. a mine, or somewhere it will not interact with players.
  
== Seed Objects ==
+
== Dynamic Game Objects (GameObj) ==
 +
 
 +
Legends of Aria is a true world simulation in the sense that there are very little arbitrary rules on the dynamic game objects in the world. Dynamic game objects (GameObjs) can be placed anywhere and are defined by their properties. GameObjs that contain a mobile component can move smoothly throughout the world using the pathing algorithm.
 +
All GameObjs are created from templates. The template is the definition for the initial state of an object at creation. It defines things like: What does it look like (Client Id)? What is its name? What sorts of behaviors does this object have? etc. Once the GameObj is created, the template is never referenced again and every property about that object can be changed by scripts or god powers.
 +
 
 +
'''''NOTE: In Lua, the reference type for dynamic game objects is GameObj and we will refer to them as such in this handbook.'''''
 +
 
 +
=== Seed Objects ===
  
 
Seed objects are dynamic object that spawns when the server resets or when loaded the first time.
 
Seed objects are dynamic object that spawns when the server resets or when loaded the first time.
They can be grouped, under "category" or "group", so they can be loaded, saved and edited all at once or separately. Celador base map's Seed Objects are grouped by zone and types.
+
Many of these “Seed Objects” are invisible to mortal players and are used as a source for controller scripts. The simplest and most common example of a controller script is a spawner, a behavior that spawns other GameObjs like monsters or animals on the map.
 +
In Unity3D, they can be grouped, under "category" or "group", so they can be loaded, saved and edited all at once or separately. Celador base map's Seed Objects are grouped by zone and types.
  
To access Seed Objects functionality, go to "LoA Toolkit", "Dynamic Editors" then "Seed Object Editor".
+
In Unity3D, to access Seed Objects functionality, in the "LoA Toolkit" menu, select "Dynamic Editors" then "Seed Object Editor".
 +
 
 +
Tips:
 +
* You only need to [[Modding_Guide#Loading|load your seed objects]] when you need to add or edit some.
 +
* Once saved, you can delete them all from the scene: In the "LoA Toolkit", go to "Dynamic Editors" then "Seed Object Editor" and press "Reset Seed Objects". This will save some resources.
  
 
=== Loading ===
 
=== Loading ===
Line 64: Line 257:
 
You can select in the "Seed Object Editor" to "Load All Seed Objects" or the specific "Group" that you want to load to edit.
 
You can select in the "Seed Object Editor" to "Load All Seed Objects" or the specific "Group" that you want to load to edit.
  
=== Creating ===
+
=== Creating an Instance ===
  
 
It is advised to create groups/categories to have a finer detail of finding, editing and saving/loading of seed objects. In order to do this, click on "Create New Category" on the "Seed Object Editor" window. You can rename each category or seed object from Unity's "Hierarchy" widget.
 
It is advised to create groups/categories to have a finer detail of finding, editing and saving/loading of seed objects. In order to do this, click on "Create New Category" on the "Seed Object Editor" window. You can rename each category or seed object from Unity's "Hierarchy" widget.
Line 83: Line 276:
 
You can choose to "Save All Seed Objects" or select individual groups/categories to be saved.
 
You can choose to "Save All Seed Objects" or select individual groups/categories to be saved.
 
Make sure you save the seeds as often as possible not to loose your work (since it's independent from Unity's scene/project saving).
 
Make sure you save the seeds as often as possible not to loose your work (since it's independent from Unity's scene/project saving).
 +
 +
=== Properties ===
 +
If you understand all of the different types of properties and behaviors that can be assigned to GameObjs then you essentially understand how Legends of Aria works at its core. Let’s quickly go through these properties and behaviors (some will be explained in more detail later).
 +
 +
==== Base Properties ====
 +
 +
These properties exist on every GameObj in the game. If a property is not defined in the template, it will fall back to its default value (assuming it’s not required)
 +
 +
* ClientId (required) – This is the art asset id the client uses to display this object. It also determines which Shared Object Properties (See section under Lua Script Engine) this object has and their default values.
 +
* Name - ''Modder Tip: Nearly every string in the game, including names, can be color coded. It uses html color codes in square brackets and is terminated with a dash in square brackets. Example: A blue string would be “[0000FF]Blue String[-]”''
 +
* ScaleModifier – Optionally modifies the size of the object by multiplying the default scale of the object by this value.
 +
* Hue – This is a hexadecimal color code in the format 0xARGB. Example: Red is 0xFFFF0000
 +
 +
==== Mobile Component ====
 +
This must exist on any object that can move smoothly across the map using the pathing algorithm. Currently, this is limited to players, NPCs and creatures, however, later this could be expanded to vehicles such as carts and boats.
 +
 +
* BaseRunSpeed – Default is currently 6 (units/sec)
 +
* MobileType – This is used to group mobs together for player targeting purposes. For example, if a mobile is “Friendly” then players will need to force an attack on them. This value is also accessible in the Lua script engine.
 +
 +
==== Object Variable Component ====
 +
 +
Object Variables are for storage of persistent information about the object. This means it is maintained across server restarts. Object variables are attached to the GameObj itself and are accessible to any behavior, even behaviors attached to other GameObjs. For example, the number of PvP kills could be stored on a player object in the “PlayerKills” object variable.
 +
 +
''Modder Tip: Many behaviors expect certain object variables to be set on an object. For example, the ”weapon_base” behavior expects the “WeaponType” object variable to be set.''
 +
 +
==== Script Engine Component ====
 +
 +
This is the component that creates Lua environments for any behaviors attached to the GameObj. These behaviors define what an object can do. For example, attaching the food behavior to an object makes it able to be eaten, or attaching an AI script to a creature.
 +
 +
''Note: Even if your object does not have any Object Variables or Behaviors at creation, it should still have an empty ObjectVariableComponent and ScriptEngineComponent node in its template file. This is because the engine does not yet automatically create these for you when they are needed at runtime. If you are using the template editor tool, this is automatically done for you.''
  
 
== Prefabs ==
 
== Prefabs ==
Line 88: Line 311:
 
Prefabs are usually static objects that can be place on a map, i.e. a building, trees, etc.
 
Prefabs are usually static objects that can be place on a map, i.e. a building, trees, etc.
 
You can use "Default" Celador prefabs, which can be found in Unity's "Project" widget, under "Assets", "Legends of Aria Toolkit", "Default Object Library", "Prefabs".
 
You can use "Default" Celador prefabs, which can be found in Unity's "Project" widget, under "Assets", "Legends of Aria Toolkit", "Default Object Library", "Prefabs".
 +
 +
Make sure you save your Unity project/scene and [[Modding_Guide#Saving_your_mod|rebuild your mapData]] after you added or modified any Prefab to your mod.
 +
 +
=== Permanent Objects (PermanentObj) ===
 +
 +
In order to allow the user to interact with the thousands of rocks and trees on the map without killing server performance, we also have a second, simpler, type of object for them called “Permanent Objects”. These are map objects that never move and have no base properties or behaviors. The only information that is stored for each is a single visual state (Example: a tree could have full, stump and hidden).
 +
 +
=== Client Only Objects ===
 +
 +
These are objects that are built into the map and the server has no access to. This means players and other objects cannot interact with them. A simple example of this is grass or a bridge. Collision for client only objects is also built into the map and cannot be changed.
 +
 +
== Custom Objects ==
 +
 +
If the default set of prefabs from LoA isn't sufficient for you, you can create or import your own objects, either from scratch or using assets available from Unity3D's asset store (Under the "Window" menu, "Asset Store").<br />
 +
'''All of the objects you place on your map also seem to work without setting up your Custom Object Library. Why do it then?'''<br />
 +
The reason for this is because it currently only works due to a problematic bug. Right now Citadel Studios does not use, nor support the method that Unity uses to assign assets to specific bundles.<br />
 +
While it works for now, you do not want to end up having to do tons of work once that changes.<br />
 +
Especially if you use a lot of assets, it can quickly become a staggering amount of work that will be frustrating to get through.<br />
 +
<BR/>
 +
Watch the video on the right for a detailed tutorial.
 +
{{#evt:
 +
service=youtube
 +
|id=https://www.youtube.com/watch?v=yExOhUfYDmA
 +
|alignment=right
 +
}}
 +
 +
==== Things to be mindful of ====
 +
* Do not break prefabs in your scene. The reason you want to work with prefabs in the first place is that if you can easily place them and quickly make changes to the file, which updates all of them in your scene.
 +
* Do not create new prefabs that consisting of old prefabs listed your custom Custom Object Library. It breaks the connection to the old prefabs you group in the new one, and it can get very messy. (This may changed when we upgrade to Unity 2018.2)
 +
* Location matters. Things like your colliders, surfaces and object bounds should be in the first hierarchy level of your prefab.
 +
* The reason we set up object colliders with capsule and box colliders, and not just add collision to the mesh of an object (despite it being so much easier and faster to do) is because of the performance cost. When you have a few higher polygon colliders interacting with each other due to their placement, it can begin to cost a lot.
 +
 +
=== Custom Objects Library ===
 +
 +
The following steps are necessary to create a custom object library:
 +
# In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename that folder with the name of you new library, e.g. "MyCustomLibrary".
 +
# Select that new folder. Under the "LoA Toolkit" menu, select "Custom Assets" then "Create New Custom Object Library". A new "Custom Object Library" library will be created under that folder.
 +
# Click on the "Custom Object Library" and in Unity's "Inspector" widget, set the "Bundle Name" to the same name you used in step 1, e.g. "MyCustomeLibrary".
 +
 +
==== Things to be mindful of ====
 +
* If you are working with multiple Custom Object Libraries, they should never be placed in the same folder.
 +
* Never create a new Custom Object Library in the same folder as an existing one. It will break the old completely.
 +
* If you place a prefab you added to your Custom Object Library into a new prefab you add to your project, it will break the old. This means the old prefab will no longer automatically update if changes are made to the original prefab template.
 +
* Players have to download the whole asset bundle generated by your Custom Object Library each time it is updated (Note: this is done automatically by the LoA client).
 +
 +
=== Creating Object Prefabs ===
 +
 +
The following steps are to create a new "Prefab" Object to be added to your library, and be reused in the game:
 +
# In Unity's "Hierarchy" widget, right-click and select "Create Empty" (an alternative is to go in the "GameObject" menu and "Create Empty" from there). It will create a new empty "GameObject" object, that will be referred as "parent" object in the next steps.
 +
# Rename that "parent" object consistently and, after having selecting it, go in the "Inspector" widget and press "Add Component". Search for "Client Object" and assign it to it.
 +
# When your camera is pointed at a location you want to visualize the object, and while the "parent" object you created is selected in the "Hierarchy", go in the "GameObject" menu and select "Move To View". It shall be centered on your view, sitting on the ground.
 +
# You can now import an external object, e.g. from another library or from your own creation, as a children of the "parent" object that you created in the previous steps. It will probably not be added under the object you created right away, thus make sure you drag it there from the "Hierarchy" widget.
 +
#* If you import an object from an external asset library (e.g. from the asset store), make sure you break the link from its original template. Select the custom object and in the "GameObject" menu, select "Break Prefab Instance".
 +
#* If you import an object, it might already contain a Collider property. Since LoA manages Colliders of its own (cf. here under), make sure you delete any existing Collider from the imported model.
 +
# You might need to apply scaling to that child object so it fits within the scale of the map.
 +
#* Do not apply scaling to the "parent" object, since this one can be manipulated by the client game engine.<BR/>---------------------------------------------------------------------------------------------------------<BR/>
 +
# For all custom objects you are importing/creating, you have to create a bounding box representing the space the object takes up in the world:
 +
## Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
 +
## Rename that new object "ObjectBounds" (exactly that name, or it won't work) and move it as the first child of the "parent" object.
 +
## Select that "ObjectBounds" and in the "Inspector", "Add Component", search for "Box Collider" (LoA only works with Box Colliders) and select it.
 +
## Set the "Box Collider" values in the "Inspector" so it matches what you want. Depending on the object, you might want to create a Bounding Box that is bigger than the object itself (e.g. to leave enough space around a house for placing decorations, etc).<BR/>---------------------------------------------------------------------------------------------------------<BR/>
 +
# If the custom object you are importing/creating is an object that players are supposed to interact with (e.g. grab them), you will have to create a picker object:
 +
## Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
 +
## Rename that new object, e.g. "PickerBounds" (you can choose any name), and move it as the first child of the "parent" object.
 +
## Select that "PickerBounds" and in the "Inspector", change "Layer" to "PickerCollider".
 +
## Select that "PickerBounds" and in the "Inspector", "Add Component", and use any type of Unity Collider best adapted to your object's shape (e.g. "Box Collider" or, more commonly, "Capsule Collider") and select it.
 +
## Set the "Box Collider" values in the "Inspector" so it matches what you want, i.e. to best fit the object (might want to make it bigger if the object is small).<BR/>---------------------------------------------------------------------------------------------------------<BR/>
 +
# If you need Collision detection, so no character can go through that object (e.g. only through a house door or around a tree), you can add 1 or more "Collider"s (i.e. 1 for a tree, several for house walls):
 +
## Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
 +
## Rename that new object "Collider" (exactly that name, or it won't work) and move it as the first child of the "parent" object.
 +
## Select that "Collider" and in the "Inspector", "Add Component", search for "Box Collider" (LoA only works with Box Colliders) and select it.
 +
## Set the "Box Collider" values in the "Inspector" so it matches what you want.
 +
## Repeat the steps above to create as many colliders as needed for this object.<BR/>---------------------------------------------------------------------------------------------------------<BR/>
 +
# If the custom object you are importing/creating is a house or building, you will probably need to create collapsible roofs and walls for inside view:
 +
## Watch the video listed above for a detailed description<BR/>---------------------------------------------------------------------------------------------------------<BR/>
 +
# When done editing, drag the finalized object from "Hierarchy" into your custom library folder in Unity's "Project" widget.
 +
# Click on your custom objects library in the "Project" widget and click on "Add Field". A new empty "Element" entry will be created.
 +
# Drag the custom object from the custom library folder in "Project" in the field next to the new "Element" in "Inspector". You can alternatively press the round button next to the field and search for your custom object in the window that opens.
 +
# Save your Unity project/scene and [[Modding_Guide#Saving_the_custom_objects_library|build the custom assets library]].
 +
# If you just need the object you created as a template, and not an instance in the world, i.e. not as a static object in the world, you can delete the object from Unity's "Hierarchy" widget. You can reuse it later from your custom object library later or use it inside a Lua script.
 +
<BR/>
 +
Repeat those steps above for any new custom object you are creating.<BR/>
 +
''Note: If you modify any property from a custom object in Unity's "Hierarchy", and you want that change to be taken into account in the template, make sure you click in Unity's "Inspector" widget on the "Apply" button of "Prefab"''
 +
 +
=== Saving the custom objects library ===
 +
 +
Once you have created all your custom objects, or adding any new ones, or editing any existing ones, make sure you (re)build the library:
 +
# In Unity's "Project" widget, select your custom objects library asset, which is under [[Modding_Guide#Custom_Objects_Library|the folder you created earlier in this section]].
 +
# In Unity's "Inspector" widget, press the "Build" button. This will take several minutes. Alternatively, you can also "Build" your mapData, this will also trigger building the custom objects library.
 +
# Make sure you have edited the "Mod" section of your server "ClusterConfig.xml" file to add the consistent "<ClientBundle Type="ClientObjects" ...>".
 +
 +
=== Object Templates ===
 +
 +
Object templates are custom objects that you can dynamically spawn within the game, either by a player with enough rights to do so, or through a Lua script.
 +
 +
# Make sure you first [[Modding_Guide#Creating_Object_Prefabs|created that custom object]] and added it to [[Modding_Guide#Custom_Objects_Library|your custom objects library]].
 +
# Go to your mod's template folder, located under <server>\mods\''YOUR MOD NAME''\templates (You can create sub-folders as needed for your organization, i.e. by category/group or region, since sub-folders are ignored by the engine).
 +
# Create a XML file for your object template, e.g. <object_template.xml> and open it for editing
 +
# Fill the file with a basic description:<BR/>
 +
<syntaxhighlight lang="xml">
 +
<ObjectTemplate>
 +
        <ClientId>In Unity3D's "Project", select your asset prefab from the custom objects folder, put here the value of "Client Id", e.g. 584</ClientId>
 +
        <Name>Put here the name of your custom object, e.g. MyCustomObject</Name>
 +
        <CustomAssetBundle>Put here the name of your custom library, e.g. MyCustomLibrary</CustomAssetBundle>
 +
        <SharedStateEntry name="Weight" type="int" value="1"/>
 +
</ObjectTemplate>
 +
</syntaxhighlight>
 +
 +
Save the file. You can now try running the server, logging as a "God" character and use the "/create" call to instantiate your object.
 +
 +
== Custom Textures / Map Images / Loading Screens ==
 +
 +
Custom textures, map images, and loading screens are supported via the creation of a UI Texture Library prefab from Toolkit 0.8.3 and higher.
 +
All three of these are handled by the creation of a UI Texture Library object.
 +
 +
=== UI Texture Library ===
 +
 +
The following steps are necessary to create a custom ui texture library:
 +
# In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename that folder with the name of you new library, e.g. "MyUITexturesLibrary".
 +
# Select that new folder. Under the "LoA Toolkit" menu, select "Custom Assets" then "Create UI Texture Library". A new "UI Texture Library" library will be created under that folder.
 +
# Click on the "UI Texture Library" and in Unity's "Inspector" widget, set the "Bundle Name" to the same name you used in step 1, e.g. "MyUITexturesLibrary".
 +
# In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename this folder to "UI". Inside the UI folder do the same thing again but this time name it "Textures", also create a "Maps" and "Loading" folders.
 +
 +
=== Adding custom textures to your UI Texture Library ===
 +
 +
Simply place your custom image files (PNG Format) inside the Assets/UI/Textures folder you created above.
 +
 +
=== Adding custom map images to your UI Texture Library ===
 +
 +
TBD
 +
 +
=== Adding custom loading screen images to your UI Texture Library ===
 +
 +
TBD
 +
 +
=== Saving the ui texture library ===
 +
 +
Once you have added all your custom textures, or editing existing ones, make sure you (re)build the library:
 +
# In Unity's "Project" widget, select your ui texture  library asset, which is under the folder you created earlier in this section.
 +
# In Unity's "Inspector" widget, press the "Build" button. This will take several minutes.
 +
# Make sure you have edited the "Mod" section of your server "ClusterConfig.xml" file to add the consistent "<ClientBundle Type="ClientObjects" ...>".
 +
 +
== World Streamer Support ==
 +
 +
The 3rd party World Streamer addon is supported from Toolkit 0.8.3 and higher for creation of large maps. This addon requires the following modifications in order to work with Legends of Aria:
 +
# Add the following additions to WorldStreamer\Scripts\Streamer.cs
 +
<syntaxhighlight lang="c">
 +
//Add to line 84
 +
public bool loadingRangeInUnits = true;
 +
 +
//Add the following starting at line 841
 +
int loadingRangeX = (int)loadingRange.x;
 +
int loadingRangeY = (int)loadingRange.y;
 +
int loadingRangeZ = (int)loadingRange.z;
 +
if(loadingRangeInUnits)
 +
{
 +
    loadingRangeX = 1;
 +
    loadingRangeY = 1;
 +
    loadingRangeZ = 1;
 +
}
 +
</syntaxhighlight>
 +
 +
=== Setting up a project for World Streamer ===
 +
# Inside your Unity Project Build Settings/Player Settings/Scripting Define Symbols add WORLD_STREAMER_ENABLED
 +
# Add MapDataTerrain.cs to each Terrain object in any Map using World Streamer (This will force update Surface collision)
 +
# To be continued.

Latest revision as of 14:01, 2 September 2021

Disclaimer

This guide is mostly intended to non-professional Unity3D developers & designers, i.e. beginners who are motivated to mod using the LoA engine.
Actually, current contributors of this guide are relatively new to Unity3D and Lua/C#, with little to no experience with those before starting to work on a Legends of Aria server.
The concepts and details given in this guide are mostly the basics to get you up-and-running on a first mod. As you will want to improve your mod, you will certainly have to go further into the details and complexity of Unity3D editing and Lua, or even C#, programming ... which won't necessarily be covered here as the capabilities of modding are quite large, and you might even try something nobody tried before.
As Citadel Studios still is making a great deal of changes to map creation, parts of this guide may at times become out of date. For that matter, do not hesitate to give us feedback on this guide (what need to be clarified, detailed, updated/corrected, etc), or even to edit it yourself to keep the momentum going.

Tips for Beginners

Backup Regularly. Be sure to always back up your complete unity project on a regular basis.

Ask For Help. We can not stress this enough. Ask for help. Unity has a steep learning curve. You are working in a professional game engine. If you encounter issues, do not try to figure it out yourself for hours on end. Instead, ask for help. On top of that, you might actually be doing everything right. The LoA toolkit still has quite it's share of bugs, and you do not want to be spending time kicking yourself because you think you screwed up. So, you guessed it, ask for help. If you are worried your question might be dumb, still ask for help. You are a modder, not a professional game developer. We all have to start somewhere. There are currently 2 Discord communities dealing with LoA server & modding, do not hesitate to request joining them: "Shards Online Admins" and "Community Projects - LoA"

Start Small. For your first project, start with a very small map and work on it from start to finish. That is the best way to familiarize you with all of the steps, know how everything interacts, and get a sense of how much time what takes.

List of current Issues & Bugs

We're trying to maintain a list of current issues and bugs you might encounter here.

Capabilities

What can I mod? What can't I mod?

  • The Official Map is currently moddable in a very limited way. You can not change the terrain mesh geometry or textures, nor remove any static objects.
  • Custom Equipment is currently not moddable in Unity.
  • Custom Maps can be made in Unity and run in game.
  • Custom Assets (such as custom objects) can already be added and set up for the client to properly use.
    • This includes adding object or surface collision, transparency colliders or collapsible roofs for houses, as well as object bounds and picker boxes for support players to be able to interact with them.
  • Custom Maps currently do not support a proper SFX set up. Both music and environment effects can be placed in the scene for testing and they will play in the client. However, you can not lower or increase the volume in the client properties.

Necessary Tools

For the time being, modding is only feasible on Windows machines.

  1. Unity 3D editor: Download Unity3D Installer version 2018.3.4f1. You will need to create an account.
    • Note: When you download and install Unity, to be sure to also download and install the standard assets. It is possible to install unity without these. If you do, then you will need to manually add them to be able to import.
  2. Editing Lua scripts and XML files: Download Sublime Text or any other editor with syntax highlighting, e.g. Notepad++.
  3. The latest Legends of Aria Toolkit.

Note: Unity3D useful tip to move the camera: Press right-clight to enter "WASD" camera control mode. Add 'SHIFT' to accelerate camera movement.

Creating a new project, based or not on the Celador map

Watch the video on the right, introducing the setup.

Mod Folder Structure

NOTE: You must have first installed a LoA server before to proceed with the direction below.

  1. Launch Unity3D, create a "New" "3D" project, assigning it with a name, preferably in a folder of your choice. No Unity Analytics is needed.
  2. Import assets: in "Assets" menu, "Import Package" and import both "Effects" and "Environment" (Press "Import" for each new window opening).
    • Do not import any other standard packages. A common mistake is that new map creators believe it is better to import all of the standard assets. It is not. It may break your project. I will get into that a little further down the road when we cover custom assets.
    • The Standard Assets package from the asset store is not the same as the one you import here. The one from the asset store can actually break your project. If you do not see them, the unity download you used does not include the files. You will need to download them manually and add them. The guide for this is at the end of this chapter.
  3. From the Assets store (in "Window" menu, select "Asset Store"), search for the "Post Processing Stack" package ("Unity Essentials" from "Unity Technologies"), install and import it.
    • The Post Processing Stack is made by Unity and is free. It combines a complete set of image effects into a single post-process pipeline. As Legends of Aria recently began to use post-processing profiles on it's camera, you want to have this for everything to function properly.
  4. in "Assets" menu, "Import Package", import "Custom Package" and select the Legends of Aria Toolkit you previously downloaded. Click "Import" on the new widow, this will take several minutes.
  5. You should now have a new "LoA Toolkit" menu item in Unity3D.
  6. Under that new menu item, select "Settings".
  7. "Browse" the "Base Path" to reflect the path: <server>\Build\base
  8. "Browse" the "mods Path" to reflect the path: <server>\mods
  9. Press "Save".
  10. If you are editing a mod that you already created, select the consistent mod name in the "Mod" pull-down list (You might have to "save" first and reopen the Settings).
  11. If you are starting a new mod, select "Create Mod" under the "LoA Toolkit" menu.

Your Mods folder under <server> should then reflect the structure displayed on the right.

Compatible Unity Assets

Citadel Studio currently does not provide a list of the content they use for their official server.

Here under is a list of assets that have been tested by members, and are available on the Unity Asset Store (under "Window", "Asset Store"). Besides for the "Post Processing Stack", they are optional.

We are not listing here Object assets, since there are certainly plenty out there and they shall all be compatible, but rather utility assets which are helping design better-looking maps. Be aware that while there are plenty of free assets out there, many come at a cost and will depend on your willingness to spend money to get a better-looking world. You could certainly avoid using those if you're a professional 3D game designer, but for the most of us, using such assets is a necessity (unless you're willing e.g. to spend days/weeks manually editing your terrain). Do not feel however pressured to spend money to get tools or content for your project. There is a good amount of content provided by Citadel Studios. The biggest difference in the quality of your maps you will get out of actual experience of making them. There is also a great deal of free content available online, and there are regular sales every few months on the Unity Asset Store if you do want to get some custom content.

Asset Name Editor Cost
Post Processing Stack Unity Technologies Free
Terrain Toolkit 2017 Heparo Free
Relief Terrain Pack Tomasz Stobierski $40
Vegetation Studio Awesome Technology $75
SpeedTree SpeedTree $19/mo (a few free assets in the store, can also just buy trees packages)

Modding the Celador maps

  1. Look in Unity's "Project" widget, select the "Legends of Aria Toolkit" folder and double-click on the "ShardsToolkit.unity" Unity asset (It's a scene map loader helper).
  2. Select the "Game" above the viewer window and press the "Play" button on the top right of that same window.
  3. You can select any scene map to be loaded by pressing its button.
    • For "New Celador", there is an exception: the map is split into sub-scenes because it is very big: Under the "LoA Toolkit" menu, select "Utils" then "World Streamer Manager". You can then select a "Preset" selection of scene respective to the area(s) you are looking to edit. You can alternatively load individual scenes by clicking on them.
  4. Switch to the "Scene" view by pressing the "#Scene" button above the Unity viewer (from the "Game" view you currently are on).
  5. You can add Prefabs to the map, as well as Seed Objects (cf. below).

Make sure you save your mod after edition.

Modder Tip: Not all files in the base folder are overridable (moddable). Here is a full list of these files:

  • ClientIdReference.txt
  • ObjectCollisionData.xml
  • ObjectTagDefinitions.xml
  • mapdata/MAPNAME/StaticCollision.xml

Starting a new map

Watch the video for on the right for more detail.

  1. From the "LoA Toolkit" menu, select "Custom Assets", then "Create New Custom Map". You can choose either it's an exterior or interior map. A new "MapData" asset will be created under your new "Untitled" (a least until you save it) unity scene in Unity's "Hierarchy" widget.
    • The reason we are creating our new scene this way and not the way you would normally in Unity is that this will add a couple of important things to your scene for you. These are the MapData object, the DefaultOutdoorLighting or DefaultIndoorLighting objects, and the DefaultOutdoorCamera or DefaultIndoorCamera objects. You should always have these in your scene. If you do not, something went wrong.
  2. Create a new terrain, either by right clicking in the "Hierarchy" widget or under the "GameObject" menu, then "3D Object" and "Terrain".
    • Note: It is important to position the Terrain object in the "Hierarchy" widget as a top node, i.e. not under any other object (including not under the "MapData" object). Drag the Terrain object if needed.
  3. You can edit the terrain properties (size, center, texture, etc.) from Unity's "Inspector" widget. You can also use some Unity Terrain generators to help you create terrains easily (some are free in Unity's asset store)
  4. You can now add Prefabs to the map, as well as Seed Objects (cf. below).

Make sure you save your mod after edition.

Useful Map Features

  • How to add wind to your map.
  • How to add lighting to your scene.
    • At some point you will begin to look into how to do the lighting for your scene. You will hear terms like Linear and Gama Color Space, as well as baked lighting and real time lighting. You may also want to look into giving your map that extra polish by creating post-processing profiles for your scene.

Map Controllers & Regions

Watch the video on the right for a tutorial.

Controllers are invisible objects that are managing the normal functioning of a map, like day/night cycle, weather, spawns, protection of the area, etc.

  1. You first need to create a new template for the controller.
    1. Under Windows Explorer, go to your <server>\YOUR MOD NAME\templates\ folder and create a new XML file for your controller. Optionally, the template file can be created in any sub-folders, which is a good practice to stay organized. A good practice as well is to split controllers by category (weather, day/night, spawns, etc.)
    2. Fill the file with some controller data. Check an example here under, and the templates from the Celador controllers, which can be found in <server>\Build\base\templates\celador
  2. Back in Unity3D, under the "LOA Toolkit" menu, select "Dynamic Editors" then "Region Editor" (usually have to retry, since it doesn't load correctly the first time).
  3. Select your Mod Name. Click "Create a new Region". A "Regions" parent object will appear in Unity's "Hierarchy" widget (if there wasn't one already), with a "New Region" object underneath. You can rename it.
    • Naming the newly created region "GuardZoneLarge" will make the area guard protected.
  4. Selecting that new Region object in "Hierarchy", you can now press "Add Node". A new "RegionArea" object will be created under the Region object. In "GameObject" menu, select "Move To View" when your camera points at the location you want that object to be positioned.
  5. Change the size of this new "RegionArea" object to match the zone you want to cover on the map.
    • For certain controllers, e.g. weather, you will need to create very big Regions.
  6. Press "Save Regions" to make sure you save your work. You can optionally delete the "Regions" parent node now (or press the "Reset Regions" button).
  7. If you haven't loaded your Seed Objects yet, reload them.
  8. Click on "Create a New Seed Object" and "Select" to assign it the template you created above (If you created folders, look for the folder name first).
  9. In "GameObject" menu, select "Move To View" when your camera points at the location you want that object to be positioned.
  10. Once done, save your Seed Objects (and remove them) and save your mod.

An example of XML content for a day/night time controller:

<ObjectTemplate>
        <ClientId>2</ClientId>
        <Color>0xFF00FF00</Color>
        <Name>Time Controller</Name>
        <Tag>TimeController</Tag>
        <ObjectVariableComponent/>			
        <ScriptEngineComponent>
                <LuaModule Name="shard_time_controller">
                        <Initializer>
                                {
                                        DaylightDurationSecs = 45 * 60,
                                        NighttimeDurationSecs = 15 * 60,
                                }
                        </Initializer>
                </LuaModule>
        </ScriptEngineComponent>

Static Map Collision

While this section is early in the guide, you shouldn't do this step before your map is pretty much complete. In order to block player from getting to some areas, e.g. cliffs, map borders, river beds, etc, you want to add some static map collisions. This tool is pretty rudimentary, and is using a painted 2D map. Collision maps are a 2d plane you can texture paint with the texture brush. Black is traversable (and does not display), white represents collision and is not traversable (and displays).

Watch the video on the right for a tutorial.

  1. To paint your collision map, go to to the "LoA Toolkit" drop-down menu, select "Dynamic Editors", then "Collision Editor"
    • Make sure the "Current Mod" is your mod, otherwise re-select your mod from the "LoA Toolkit" Menu, "Settings".
  2. Switch to top down isometric view, by pressing the green 'Y' axis locator then the cube at the top right of the scene window (should then display "Top" underneath), and reposition your camera to have a full view of your map.
  3. Press the "New Static Collision" button. A new scene with a set of 4 planes will be created in Unity's "Hierarchy" (names starting with "Collision").
    • If you map is pretty elevated, you might want to change the height of those planes to have a better view on them using the "Collision Terrain Y" positioner.
  4. Press the "Show Selected Area" checkbox to be able to visualize which plane you are editing (yellow highlight).
  5. Repeat the next sub-steps here under for each plane
    1. Select the plane in the "Hierarchy". In its "Inspector" widget, select "paint texture" button (the 4th one). Select the white color and the hard border round brush (the 4th one). You can reduce the size of the brush if needed.
    2. Zoom as needed on your map and move the plane's Y to adjust as close to the map as you can. In the scene, draw the parts that players will collide against.
  6. When done, press the "Save Static Collision" button, and delete the scene that was created during step 3 (select "Don't Save").
  7. Make sure you save your mod after edition.

Saving your mod

  1. First, make sure you have saved your Unity project, saved all your seed objects (if any), built your custom objects library (if any).
  2. When done, select "MapData" in Unity's "Hierarchy" widget. Select "Reset Permanent IDs" (unless you have a script that refers to any Permanent IDs) in Unity's "Inspector" widget and press "Build". If you haven't saved the Unity project or scene yet, Unity will require you to save it first.
  3. To make sure your server loads your modifications, make sure you consistently edit the "<Mod>" section of the ClusterConfig.xml file, i.e. put your mod name there.
  4. If you have created a new map, make sure you add a "<ClientBundle>" subsection in that section and add or edit the consistent "<Region>".
  5. Also, make sure you clean up all your server backups before to reload it (careful of what you delete as well, like characters' data, if you're in production).

Potential issues

Here is a list of potential issues you might encounter when testing your mod, and ways to fix those:

  • Custom objects collision not working properly, especially on custom maps, even though you are 100% sure your collision is set up correctly.
    • This might be a "Terrain" issue. Make sure your Terrain object isn't under another object, i.e. is at the top level of the Hierarchy, and that it doesn't contain any child object.
    • This might also be a cache issue. You can try to delete the folders related to your mod (usually starting with your mod name) in <C:\Users\YOUR WINDOWS ACCOUNT NAME\AppData\LocalLow\Unity\Citadel Studios Inc__Legends of Aria>
      • A cache issue impacting Collision will usually return some "Invalid client path" warnings on the server shell and the server will "bump" the char to a correct location. This is because the server collision detection works and the client isn't because its cache hasn't been updated.
  • Weather not playing properly when you're sure the weather is active and the player is in the correct area:
    • You need to have a region called "NoWeather" in your custom map. You can put it inside e.g. a mine, or somewhere it will not interact with players.

Dynamic Game Objects (GameObj)

Legends of Aria is a true world simulation in the sense that there are very little arbitrary rules on the dynamic game objects in the world. Dynamic game objects (GameObjs) can be placed anywhere and are defined by their properties. GameObjs that contain a mobile component can move smoothly throughout the world using the pathing algorithm. All GameObjs are created from templates. The template is the definition for the initial state of an object at creation. It defines things like: What does it look like (Client Id)? What is its name? What sorts of behaviors does this object have? etc. Once the GameObj is created, the template is never referenced again and every property about that object can be changed by scripts or god powers.

NOTE: In Lua, the reference type for dynamic game objects is GameObj and we will refer to them as such in this handbook.

Seed Objects

Seed objects are dynamic object that spawns when the server resets or when loaded the first time. Many of these “Seed Objects” are invisible to mortal players and are used as a source for controller scripts. The simplest and most common example of a controller script is a spawner, a behavior that spawns other GameObjs like monsters or animals on the map. In Unity3D, they can be grouped, under "category" or "group", so they can be loaded, saved and edited all at once or separately. Celador base map's Seed Objects are grouped by zone and types.

In Unity3D, to access Seed Objects functionality, in the "LoA Toolkit" menu, select "Dynamic Editors" then "Seed Object Editor".

Tips:

  • You only need to load your seed objects when you need to add or edit some.
  • Once saved, you can delete them all from the scene: In the "LoA Toolkit", go to "Dynamic Editors" then "Seed Object Editor" and press "Reset Seed Objects". This will save some resources.

Loading

If you are editing from the Celador base map, select the "Default" "Mod", otherwise load your module's specific group (if not already loaded). You can select in the "Seed Object Editor" to "Load All Seed Objects" or the specific "Group" that you want to load to edit.

Creating an Instance

It is advised to create groups/categories to have a finer detail of finding, editing and saving/loading of seed objects. In order to do this, click on "Create New Category" on the "Seed Object Editor" window. You can rename each category or seed object from Unity's "Hierarchy" widget. Then you can "Create New Seed Object" from the "Seed Object Editor" window. You will want to drag that "New Seed" object within the consistent category (that you created above) in Unity's "Hierarchy" widget, and rename it. Then select that seed in the "Hierarchy" widget and you will see Unity's "Inspector" widget updating, as well as the bottom of the "Seed Object Editor" window, showing "Seed Object Selected". You can "Select" a template to be used for that seed (You might have to re-select "Default" for "Mod" to get all the templates if you had changed it before).

A useful thing when your editing point-of-view is pointing at the location you want to place your item at, is to use the "GameObject" menu's "Move To View" function. Double-clicking on an object in Unity's "Hierarchy" will move the point-of-view to point to the object's location.

Make sure you save your seed objects when done.

Saving

If you have modified any group of seed object or single object from the "Default" Celador map, make sure you select your "Mod" in the "Seed Object Editor" before saving. Ditto if you want to override any "Default" group, you can also create a group of the same name of a "Default" Celador group to override.

You can choose to "Save All Seed Objects" or select individual groups/categories to be saved. Make sure you save the seeds as often as possible not to loose your work (since it's independent from Unity's scene/project saving).

Properties

If you understand all of the different types of properties and behaviors that can be assigned to GameObjs then you essentially understand how Legends of Aria works at its core. Let’s quickly go through these properties and behaviors (some will be explained in more detail later).

Base Properties

These properties exist on every GameObj in the game. If a property is not defined in the template, it will fall back to its default value (assuming it’s not required)

  • ClientId (required) – This is the art asset id the client uses to display this object. It also determines which Shared Object Properties (See section under Lua Script Engine) this object has and their default values.
  • Name - Modder Tip: Nearly every string in the game, including names, can be color coded. It uses html color codes in square brackets and is terminated with a dash in square brackets. Example: A blue string would be “[0000FF]Blue String[-]”
  • ScaleModifier – Optionally modifies the size of the object by multiplying the default scale of the object by this value.
  • Hue – This is a hexadecimal color code in the format 0xARGB. Example: Red is 0xFFFF0000

Mobile Component

This must exist on any object that can move smoothly across the map using the pathing algorithm. Currently, this is limited to players, NPCs and creatures, however, later this could be expanded to vehicles such as carts and boats.

  • BaseRunSpeed – Default is currently 6 (units/sec)
  • MobileType – This is used to group mobs together for player targeting purposes. For example, if a mobile is “Friendly” then players will need to force an attack on them. This value is also accessible in the Lua script engine.

Object Variable Component

Object Variables are for storage of persistent information about the object. This means it is maintained across server restarts. Object variables are attached to the GameObj itself and are accessible to any behavior, even behaviors attached to other GameObjs. For example, the number of PvP kills could be stored on a player object in the “PlayerKills” object variable.

Modder Tip: Many behaviors expect certain object variables to be set on an object. For example, the ”weapon_base” behavior expects the “WeaponType” object variable to be set.

Script Engine Component

This is the component that creates Lua environments for any behaviors attached to the GameObj. These behaviors define what an object can do. For example, attaching the food behavior to an object makes it able to be eaten, or attaching an AI script to a creature.

Note: Even if your object does not have any Object Variables or Behaviors at creation, it should still have an empty ObjectVariableComponent and ScriptEngineComponent node in its template file. This is because the engine does not yet automatically create these for you when they are needed at runtime. If you are using the template editor tool, this is automatically done for you.

Prefabs

Prefabs are usually static objects that can be place on a map, i.e. a building, trees, etc. You can use "Default" Celador prefabs, which can be found in Unity's "Project" widget, under "Assets", "Legends of Aria Toolkit", "Default Object Library", "Prefabs".

Make sure you save your Unity project/scene and rebuild your mapData after you added or modified any Prefab to your mod.

Permanent Objects (PermanentObj)

In order to allow the user to interact with the thousands of rocks and trees on the map without killing server performance, we also have a second, simpler, type of object for them called “Permanent Objects”. These are map objects that never move and have no base properties or behaviors. The only information that is stored for each is a single visual state (Example: a tree could have full, stump and hidden).

Client Only Objects

These are objects that are built into the map and the server has no access to. This means players and other objects cannot interact with them. A simple example of this is grass or a bridge. Collision for client only objects is also built into the map and cannot be changed.

Custom Objects

If the default set of prefabs from LoA isn't sufficient for you, you can create or import your own objects, either from scratch or using assets available from Unity3D's asset store (Under the "Window" menu, "Asset Store").
All of the objects you place on your map also seem to work without setting up your Custom Object Library. Why do it then?
The reason for this is because it currently only works due to a problematic bug. Right now Citadel Studios does not use, nor support the method that Unity uses to assign assets to specific bundles.
While it works for now, you do not want to end up having to do tons of work once that changes.
Especially if you use a lot of assets, it can quickly become a staggering amount of work that will be frustrating to get through.

Watch the video on the right for a detailed tutorial.

Things to be mindful of

  • Do not break prefabs in your scene. The reason you want to work with prefabs in the first place is that if you can easily place them and quickly make changes to the file, which updates all of them in your scene.
  • Do not create new prefabs that consisting of old prefabs listed your custom Custom Object Library. It breaks the connection to the old prefabs you group in the new one, and it can get very messy. (This may changed when we upgrade to Unity 2018.2)
  • Location matters. Things like your colliders, surfaces and object bounds should be in the first hierarchy level of your prefab.
  • The reason we set up object colliders with capsule and box colliders, and not just add collision to the mesh of an object (despite it being so much easier and faster to do) is because of the performance cost. When you have a few higher polygon colliders interacting with each other due to their placement, it can begin to cost a lot.

Custom Objects Library

The following steps are necessary to create a custom object library:

  1. In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename that folder with the name of you new library, e.g. "MyCustomLibrary".
  2. Select that new folder. Under the "LoA Toolkit" menu, select "Custom Assets" then "Create New Custom Object Library". A new "Custom Object Library" library will be created under that folder.
  3. Click on the "Custom Object Library" and in Unity's "Inspector" widget, set the "Bundle Name" to the same name you used in step 1, e.g. "MyCustomeLibrary".

Things to be mindful of

  • If you are working with multiple Custom Object Libraries, they should never be placed in the same folder.
  • Never create a new Custom Object Library in the same folder as an existing one. It will break the old completely.
  • If you place a prefab you added to your Custom Object Library into a new prefab you add to your project, it will break the old. This means the old prefab will no longer automatically update if changes are made to the original prefab template.
  • Players have to download the whole asset bundle generated by your Custom Object Library each time it is updated (Note: this is done automatically by the LoA client).

Creating Object Prefabs

The following steps are to create a new "Prefab" Object to be added to your library, and be reused in the game:

  1. In Unity's "Hierarchy" widget, right-click and select "Create Empty" (an alternative is to go in the "GameObject" menu and "Create Empty" from there). It will create a new empty "GameObject" object, that will be referred as "parent" object in the next steps.
  2. Rename that "parent" object consistently and, after having selecting it, go in the "Inspector" widget and press "Add Component". Search for "Client Object" and assign it to it.
  3. When your camera is pointed at a location you want to visualize the object, and while the "parent" object you created is selected in the "Hierarchy", go in the "GameObject" menu and select "Move To View". It shall be centered on your view, sitting on the ground.
  4. You can now import an external object, e.g. from another library or from your own creation, as a children of the "parent" object that you created in the previous steps. It will probably not be added under the object you created right away, thus make sure you drag it there from the "Hierarchy" widget.
    • If you import an object from an external asset library (e.g. from the asset store), make sure you break the link from its original template. Select the custom object and in the "GameObject" menu, select "Break Prefab Instance".
    • If you import an object, it might already contain a Collider property. Since LoA manages Colliders of its own (cf. here under), make sure you delete any existing Collider from the imported model.
  5. You might need to apply scaling to that child object so it fits within the scale of the map.
    • Do not apply scaling to the "parent" object, since this one can be manipulated by the client game engine.
      ---------------------------------------------------------------------------------------------------------
  6. For all custom objects you are importing/creating, you have to create a bounding box representing the space the object takes up in the world:
    1. Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
    2. Rename that new object "ObjectBounds" (exactly that name, or it won't work) and move it as the first child of the "parent" object.
    3. Select that "ObjectBounds" and in the "Inspector", "Add Component", search for "Box Collider" (LoA only works with Box Colliders) and select it.
    4. Set the "Box Collider" values in the "Inspector" so it matches what you want. Depending on the object, you might want to create a Bounding Box that is bigger than the object itself (e.g. to leave enough space around a house for placing decorations, etc).
      ---------------------------------------------------------------------------------------------------------
  7. If the custom object you are importing/creating is an object that players are supposed to interact with (e.g. grab them), you will have to create a picker object:
    1. Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
    2. Rename that new object, e.g. "PickerBounds" (you can choose any name), and move it as the first child of the "parent" object.
    3. Select that "PickerBounds" and in the "Inspector", change "Layer" to "PickerCollider".
    4. Select that "PickerBounds" and in the "Inspector", "Add Component", and use any type of Unity Collider best adapted to your object's shape (e.g. "Box Collider" or, more commonly, "Capsule Collider") and select it.
    5. Set the "Box Collider" values in the "Inspector" so it matches what you want, i.e. to best fit the object (might want to make it bigger if the object is small).
      ---------------------------------------------------------------------------------------------------------
  8. If you need Collision detection, so no character can go through that object (e.g. only through a house door or around a tree), you can add 1 or more "Collider"s (i.e. 1 for a tree, several for house walls):
    1. Select the "parent" object and under the "GameObject" menu, select "Create Empty Child".
    2. Rename that new object "Collider" (exactly that name, or it won't work) and move it as the first child of the "parent" object.
    3. Select that "Collider" and in the "Inspector", "Add Component", search for "Box Collider" (LoA only works with Box Colliders) and select it.
    4. Set the "Box Collider" values in the "Inspector" so it matches what you want.
    5. Repeat the steps above to create as many colliders as needed for this object.
      ---------------------------------------------------------------------------------------------------------
  9. If the custom object you are importing/creating is a house or building, you will probably need to create collapsible roofs and walls for inside view:
    1. Watch the video listed above for a detailed description
      ---------------------------------------------------------------------------------------------------------
  10. When done editing, drag the finalized object from "Hierarchy" into your custom library folder in Unity's "Project" widget.
  11. Click on your custom objects library in the "Project" widget and click on "Add Field". A new empty "Element" entry will be created.
  12. Drag the custom object from the custom library folder in "Project" in the field next to the new "Element" in "Inspector". You can alternatively press the round button next to the field and search for your custom object in the window that opens.
  13. Save your Unity project/scene and build the custom assets library.
  14. If you just need the object you created as a template, and not an instance in the world, i.e. not as a static object in the world, you can delete the object from Unity's "Hierarchy" widget. You can reuse it later from your custom object library later or use it inside a Lua script.


Repeat those steps above for any new custom object you are creating.
Note: If you modify any property from a custom object in Unity's "Hierarchy", and you want that change to be taken into account in the template, make sure you click in Unity's "Inspector" widget on the "Apply" button of "Prefab"

Saving the custom objects library

Once you have created all your custom objects, or adding any new ones, or editing any existing ones, make sure you (re)build the library:

  1. In Unity's "Project" widget, select your custom objects library asset, which is under the folder you created earlier in this section.
  2. In Unity's "Inspector" widget, press the "Build" button. This will take several minutes. Alternatively, you can also "Build" your mapData, this will also trigger building the custom objects library.
  3. Make sure you have edited the "Mod" section of your server "ClusterConfig.xml" file to add the consistent "<ClientBundle Type="ClientObjects" ...>".

Object Templates

Object templates are custom objects that you can dynamically spawn within the game, either by a player with enough rights to do so, or through a Lua script.

  1. Make sure you first created that custom object and added it to your custom objects library.
  2. Go to your mod's template folder, located under <server>\mods\YOUR MOD NAME\templates (You can create sub-folders as needed for your organization, i.e. by category/group or region, since sub-folders are ignored by the engine).
  3. Create a XML file for your object template, e.g. <object_template.xml> and open it for editing
  4. Fill the file with a basic description:
<ObjectTemplate>
        <ClientId>In Unity3D's "Project", select your asset prefab from the custom objects folder, put here the value of "Client Id", e.g. 584</ClientId>
        <Name>Put here the name of your custom object, e.g. MyCustomObject</Name>
        <CustomAssetBundle>Put here the name of your custom library, e.g. MyCustomLibrary</CustomAssetBundle>
        <SharedStateEntry name="Weight" type="int" value="1"/>
</ObjectTemplate>

Save the file. You can now try running the server, logging as a "God" character and use the "/create" call to instantiate your object.

Custom Textures / Map Images / Loading Screens

Custom textures, map images, and loading screens are supported via the creation of a UI Texture Library prefab from Toolkit 0.8.3 and higher. All three of these are handled by the creation of a UI Texture Library object.

UI Texture Library

The following steps are necessary to create a custom ui texture library:

  1. In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename that folder with the name of you new library, e.g. "MyUITexturesLibrary".
  2. Select that new folder. Under the "LoA Toolkit" menu, select "Custom Assets" then "Create UI Texture Library". A new "UI Texture Library" library will be created under that folder.
  3. Click on the "UI Texture Library" and in Unity's "Inspector" widget, set the "Bundle Name" to the same name you used in step 1, e.g. "MyUITexturesLibrary".
  4. In Unity's "Project" widget, Select "Assets" and right-click "Create" then "Folder". Rename this folder to "UI". Inside the UI folder do the same thing again but this time name it "Textures", also create a "Maps" and "Loading" folders.

Adding custom textures to your UI Texture Library

Simply place your custom image files (PNG Format) inside the Assets/UI/Textures folder you created above.

Adding custom map images to your UI Texture Library

TBD

Adding custom loading screen images to your UI Texture Library

TBD

Saving the ui texture library

Once you have added all your custom textures, or editing existing ones, make sure you (re)build the library:

  1. In Unity's "Project" widget, select your ui texture library asset, which is under the folder you created earlier in this section.
  2. In Unity's "Inspector" widget, press the "Build" button. This will take several minutes.
  3. Make sure you have edited the "Mod" section of your server "ClusterConfig.xml" file to add the consistent "<ClientBundle Type="ClientObjects" ...>".

World Streamer Support

The 3rd party World Streamer addon is supported from Toolkit 0.8.3 and higher for creation of large maps. This addon requires the following modifications in order to work with Legends of Aria:

  1. Add the following additions to WorldStreamer\Scripts\Streamer.cs
//Add to line 84
public bool loadingRangeInUnits = true;

//Add the following starting at line 841
int loadingRangeX = (int)loadingRange.x;
int loadingRangeY = (int)loadingRange.y;
int loadingRangeZ = (int)loadingRange.z;
if(loadingRangeInUnits)
{
    loadingRangeX = 1;
    loadingRangeY = 1;
    loadingRangeZ = 1;
}

Setting up a project for World Streamer

  1. Inside your Unity Project Build Settings/Player Settings/Scripting Define Symbols add WORLD_STREAMER_ENABLED
  2. Add MapDataTerrain.cs to each Terrain object in any Map using World Streamer (This will force update Surface collision)
  3. To be continued.