README.org 5.04 KB
Newer Older
Oliver Mead's avatar
Oliver Mead committed
1
2
#+TITLE: DOTS Info

Oliver Mead's avatar
Oliver Mead committed
3
4
5
6
7
8
* Table of Contents :TOC:
- [[#preface-why][Preface, "Why?"]]
- [[#required-packages][Required Packages]]
  - [[#dots-packages][DOTS Packages]]
- [[#platform-packages][Platform Packages]]
- [[#builds][Builds]]
Oliver Mead's avatar
Oliver Mead committed
9
- [[#entities][Entities]]
Oliver Mead's avatar
Oliver Mead committed
10

Oliver Mead's avatar
Oliver Mead committed
11
12
13
14
15
16
17
* Preface, "Why?"
Unity is in the midst of a transformation that will fundamentally change the way
games are written. While those changes are not in the mainstream distribution of
the engine, it is imminent. This document aims to consolidate and summarise
information on the requirements and use of this new Data-Oriented Technology
Stack, and serve as a reference for project setup and development in the future.

Oliver Mead's avatar
Oliver Mead committed
18
It is still a good idea to learn the "classic", object-oriented approach taken
Oliver Mead's avatar
Oliver Mead committed
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
by both our game development module and the current series of learning materials
that Unity provides. Much of the programming, concepts and techniques will still
be useful and will still be necessary with some changes.
* Required Packages
** DOTS Packages
Installing the DOTS packages requires opening the Package Manger within the
project (Select =Window > Package Manager=), then add by name (select from the
drop-down "+" menu). Enter the following package names (one at a time):
+ =com.unity.entities=
+ =com.unity.rendering.hybrid=
+ =com.unity.dots.editor=
+ =com.unity.physics= \leftarrow The re-implementation of the physics engine built on DOTS
These packages are marked experimental, so be sure to save often and make use of
good version control practices. Be sure to push changes to the remote repository
often, and use branches when writing and testing new functionality before merging
with parent branches.

I expect we will be working simultaneously so we can work out any issues, talk
about problems etc. together.
*** Domain Reload
Oliver Mead's avatar
Oliver Mead committed
39
As noted in the [[https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/install_setup.html][entities documentation]], Domain Reload occurs when entering play
Oliver Mead's avatar
Oliver Mead committed
40
41
42
43
44
45
46
47
mode within the editor, and is especially slow when using DOTS. To disable this,
enable the "=Enter Play Mode Settings=" checkbox in the =Editor= section of the
Project Settings, while leaving its child options unchecked.
* Platform Packages
It is also necessary to install the DOTS based platform packages for Unity (The
default tool-chains will not be replaced by default).

Install, in the same way as above, the =com.unity.platforms.<platform>= packages,
Oliver Mead's avatar
Oliver Mead committed
48
49
50
where =<platform>= is the desired target, for example I will install
=com.unity.platforms.linux= and =com.unity.platforms.windows= to produce binaries
for Linux and Windows.
Oliver Mead's avatar
Oliver Mead committed
51
52
* Builds
Building through the standard =File > Build and Run= or =<ctrl+b>= will not work
Oliver Mead's avatar
Oliver Mead committed
53
with DOTS. You must create a "Classic Build Configuration" for each target
Oliver Mead's avatar
Oliver Mead committed
54
55
56
57
58
59
platform through the asset manager:

=+ > Build > <Platform> Classic Build Configuration=

From now on you must build the project by selecting this configuration and using
the options shown in the inspector.
Oliver Mead's avatar
Oliver Mead committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
* Entities
In the standard OOP model of game development, functionality is tied to
individual instances of objects. Each Monobehaviour (the class that from which
all standard scripts inherit) has its own ~Start()~, ~Update()~, similar and
accompanying methods. The engine will run all of these sequentially.

In this model, each game object is treated as a collection of data (the entity),
with this data organised into "components". These components are analogous to a
struct in C, they are mutable collections of data, they do not have their own
functionality in the form of methods.

It is the job of a =System= to read and transform the data of the entities. For
example you may have many entities with a ~Character~ component, each with an
~hp~ variable. This will include all players, enemies and NPCs. Characters may
be poisoned during the game, adding a ~Poison~ component to their entity. This
component will contain a value ~float rate~ to determine how much damage to deal
each second, and a ~float duration~ to determine how long the character will be
poisoned for.

You may define a ~StatusSystem~, which manages status effects (in this case
poisoning). It will operate on all of the entities with a ~Character~ /and/ a
~Poison~ component, and update the ~hp~ variable based on the data related to
the poison.

What will this look like? Within the StatusSystem's ~OnUpdate()~ method:
#+begin_src csharp :exports code
float dT = Time.DeltaTime;

Entities
  .WithAll<Character, Poison>()
  .ForEach(
      // define the lambda that transforms the data
    (ref Character ch, ref Poison poison, in Entity entity) => {
      ch.hp -= poison.rate * dT;
      poison.duration -= dT;
      if (poison.duration <= 0) // remove the poison component if it has expired
          EntityManager.RemoveComponent<Poison>(entity);
    })
  .ScheduleParallel();
#+end_src

Some keywords are used in the lambda definition that relate to C#'s implementation:
+ ~ref~ creates a mutable reference to the given argument
+ ~in~ creates an immutable reference to the argument (here we are not modifying
  ~entity~, only passing the reference to the ~EntityManager~ in order to remove
  the component)