Fun Metaverse Development Story: Component-based Development #1/4

ARBEON Co., Ltd.
Arbeon
Published in
6 min readJan 10, 2023

It’s nice to meet you.
I’m David from MetaverseLAB, the team that creates metaverse within Arbeon app.

I will be making a four-piece blog post series on component-based development (CBD), and today marks the first one. Are you excited to find out what it will be about? Let’s get started right away!

The magic of creating an object of a new behavior using a component —
What is Component-based Development?

First, let us look at what CBD is. CBD refers to the development methodology that shifted from the object-centered thinking and development, instead placing focus on the components. Here, the “component” should not be understood as a separate entity from the object. Instead, it’s proper to consider that this possibly abstract term “object” was detailed and fleshed out as the “component.” To put it simply, it would be right to view the CBD as a part of object-oriented programming (OOP).

CBD, Why Use It?

There is something abstract and vague about objects. And so, solving this issue involves coming up with the definition of an object, and there are several methods to do so. By and large, OOP offers better productivity and reusability than process-oriented programming, but making other software using this one poses certain issues that cannot be solved with the existing class.

For example, let us say we’re making a “rabbit” as software.

There will be many ways to design a rabbit, but simply, the below design example could be made.

Let’s write this in code.

public class Animal
{
protected virtual void Move() { Console.WriteLine("Moving"); }
public virtual void Live() { Console.WriteLine("Living"); }
}

public class EarAnimal : Animal
{
protected virtual void Listen() { Console.WriteLine("Listening"); }
}

public class FurEarAnimal : EarAnimal
{
protected virtual void GrowFur() { Console.WriteLine("Fur is growing"); }
}

public class Rabbit : FurEarAnimal
{
protected override void Move()
{
Console.WriteLine("baby step moving");
}

protected override void GrowFur()
{
Console.WriteLine("white fur is growing");
}

protected override void Listen()
{
Console.WriteLine("Rabbit is listening");
}
public override void Live()
{
Move();
GrowFur();
Listen();
}
}

public static class Program
{
public static void Main(string[] args)
{
Rabbit r = new Rabbit();
r.Live();
}
}

Result Output

baby step moving
white fur is growing
Rabbit is listening

This code may seem complicated to reuse in the future, but let me try to explain using an example for better understanding.

Let us assume that we’re making new software that “wants to make a dog whose fur is rabbit fur.” In this scenario, do you think we can utilize the rabbit coded above? It’s likely that the below will happen.

public class Dog : Rabbit
{
protected override void GrowFur()
{
base.GrowFur();
}

protected override void Listen()
{
Console.WriteLine("Dog is listening.");
}

protected override void Move()
{
Console.WriteLine("big step moving");
}
}

Result Output

big step moving
white fur is growing
Rabbit is listening

Let’s enumerate a few big issues with the above code.

  1. Logical contradiction
    Rabbit being inherited: A dog is not a detailed concept of a rabbit. This could create a serious misunderstanding on the part of the programmers. Programmers are required to write and understand a massive amount of code daily. Such a logical contradiction would force them to write complex code.
  2. Rabbit’s codes that are abandoned
    The rabbit’s GrowFur method can be well used, but functions like “Listen” and “Move” are unnecessary for dogs. This could cause confusion to the programmers as well.
  3. Low productivity
    Inheritance may have lowered the number of codes to be written, but eventually, programmers would need to write codes, compile, and distribute them. These processes drag the development speed. The delay for the development speed may not be so serious for C# and Java with their intermediate language and JavaScript with its interpreter, but a language like C++ is bound to be worse with a longer time needed for compiling.

All right, and what would happen if we design and write this in CBD?

public abstract class Component
{
public abstract void Do();
}

public class Ear : Component
{
public override void Do()
{
Console.WriteLine("Listening.");
}
}

public class Leg : Component
{
public override void Do()
{
Console.WriteLine("Moving.");
}
}

public class Fur : Component
{
public override void Do()
{
Console.WriteLine("fur is growing");
}
}

public class RabbitEar : Ear
{
public override void Do()
{
Console.WriteLine("Rabbit ear is Listening");
}
}

public class DogEar : Ear
{
public override void Do()
{
Console.WriteLine("Dog ear is Listening");
}
}

public class LongLeg : Leg
{
public override void Do()
{
Console.WriteLine("Bigstep moving");
}
}

public class ShortLeg : Leg
{
public override void Do()
{
Console.WriteLine("baby step moving");
}
}

public class WhiteFur : Fur
{
public override void Do()
{
Console.WriteLine("WhiteFur is growing");
}
}

public class Animal
{
private string name;
private List components;
public Animal(string name, params Component[] components)
{
this.name = name;
this.components = new List();
this.components.AddRange(components);
}
public void Live()
{
for (int i = 0; i < components.Count; i++)
{
components[i].Do();
}
}
}

public static class Program
{
public static void Main(string[] args)
{
Animal rabbit = new Animal("Rabbit", new RabbitEar(), new ShortLeg(), new WhiteFur());
rabbit.Live();
}
}

Result Screen on the Rabbit

Rabbit ear is Listening
baby step moving
WhiteFur is growing

Here’s how it’s done. First, select the components that can comprise a rabbit.

  1. RabbitEar
  2. ShortLeg
  3. WhiteFur

And define the classes that can hold these components. Here, the class would be “Animal.” Declare the member variable to give a name, define the list that can contain components of the rabbit, and name it with components. Look at the rabbit code and insert the name and necessary components. Afterward, define an object.

The same method could be used to make a dog. Let’s do it.

Animal dog = new Animal("Dog", new DogEar(), new LongLeg(), new WhiteFur());

Result Screen on the Dog

Dog ear is Listening
Bigstep moving
WhiteFur is growing

What do you think? Did you see how we can create a new animal with the existing ingredients?

Like this, the development process of creating an object with new movements using components is called the CBD.

The Brilliance of CBD and its Limits

Here are the advantages based on the design above:

  1. We can make more animals once we expand the components!
  2. We can define the variables we’ll hand over to the animal generators in the form of a table!
    Once you have created the table for the animal generators, they will be able to create various animals by reading the table alone. And this allows the users who are not programmers to edit the program by making the editor.
  3. We can enjoy low dependence and high coupling!
    Once you start designing the component to work even in closed environments, you will see that there’s actually a great benefit in terms of low dependence and high coupling.

And if there are upsides, there are downsides, too.

  1. How to communicate with each component?
    This deserves a more detailed explanation, so it will be dealt with in the next post.
  2. The level of difficulty of the design
    The design can be difficult as the components need to operate well, even in closed environments.
  3. A lot of tests are needed.

- A unit test on whether the components independently work well in closed environments
(because they should be reusable in other software).

- A test on whether it operates normally in the actual software user environment where components are mixed in.
- It could be slower than when components are not used. This will be dealt with in the next blog post as well.

The Arbeon app
uses CBD too.

Arbeon app is made using Unity. Unity uses CBD to create a virtual environment and set it in motion (Of course, there is a concept called “DOTS,” but I’ll explain it in the future if I have the chance). The animal class I mentioned above can be expressed as GameObject, and classes like “Transform,” “Collider,” “Rigidbody,” etc. can be expressed as a component. So in order to be good at using Unity, one should have a solid grasp of CBD.

Up Next!

I plan on talking about how each component communicates with one another in CBD. There are cases where it doesn’t need another object through its low dependence and high coupling, but there are also cases when it has to communicate with other objects. I’ll be talking about how it’s done in such a case.

Please look forward to it!

Ref.

[1] https://ko.wikipedia.org/wiki/
[2] https://docs.unity3d.com/kr/2018.4/Manual/Components.html
[3] https://docs.unrealengine.com/4.26/en-US/Basics/Components/
[4] https://hrcak.srce.hr/file/69311
[5] https://www.youtube.com/watch?v=cxyG_REKD4Y
[6] http://gameprogrammingpatterns.com/component.html

--

--