# Question
Title: Is ECS an object-oriented design in disguise? (rather philosophical/technical)
Correct me if I'm wrong, but having read a lot about the ECS-Pattern in general and in the context of current game engines **I am beginning to wonder if the ECS-Pattern in it's core is hardly more than an object-oriented design in disguise with added reusability?**

To clarify my point, first of all there are good answers here describing the general function how an ECS approach works (e.g. here, though I would argue about the HashMap approach). Furthermore Unity added alot of functionality in this regard in its 2019 DOTS.

In this unity blog describing the changes and differences to traditional "gameobjects" and the rough implementation Unity uses, one paragraph raised some questions:

> \[...\] In an earlier draft of this post I wrote “we store entities in chunks”, and later changed it to “we store component data for entities in chunks”. It’s an important distinction to make, to realize that an Entity is just a 32-bit integer. There is nothing to store or allocate for it, other than the data of its components. Because they’re so cheap, you can use them for scenarios that game objects weren’t suitable for. Like using an entity for each individual particle in a particle system.

There is - what I'd call - a hype about the ECS-Pattern and why it is so much better than a traditional approach using objects as entities and components, and their class as the systems part. Having done my fair share of projects in different topics and different programming languages, an instance of a class without any variables or functions is, on an abstract level, nothing more than a statement of it's existence, most likely an address in memory.

So it would also satisfy this part

> to realize that an Entity is just a 32-bit integer. There is nothing to store or allocate for it

of the quote (apart from the name).

Moreover a class is a collection of variables (or fields/members or any other word for it) which could also be called data components. Together with the class's functions .. is it an ECS based design if you group the objects based on their class when processing multiple objects?

If you compare the ECS-Pattern to a traditional particle system, which usually consists of arrays of variables so it can store different data for each of it's particles, the similarities are even more obvious.

```
public class ParticleSystem{
    int numParticles;
    float[] x;
    float[] y;
    float[] size;

    public void update() {
        move();
        resize();
    }

    public void move() {
        for (int i = 0; i < numParticles; ++i) {
            x[i] += 0.2f;
            y[i] -= 0.1f;
        }
    }

    public void resize() {
        for (int i = 0; i < numParticles; ++i) {
            size[i] *= 0.95f;
        }
    }
}

```

Take this over-simplified particle system as an example. It would be treated as a traditional "gameobject". Now you could write it differently ..

```
public class Position {
    float x, y;
}

public class Size {
    float size;
}

public class ParticleSystem{
    int numParticles;
    Position[] positions;
    Size[] sizes;

    MoveSystem moveSystem;
    SizeSystem sizeSystem;

    public void update() {
        moveSystem.execute();
        sizeSystem.execute();
    }
}

public class MoveSystem {
    Position[] positions;

    public MoveSystem (Position[] pos) { positions = pos; }

    public execute() {
        for (int i = 0; i < positions.length; ++i) {
            positions[i].x += 0.2f;
            positions[i].y -= 0.1f;
        }
    }
}

public class ResizeSystem {
    Size[] sizes;

    public SizeSystem(Size[] s) { sizes = s; }

    public execute() {
        for (int i = 0; i < sizes.length; ++i) {
            sizes[i].size *= 0.95f;
        }
    }
}

```

.. and it looks like an ECS-based particle system with the main class as the "manager" of the entities. Every particle(entity) is just a 32-bit integer (it's index). There is nothing to store or allocate for it, other than the data of its \[two\] components.

(I do know this is neither elegant nor complete code)

You could write every class inheriting from a basic "gameobject" as a collection of instances. Imagine you have a virtual meadow with sheep roaming around. They need various different components for logic, physics, rendering and ai but you could easily design it like a classic particle system.

And if you read the whole post it describes a "archetype" class with up to 16k per "chunk" holding only entities of the same kind and running systems in a linear loop over all the chunks of all archetypes which feature the same components and all entities in those chunks. Which sounds a lot like "particle systems" for each archetype of entities. It just hides the archetype class from the user ..?

**Edit1:**

I am not struggling to understand the specifics of how to implements an ECS-Pattern or how it works on a functional level, rather the aspects an reasons why it is considered by many to be vastly superior to an OOP design. This requires a view of the entire system, from the software layer right down to the hardware considerations.

One common argument in favor of ECS is the RAM allocation and the improvements on cache-miss-rates - and therefore performance - for both data and instructions, as a component-based grouping of data and system-based processing of the components allows for more efficient access to consecutive data.

Example: x Entities with components A through Z

**Why is an ECS design like**

```
A[x]; B[x]; ... Z[x];

```

**considered more efficient than**

```
(AB..Z)[x];

```

**..?**

In the first case you could cache a single component per read for (potentially) multiple entities at once. But depending on your system you need multiple reads from different locations on the RAM. The second case could (potentially) cache a single object per read (more likely a single object with multiple consecutive reads). And although RAM is designed for random access, different sources claim consecutive access is still a lot faster.

I do get the fact a system doesn't need all the data of a single object. Which, as I see it, is the strongest argument on this level. This article from Intel's developer zone includes an illustration of the problem with fragmented RAM on a class-based view of the system. If you change the view from a class-based to a per-byte view, ECS would have the same problem. The components a systems requires to operate are stored in seperate arrays so the system regularly needs to access non-consecutive memory. Which is the flaw of an OOP based memory design that is pointed out in the article, as the prefetching needs to learn what to load next?

**Edit2: addressing the comment from Quentin**

Again, I am not concerned on the functional design of how a system **discovers** all relevant entities, but on the "decision-making" process which objects are **relevant**.

Imagine you want to model two kinds of entities. Returning to the example from this Q&A the first kind of entity is the ball which just falls in the direction of the global gravity.

```
spd += global.gravity * global.deltaTime;
pos += spd * global.deltaTime;

```

The second kind of entity shall be an alien ball, which is negatively affected by gravity.

```
spd += -global.gravity * global.deltaTime;
pos += spd * global.deltaTime;

```

Notice the **-** global.gravity this time. Disregarding how the example's system discovers all eligible objects, as long as the systems operates on all objects that feature a speed and a position component - that are eligible - , the questions boils down to **what decides if an object is eligible?**

As systems are not exclusive, i.e. a system that operates on components A and B, and a system that operate on components A, B and C both process the same object (if the object in question does contain all three components) **how would you differentiate different between different behaviours without adding additional components to all entities?**

If you were to add a gravity component to the alien ball entities to address the different gravity, the "Fall" system would still process the alien balls as they still have the speed and position components. An "AlienFall" system, which takes speed, position and gravity components would then only process the alien balls with the correct gravity and both systems would negate each other (in terms of the speed calculation) and the result would vary based on the order in which the systems are executed.

Unifying both systems by adding a gravity component to every entity would rather contradict the ECS efficiency paradigmas as you effectively add lots of data compared to the information it represents.

# Answer
> 3 votes
Strong "no" from me. The concept of what constitutes object-oriented design and programming is widely contested in my experience when it comes to the nuanced details among experts and pioneers who introduced object-oriented concepts to languages. Yet if there's anything that seems to be at the heart of the focus behind OOP, it's *encapsulation*: the bundling of data (state) and logic (functions/methods) to access/mutate that object's internal state. It's not that OOP is the only way to achieve this, but I would say it's the primary and lowest-common-denominator focus.

The ECS immediately goes in the opposite direction here. It also varies in terms of how people design and implement it, but at the heart of it is a *separation*, not a *bundling*, of data (in components) from logic (systems). I would tend to characterize most ECS designs I see as procedural programming on steroids. Sometimes I also see functional-style variants that arrange systems in a pipeline with immutable scenes and components. Of course, some people might use objects here and there to implement an ECS, but again the heart of an ECS revolves around *separation*, not *encapsulation*, and so I'd say it's very, very far-removed from OOP.

> > Why is an ECS design like \[...\] considered more efficient than \[...\]

Sticking to the philosophical and generalized kind of vibe here, it is not necessarily always the case that the ECS is more efficient than an object-oriented design. But OOP encourages bundling of data (and logic) based closer to human intuition, not access patterns friendly to the hardware. Since the ECS immediately abandons encapsulation, it is free to do things like split hot/cold data, even for what might normally and naturally be bundled together into a single object by an object-oriented designer, for more efficient access. Again it is not object-oriented, and breaking that capsule apart as the ECS does means we're free to arrange and rearrange data more freely. Object-oriented designs often trap you inside the capsule when you're staring at profiler hotspots unless the capsule you're inside is very big and offers plenty of room to change data representations.

# Answer
> 0 votes
ECS is not OOP. It is data-driven. From an OO stand point ECS flips encapsulation on its head. However, you can build OOP on top of it.

You can imagine a solution that lets you write a class - in a conventional fashion - but underneath it would be generating components and systems. The solution would enforce any accessibility rules necessary, and would implement any features you consider to be mandatory for OO, and well, it would be OO, but the values of an entity are not contiguous in memory.

I don't think ECS are inherently OO, but you can use them that way. You can implement an object oriented design on top of systems that do not have object oriented features… Case in point: you can implement an OO design on an structured language by following the pattern that the first parameter a routine is the *this* pointer that goes to an struct with the fields. Yes, that does not have the right encapsulation rules either, however you can built an OO solution on top of it. *And that is how C++ started, the first C++ compiler it would generate C code that worked in the fashion I just described.*

# Answer
> 0 votes
## Short Answer

ECS fundamentally takes into consideration how modern processors best manipulate data rather than how people think about data and this forces programmers to write more efficient code just because writing bad (slow) code isn't the path of least resistance anymore. One isn't inherently faster than the other but ECS is harder to make slow and easier to multithread!

## Long Answer

> ECS-Pattern in it's core is object-oriented design in disguise with added reusability?

In traditional OOP you create an object and have it take core of it's own responsibilities leaving everything else for other classes to handle. This means that it contains all of it's own data and the logic to modify it in a single class. In ECS (as you show with examples) you have the data split out from the logic and in the case of Unity you can further divide the logic into multiple systems in order.

This separation of data and logic is what makes ECS different to OOP since a class is no longer responsible for it's own actions, rather the responsibilities have been (or can be) divided up and moved to multiple classes (some of which can be reused if you design it that way), this approach of simply passing data into a thing that knows how to modify the data is what makes it data-driven because you always have to think about the data first.

Can you do this with OOP? Yes. but you then have to keep the data and the logic together whereas ECS keeps separation between it and allows for more flexibility when trying to modify data.

> Why is an ECS design like `A[x]; B[x]; ... Z[x];` considered more efficient than `(AB..Z)[x];`..?

It's not. It's implantation that matters. I could write a slow ECS-System and a really fast gameobject-System.

Basically if you can group data together in memory (as you mention) the CPU can make a good guess of what data a system is going to want to access next and it'll load it into the CPU cache before the program ever asks for it. This makes a big difference because the cache is much faster than accessing from memory in comparison and the amount of data that the cache can store is relatively small (MB in Cache vs GB in memory).

If you were using traditional OOP you would have an object with a lot of data which needs to be pulled into the cache in order to start working on the data. Now this could potentially hit multiple bottlenecks:

* If you have slow memory it's going to take a while to make get the data to the CPU lowering performance
* If you have a lot of data you won't be able to fit it all into the cache and you'll have to make multiple trips or load bits of it in and out lowering performance
* If there is other stuff going on which needs to be processed that will also be using a part of the total memory bandwidth which lowers performance.

**This is where ECS shines** (again, assuming a good implementation) because the data is in small chunks you load only the amount of data that you actually need. Looking at Unity's gameobjects (because that's where your examples are coming from) a gameobject has a name and position and rotation and a parent and children and other components etc. this is all bloat that has to be loaded... why? we don't need it! someone might need it but only is specific circumstances. With entities you have it's components and we don't really care about the entity itself only the components of an entity which we can feed into a system and by extension only the data that we need! see the bullet list why this is important!

If there is a good implementation of ECS that data will be tightly packed together, no gaps in memory that will cause a CPU cache miss (which is more expensive than just getting the data for reasons that are beyond this question) and no unused data that is either repeated (and therefore only read once) or not used at all (cause you can just delete it or put it into another component if a different system uses it).

If you compare this to gameobjects you have loose data, a component might be in one place in memory that might contain a list which links to 200 other objects which are also spread throughout memory and then we might need another piece of data which is is inside another component on the gameobject which is somewhere else in memory (and I hope we have already cached the location of that component otherwise we get to search for it every game loop!). How is the CPU supposed to guess where this stuff is and what your going to need next? It won't and you performance suffers. but it doesn't really matter because CPUs are fast so you keep going till you want to optimise and then it's too late cause you can't pull that data out anymore, too much stuff needs it and you have to ship... Again it's not impossible to get good performance from OOP (gameobjects), just much easier to get slow performance.

**Another aspect of ECS that people don't consider** as much is that since the system that you build inside ECS only has to calculate/retrieve frame dependent data once and it can then use it for all components. In most cases this means a system grabs delta time at the start and has it ready to go as it processes the components rather than grabbing it from a random memory location each time a gameobject component goes through the game loop. In other cases a lot of stuff might only really need to be calculated once then mixed in with component data and ECS makes this really easy because all of the data is at an ECS systems finger tips and harder to make the mistake of recalculating each frame because you know that a system is called once were as a gameobject might be called many times but which one takes the hit in working out this data once? if you mess it up can you live with last frames data or will that cause bugs? Most people either don't want to take the risk or don't realise this costs potential performance.

---
Tags: software-engineering, entity-component-system
---


# Question
Title: How do I set what beta branch I want to upload my build to in Steamworks?
I have many beta branches, and when uploading the game I just run a command which executes the `app-build-xxxx.vdf` file. How do I set what specific branch I want those changes to be uploaded to? My configuration file looks something like this:

```
"appid"           "xxxxx"
"desc"            "Beta branch xxxx "

"buildoutput"     "..\output\"
"contentroot"     "..\..\Game\"

"setlive"         "<Name of the branch here as it is in steamworks>"

```

# Answer
> 1 votes
The documentation for the `setlive` parameters say:

> Branch name to automatically set live after successful build, none if empty. Note that the 'default' branch can not be set live automatically. That must be done through the App Admin panel.

You cannot accidentally set the default branch live, if that's what you are worrying about. If you are worried about accidentally setting another beta-branch live while testing, just create another password protected branch for testing this before deploying it into your proper build pipeline.

---
Tags: steam, steamworks
---


# Question
Title: How to mitigate when applying horizontal force to a rigidbody seems to overpower gravity?
I've started testing movement using the example code in this answer of making a body accelerate to a target velocity

```
    private void FixedUpdate()
    {
        Vector2 input = GetInput();

        if (Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon)
        {
            Vector3 desiredVelocity = new Vector3(input.x * speed, 0f, input.y * speed);

            Vector3 delta = desiredVelocity - body.velocity;
            Vector3 acceleration = delta / Time.deltaTime;

            if (acceleration.sqrMagnitude > maxAccel * maxAccel)
            {
                acceleration = acceleration.normalized * maxAccel;
            }

            body.AddForce(acceleration, ForceMode.Acceleration);
        }
    }

```

and I've encountered the following curious behavior: https://i.stack.imgur.com/5AOuz.jpg When moving the body by applying force, the body seems to levitate as if gravity is not being applied. It actually is being applied but it seems as if the force being applied to the body is overriding the force of gravity because as soon as I let go of the movement keys the body suddenly drops. I am not applying any force on the y axis so I'm not sure what exactly is at play here. What is going on here and what can I do to mitigate this behavior?

# Answer
> 2 votes
You're not applying just a horizontal force. You're applying a vertical force too.

Your `desiredVelocity` is constructed with a y component of zero, saying "I desire that this object should hover instead of falling," and the rest of the code then tries to honour this stated desire.

To fix that, just set `delta.y = 0` before you calculate your acceleration, to say "I don't care about movement on the vertical axis — leave that unaffected by this input acceleration"

---
Tags: unity, physics, movement
---


# Question
Title: Godot - Collision for character teleportation
I'm currently working on a little game to discover Godot game engine.

It's a Top-Down game and I want my character to be able to teleport through walls.

I thought to dupplicate my character's collision box and to set its position to the teleportation's position but I didn't find a way to check if there is a collision to this new position.

Any advise?

# Answer
As I am not allowed to comment, it may be a pain for me to answer correctly with the little knowledge I have.

I have tried a few things, I think you may get away with using a RigidBody2D as a base for the player's collision box' duplicate (let's call it a ghost). This node has a get\_colliding\_bodies function that returns an array. If the array is empty, then you can teleport to the desired location.

you can check it with something like that :

```
if get_colliding_bodies().size() == 0:
    player.teleport_to(position)

```

To work, this piece of code would require to be in a script attached to the RigidBody2D, with a reference to your player stored in a variable called player. You would also need a function called teleport\_to in the player script, but keep in mind this is just an example.

You may want to use this in a properly set function to check at the right time. For instance when the space key is released.

Here I am assuming that everything is pretty much set up in your scene and that the only issue is that you do not know how to check if there is a collision on the arrival position. I hope that would help you.
> 1 votes

# Answer
*I have no experience with this, however I believe `Area2D` is intended for this purpose.*

Based on the documentation, I guess you can connect the signal `body_exited` check `get_overlapping_bodies` and set a flag "can teleport" to `true` if it gives you an empty array. Also connect to `body_entered` and set the flag to `false` there.
> 1 votes

---
Tags: godot
---


# Question
Title: How is the value of transform.position updated and accessed between different private methods?
I followed this YouTube video but I'm still confused about how the code actually retrieves the value of `transform.position`.

I can understand the `Camera.main.ScreenToWorldPoint` code is to transform the screen position to a position in the world based on the camera's view, and it then uses this to update the `transform.position` as in the `private void OnMouseDrag` method.

However, I also learnt that since the method is declared as private, the "transform.position" cannot retrieve the value of "transform.position" in each {}bracket.

So how does the value of "transform.position" in `private void OnMouseUp`, `private void Awake` get updated, unless I misunderstood the concept?

```
using UnityEngine;

using UnityEngine.Assertions.Must;

using UnityEngine.SceneManagement;

public class GreenBird : MonoBehaviour

{
    Vector3 _initialPosition;
    private bool _birdWasLaunched;
    [SerializeField]private float _launchPower = 500;

    private void Awake()
    {

        _initialPosition = transform.position;
    }

    void Update()
    {
        if (_birdWasLaunched &&
                 GetComponent<Rigidbody2D>().velocity.magnitude <= 0.1)
        {
            timeSittingAround += Time.deltaTime;
        }

        if (transform.position.y > 10.00 ||
            transform.position.y < -10.00 || transform.position.x > 10 || transform.position.x <-10)
        {
            string currentSceneName = SceneManager.GetActiveScene().name;
            SceneManager.LoadScene(currentSceneName);
        }

    }

     void OnMouseDown()
    {
        GetComponent<SpriteRenderer>().color = Color.red;

    }

    private void OnMouseUp()
    {
        GetComponent<SpriteRenderer>().color = Color.white;
        Vector2 directionToInitialPosition = _initialPosition - transform.position;
        GetComponent<Rigidbody2D>().AddForce(directionToInitialPosition * _launchPower);
        GetComponent<Rigidbody2D>().gravityScale = 1;
        _birdWasLaunched = true;

    }

    private void OnMouseDrag()
    {
        Vector3 newPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        transform.position = new Vector3(newPosition.x, newPosition.y);

    }
}

```

# Answer
> 2 votes
It sounds to me like you're confused about the rules for variable scope.

Take a look at this example:

```
public class Foo {

    // This variable is declared inside the scope of the class.
    // That makes it a "member variable". We allocate one of these variables
    // every time we construct an instance of the class Foo, and it lives
    // and remains accessible as long as that instance does.
    public int memberField;

    // This is a method defined inside the scope of the class.
    // We call it a "member function".
    // The "private" means only code in this class is allowed to call the function.
    private void DoSomething() {

         // Inside this method, we can read and write to members of the class.
         memberField = memberField + 1;

         // We can also declare "local temporary variables"
         // to help us do our work inside the function.
         int localVariable = memberField + 1;

         if (memberField + localVariable == 7) {
             Debug.Log("Seven!");
         }
    }

    private void DoSomethingElse() {
        // Other methods in the class can also read and modify our member variable.
        // They're all accessing the same variable attached to this instance of the class,
        // so changes we make in DoSomething can be seen in DoSomethingElse and vice versa.
        memberField = memberField - 1;

        // But they can't access the temporary variable we declared in DoSomething.
        // localVariable = 3;
        // Uncomment the line above and it will throw an error.
        // We don't have a variable by that name here! (Yet...)

        // We could choose to declare a NEW variable called "localVariable"
        int localVariable = -42;

        // But this has no relationship to the variable in DoSomething.
        // It's a completely different bit of memory that we just called the same name.
    }
}

// We can define a derived class that inherits from the class Foo above.
public class ChildOfFoo : Foo {

    private DoSomethingChildish() {
        // This class's methods are ALSO allowed to use Foo's member variables,
        // because ChildOfFoo IS a kind of Foo, just a specialized version,
        // So it gets all the public or protected members that Foo had.
        // It's just not allowed to use the ones Foo marked as "private".
        memberField = 0;
    }
}

```

So, coming back to your `GreenBird` example:

`transform` is a public member variable of `MonoBehaviour` (or strictly speaking, its grandparent class, `Component`), and `GreenBird` derives from `MonoBehaviour`.

That means all the functions inside `GreenBird` are allowed to access its member variables, including `transform`, and the value is shared between them because they're all looking at the same chunk of memory.

The `private` in front of our method names just means that other classes aren't allowed to call them... *usually*. There's a special exception for Unity's MonoBehaviour message functions like `Start`, `Awake`, `Update`, `OnMouseDown` etc.: Unity looks up these methods using reflection, which works around the normal limitations on who's allowed to call what.

---
Tags: unity
---


# Question
Title: how to structure game logic for user interfaces of different nature (gui, tui, cli)?
I would like to implement a simple game logic engine that is agnostic to the rendering system, but I don't know how to do that, really... so I would like to have advise and know the state of the art!

the idea is to have a "logic" class that contains the step to be done to advance the game, for instance "show this to the user" or "wait for user input on this choice": while it was easy to make it work in a textual user interface like this:

```
forever {
    switch logic_get_next_action() {
        // Writes a message to the user on the provided output
        when MESSAGE: write(stdout, logic_get_message());
        // Writes multiple choices, then waits for an input
        when CHOICE: {
            for c in logic_get_choices() {
                write(stdout, c);
            }
            logic_update_state(read(stdin));
        }
        ...
    }

}

```

initially I thought that decoupling from `stdin` and `stdout` would be enough, and I could devise some sort of encoding that would allow me to use another kind of interface, but I realized this is very textual-centered, and relies on some synchronicity.

for instance it relies on the writes in choice to happen and be concluded before the read, and also blocks on read.

I suppose a more asynchronous solution is needed here but not really sure on how to proceed: don't want to be trapped in local choices! for instance after the textual prototype I am using an immediate mode GUI toolkit now, but what changes will I have to make if I ever switch to a retained mode?

# Answer
> 1 votes
You've solved the core of the problem by expressing your game logic so that it's a set of functions that the UI code can use in whatever structure makes sense.

> for instance it relies on the writes in choice to happen and be concluded before the read, and also blocks on read.

Unless I misunderstand, this isn't a feature of your `logic_*`, it's a feature of the particular loop you showed, which is indeed only suitable for a text-based interface.

When you write a GUI your main loop (if any) will have a different structure, but one compatible with the same logic. It might be like:

```
forever {
    // Draw frame
    switch logic_get_next_action() {
        when MESSAGE: draw_text(logic_get_message());
        // Writes multiple choices, then waits for an input
        when CHOICE: {
            let x = 0, y = 0;
            for c in logic_get_choices() {
                draw_text(c, x, y);
                y += line_height;
            }
        }
    }
    swap_buffers();

    if (event_available()) {
        if (event_is_a_button_click() && logic_get_next_action() == CHOICE) {
           ...
           logic_update_state(choice_id_from_event);
        } else ...other event handlers...
    }
}

```

This is a non-blocking main loop using the same functions.

— wait, I think I might see the problem. Your `MESSAGE` action seems like it might be intended to display a message and then go on to do something else. Are you thinking that `logic_get_next_action()` will return a next thing all on its own when it's called the next time around the loop (e.g. perhaps two MESSAGEs followed by a CHOICE)?

If so, there's your problem. Here are two ideas for how to fix it:

1. Have a "get the *current* action" function, and handle MESSAGEs like CHOICEs: the game logic doesn't change any state until until a function is called to do it. In a text UI you can just let the text scroll up, but in a GUI you often wait for a button press to advance/dismiss the text, so that has to be an explicit action — it always needs to be possible to just fetch the current state again to redraw the screen.
2. Implement in your GUI code (or, if you're using retained mode, delegate) storing the messages that have been produced by the game logic so far. This makes sense if your game logic will frequently be emitting a sequence of *event* messages (e.g. narrating the moves in a fight) rather than *describing the current state.* It's also an approach that's closer to building a terminal inside your game, which makes sense if your game is particularly focused on textual interaction.
3. Same as option 2, but specifically create a helper data structure that keeps track of what text should currently be visible — it's not used in a text interface, because the existing terminal handles keeping text around, but is used in a GUI, and it can be forwarded some hints from the game logic to say when to e.g. clear the stored text, or specify which character is speaking to display their portrait, or whatever.

Exactly which architecture choices are best depend on the sort of game you're making — what kind of interactions between the user and the game logic are occurring, and how you want the GUI to work.

# Answer
> 1 votes
I went down this route.

Yes, isolating standard input and output is not enough. Sadly, they are blocking. You need an asynchronous solution.

I modeled it as an state machine. You are either running your logic core, or waiting for input. The UI was also an state machine. The logic core could request any state from the UI, and that state could result in some input from the user. To take this input, I made the logic core give a continuation to the UI. When the callback is executed the logic core updates its state, and next game loop cycle it decides what to do, which include calling the UI again.

But that is only good for turn-based-esque games.

I did the above for a visual novel. Next I moved to a 3d game. I followed the same pattern. The logic core would decide how to move the models, keeping a representation of the game state. Then a different subsystem would manipulate the 3D scene keeping it in sync with that representation. That worked good. Until I had to make it real-time.

To make it real-time, the logic core will call an avatar controller with the delta, and any new input, plus a continuation for when the action of the input is completed (if ever, it might not if another input interrupts it). The avatar controller will then update the state, according the last input taken and the elapsed time. If it finished, it calls the continuation. If a new input was passed, it might cancel the motion it was doing and pick a new one.

I no longer keep a pure representation of the world in the logic core. The reason being: physics. Thus, I let physics, animation, etc. To run independently, and they will report to the logic core when there is a collision. In fact, this is how I handle input. Another component will take input and report it to the logic core.

What is in the callback? It is what you could call the AI director (part of the logic core). It will spawn entities, despawn entities, and give goals to those entities. The entities know how to carry simple actions, and how to react to physics. However, the lack awareness of each other, so the AI director handles that, and also coordinates them according to player actions.

---
Tags: gui, design-patterns, text-based
---


# Question
Title: How to hide a sprite on trigger when the player enters the trigger zone?
I am making a roof for my 2D top down survival game, and I want to make it so that the roof disappears when the player enters the building, and re-appears when they leave.

Here is the code I've written so far:

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Roof : MonoBehaviour {
    public GameObject roofGameObject;

    void OnTriggerEnter2D(Collider2D collision) {
        roofGameObject.SetActive(false);
    }

    void OnTriggerExit2D(Collider2D collision) {
        roofGameObject.SetActive(true);
    }
}

```

I got it to work so that, when I go in, the roof it disappears. But when I leave it stays disappeared. How can I fix that?

# Answer
The problem is that an inactive GameObject no longer checks for trigger events. So when the collider which triggers the reactivation of the roof is on the roof itself, then it won't be able to reactivate itself.

One solution is to separate the trigger area for activating and deactivating the roof and the roof itself into two separate GameObjects.

Another solution is to not deactivate the whole roof gameObject, but only its `Renderer` component. That way the roof will disappear visually, but anything else the roof does will still work:

```
void OnTriggerEnter2D(Collider2D collision) {
    roofGameObject.GetComponent<Renderer>().enabled = false;
}

void OnTriggerExit2D(Collider2D collision) {
    roofGameObject.GetComponent<Renderer>().enabled = true;
}

```

By the way: Instead of making it disappear completely, you can also make it render slightly transparent. Assuming you are using a SpriteRenderer (as implied by 2d), you can do that by changing its color property to something with a low alpha-value:

```
Color translucentWhite = new Color(1.0f, 1.0f, 1.0f, 0.2f);

roofGameObject.GetComponent<SpriteRenderer>().color = translucentWhite;

```

However, in a 3d game, you likely want to use a `MaterialPropertyBlock` instead of the color-property.

1. the performance is better (on the build-in render pipeline) because it doesn't create new materials at runtime each time you change the color .
2. When you have shaders which have more than one color property, then you can control which color(s) to change.
> 0 votes

---
Tags: unity, c#, 2d
---


# Question
Title: Programmatically extract textures from an arbitrary material
How do you programmatically extract the textures and other properties of an arbitrary Unity material?

Ideally runtime - I'm trying to upload the data to the server for remote access.

# Answer
> 2 votes
I think what you are looking for are the methods of Shader to get information about the properties and then as mentioned in the comments, use the methods of Material to get the data assigned to those properties (if any).

Below an example test where I check if the property is a texture, and log it if it is.

```
public class Example : MonoBehaviour
{
    public Material material;

    public void Start()
    {
        Shader shader = material.shader;

        for (int i = 0; i < shader.GetPropertyCount(); i++)
        {
            string propertyName = shader.GetPropertyName(i);
            var propertyType = shader.GetPropertyType(i);

            if (propertyType == UnityEngine.Rendering.ShaderPropertyType.Texture)
            {
                var texture = material.GetTexture(propertyName);
                Debug.Log(propertyName + " : " + texture?.name, texture);
            }
        }
    }
}

```

---
Tags: unity, materials
---


# Question
Title: Heat bar that always goes down but when near fire it goes up
For the fire I have this script on it.

```
public class HeatingZone : MonoBehaviour
{
    public float heatPerSecond = 1.0f;

    void OnTriggerStay2D(Collider2D other)
    {
        PlayerHeat heat = other.GetComponent<PlayerHeat>();
        if (heat != null)
        {
            heat.Heat(heatPerSecond * Time.fixedDeltaTime);
        }
    }
}

```

On the player I have this script.

```
public class PlayerHeat : MonoBehaviour
{
    public int maxHeat = 100;
    public float currentHeat;

    public HeatBar heatBar;

    void Start()
    {
        // all objects should spawn with full health
        currentHeat = maxHeat;
        heatBar.SetMaxHeat(maxHeat);
    }

    // method for getting healed
    public void Heat(float amount)
    {
        currentHeat += amount;
        // make sure we can't heal further than max health
        if (currentHeat > maxHeat)
        {
            currentHeat = maxHeat;
        }
    }
}

```

And for the heat bar I have this script.

```
public class HeatBar : MonoBehaviour
{
    public float UpdatedHeat;
    public Image Heat;
    public float HeatDecreasePerSecond;
    public int maxHeat = 100;
    public Slider slider;
    public Gradient gradient;
    public Image fill;

    // Start is called before the first frame update
    void Start()
    {
        HeatDecreasePerSecond = -0.5f;
    }

    // Update is called once per frame
    void Update()
    {
        UpdatedHeat += HeatDecreasePerSecond * Time.deltaTime;
        Heat.fillAmount = UpdatedHeat / maxHeat;

        if(UpdatedHeat >= maxHeat)
        {
            UpdatedHeat = maxHeat;
        }
    }

    public void SetMaxHeat(int heat)
    {
        slider.maxValue = heat;
        slider.value = heat;

        fill.color = gradient.Evaluate(1f);
    }

    public void SetHeat(int heat)
    {
        slider.value = heat;

        fill.color = gradient.Evaluate(slider.normalizedValue);
    }
}

```

There are no errors but it is not working. Please help.

# Answer
> 0 votes
The problem appears to be that your `PlayerHeat` component does not tell the `HeatBar` component when its `currentHeat` value changes. There appears to be a method `HeatBar.SetHeat` which is supposed to be used for that purpose, but that method never gets called.

I would recommend to add a call to that method in the `PlayerHeat.Update` method. You *could* put it into `PlayerHeat.Heat` so the bar only gets updated when the heat actually changes. But you declared `PlayerHeat.currentHeat` as *`public`*, which means that it might get changed in other ways. So you need to keep that possibility in mind and continuously update the health bar in Update... or make that variable private and properly encapsulate access to it. (By the way: it is generally a good idea to declare everything `private` by default and only make things `public` when you have a good reason to.)

Further, it appears that you tried to implement the logic for continuously reducing heat in `HeatBar.Update`. Your implementation does not actually do anything, because all it does is change a variable `UpdatedHeat` which then does not get used for anything. But I would not put that code there anyway, because the heat loss mechanic is not a part of the heat bar on the UI. It's a part of the player heat mechanic. So it should be part of the `PlayerHeat` behavior (if not a separate behavior). You might also notice that the `currentHeat` now changes every update, so one more reason to put the call to `heatBar.SetHeat` into `PlayerHeat.Update`.

```
public class PlayerHeat : MonoBehaviour
{
    public int maxHeat = 100;
    public float currentHeat;
    public float heatLossPerSecond;

    public HeatBar heatBar;

    void Start()
    {
        currentHeat = maxHeat;
        heatBar.SetMaxHeat(maxHeat);
    }

    void Update(){
        currentHeat -= heatLossPerSecond * Time.deltaTime;
        if (currentHeat <= 0) {
            currentHeat = 0;
            Debug.Log("You froze to death :(");
        }
        heatBar.SetHeat(currentHeat);
    }

    public void Heat(float amount)
    {
        currentHeat += amount;
        if (currentHeat > maxHeat) {
            currentHeat = maxHeat;
        }
    }
}

```

---
Tags: unity, c#, 2d, game-mechanics
---


# Question
Title: Why do I need a local server for HTML5 game development?
I'm new to HTML5 game development. I'm trying to make something using Pixi.js, but when I tried to view it in a browser, I saw a blank page. According to the tutorial I'm following, I need to set up a local server. I'm not sure why I'd need to do that, though.

Could you please tell me why I would need a local server to run HTML files on my browser?

# Answer
> 14 votes
Web browsers disable some Javascript features for security reasons.

My bet is that you just hit Google Chrome forbidding `XMLHttpRequest` on local files by default (see this answer on SO for how to disable that, but beware: this is dangerous). See this page on the Chrome dev site for details.

This is why you have to setup a local HTTP server to workaround the security lock.

# Answer
> 2 votes
If you just open the game's root `html`-file in a browser, your browser will (hopefully) not allow that page to access any other files. This is a security feature that limits damage from malicious scripts.

If you're comfortable on a command line and happen to have Python version 2 installed, an easy way to run a local web server is to change to the desired root directory and run

```
python -m SimpleHTTPServer

```

which serves the currenty directory's contents on `localhost` port `8888`, as documented here. Subdirectories *are* served, parent directories *aren't*, so things stay contained nicely.

The Python 3 equivalent is `python -m http.server`. (Thanks Mike!)

# Answer
> 1 votes
I've had similar issues myself in the past.

## Serving Pages

What your HTML file is possibly doing is sending HTTP requests to Localhost in order to load resources (such as Pixi.js), not actually requesting files. If not, Pixi.js may be doing that itself.

This is useful behavior on a web server, as some of the things it might be requesting could be generated dynamically, differ in response to cookies, or similar. XMLHttpRequests often go to this kind of dynamic content, and in this case the computer handling the request needs to know what to do with the file in order to generate the proper response. (If they didn't, then server-side scripts would be unable to run, you'd just get a copy of the file.) That is what the web server is there to handle.

## The Flip Side

Similarly, would you want pages from the internet to be able to access all your local files? Run arbitrary scripts as they see fit? As other answers have implied, it is a huge security risk. That's why it's turned off by default. By setting up a web server you can allow access to specific files and not others, as well as specify *how* things are accessed or run.

## What to do?

In your case, it's not so handy. If there is a webserver recommended in the tutorial, I'd use that. If not, I use Lighttpd. There's also the python SimpleHTTPServer mentioned in another answer.

Hope this helps.

# Answer
> 1 votes
**Because of browsers' default security settings**

A web browser has some extra security settings on when viewing an HTML page from local storage (like opening an HTML file with your browser). Part of these settings is to disallow AJAX requests (javascript requesting other pages). Part of this has to do that AJAX requests are always scoped to the same domain (http://example.com can only perform AJAX requests on http://example.com) and a local HTML file has no domain.

Possibly your HTML5 game framework requests its assets via AJAX in order to be more responsive.

By booting up a local web server to serve the files, the browser has a domain to scope the various AJAX requests to thus conforming with the security logic of the browser.

# Answer
> -4 votes
Html5 requires a server. 123456

---
Tags: javascript, html5, server
---


# Question
Title: How can I blend the center color of a 2 side gradient so it isn't as harsh looking in Unity Shader Graph?
I am using the gradient node in Unity's Shader Graph. It is 2 sided, with it being black-white-black. The white is quite harsh, it makes a line that stands out. I will be using this as a mask, and would like the white to not be so strong where it appears as a line. I don't know if this would be better to do outside of the gradient node or not.

I don't want to use an image (don't know how to create one), as I want more control in the shader.

Edit: I can add more points and make them less white to try and get a better blend, but this is very tedious and isn't perfect.

Here is what it currently looks like:

Here is what I want to achieve (even this is a little harsh, but closer to what I want):

I tried adding more points but still can't get it right:

# Answer
> 4 votes
What you're dealing with is an effect called Mach Bands. They come from our visual system highlighting the perceived contrast where two different greys meet, or where a gradient changes direction:

The linear interpolation used by the gradient node makes a sharp corner at each colour key, and our visual system highlights that first derivative discontinuity as a bright or dark line - even though it's not actually that much brighter or darker than the pixels next to it.

So, we need to smooth-out this corner so our brains' local contrast detection sees it as a gradual rounded shape instead of a sharp corner to highlight.

Here are a few different ways you can solve it:

1. **Top Row: More Keys**

You've already started down this road. You just need more. In this example my keys go...

* 0%: 0
    * 40%: 230
    * 45%: 252
    * 50%: 255
    * 55%: 252
    * 60%: 230
    * 100%: 0

You can see how this rounds-out the peak to minimize the perceived corner:

For the next two solutions, I use some math to put the curving bend into the input parameter, rather than into the gradient. So we can switch to a simple one-sided linear gradient - we'll mirror it in our input math.

2. **Middle Row: SmoothStep**

Here I take our 0...1 gradient parameter and subtract 0.5, so it goes -0.5...0...0.5

Taking the absolute value of this gives us a V shape, 0.5...0...0.5

Then we run this through a node called "SmoothStep" - this takes an input parameter and remaps it using a min/max range, so that values at/below the min map to 0, values at/above the max map to 1, and smoothes the values in-between.

It's a kind of "ease-in-out" function, that slows the rate of change of the input as it reaches the extremes, so it comes to a gradual stop at the min/max instead of slamming into them at full speed.

You can see as a consequence, this also increases the amount of dark fringes you get at the left and right sides of the gradient, as we spend a bit more time slowly easing into the dark extreme.
3. **Bottom Row: Quadratic**

Like before, we'll subtract 0.5 to get into the range -0.5...0...0.5

But instead of taking the absolute value to mirror the input at zero, we could instead multiply our parameter by itself, squaring it to get a positive number.

Unlike the absolute value function that makes a sharp corner at zero, this gives us a parabola that's smooth and flat at its vertex. We just need to multiply it by 2 first (or 4 afterward), to keep the output in the 0...1 range we want.

This both mirrors the gradient AND smoothes the corner in one step, but it has the opposite problem as SmoothStep: it spends most of its time in the bright values in the middle of our gradient, and just barely touches dark greys as it rushes to black at the edges.

You can of course adjust for both these artifacts by nudging your gradient keys around.

Or, if you're just using this for a white-to-black shading, you can skip the gradient sampling entirely and just subtract from 1 to get your output, with pure math. I show that for each of solutions 2 and 3 in the rightmost column. Note that this doesn't apply the gamma adjustment used by the gradient sampling, so you get a different pattern of light and dark this way, but you can tweak your coefficients to bring this to the shape you want.

Here's a summary of the curves for each of these solutions (plus a bonus "hybrid" that's just averaging the SmoothStep and Quadratic outputs)

---
Tags: unity, unity-shader-graph
---


# Question
Title: For my Heat I want to change the players speed but its not working
I have a heat bar for my player and I want it so if the player is at 40 heat or under the players speed slows. This is my script. The problem is when the player gets to under 40 heat the speed is not changing. Is this because I have a player speed on my movement script?

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerHeat : MonoBehaviour
{
    public float maxHeat = 100;
    public float currentHeat;
    public float heatLossPerSecond;
    public float moveSpeed = 4f;

    public HeatBar heatBar;

    void Start()
    {
        currentHeat = maxHeat;
        heatBar.SetMaxHeat(maxHeat);
    }

    void Update()
    {
        if (currentHeat <= 40)
        {
            moveSpeed = 2;
        }

        currentHeat -= heatLossPerSecond * Time.deltaTime;
        if (currentHeat <= 0)
        {
            currentHeat = 0;
        }
        heatBar.SetHeat(currentHeat);
    }

    public void Heat(float amount)
    {
        currentHeat += amount;
        if (currentHeat > maxHeat)
        {
            currentHeat = maxHeat;
        }
    }
}

```

This is my movement script

```
public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;

    public Rigidbody2D rb;
    public Camera cam;

    Vector2 movement;
    Vector2 mousePos;

    // Update is called once per frame
    void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");

        mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
    }

    void FixedUpdate()
    {
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);

        Vector2 lookDir = mousePos - rb.position;
        float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90f;
        rb.rotation = angle;
    }
}

```

# Answer
> 0 votes
**You need to make sure you either drag the `PlayerMovementScript` into the slot on the PlayerHeat script or use `GetComponent<ScriptName>()` if it is on the same object!**

What is worth bearing in mind is, all "MonoBehaviour" Scripts are Components that live on Game Objects so if you had a MonoBehaviour Script called "PlayerHealth" you could use `this.GetComponent<PlayerHealth>();` to retrieve it. Then do something like `playerHealth.TakeDamage(damageAmount);` to call **public** functions on it or, as you see below public fields(variables)

You would do something like

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerHeat : MonoBehaviour
{
    public float maxHeat = 100;
    public float currentHeat;
    public float heatLossPerSecond;
    public float moveSpeed = 4f;
    //either drag your player movement script into this slot in the inspector
    public PlayerMovement playerMovementScript;

    public HeatBar heatBar;

    void Start()
    {
        currentHeat = maxHeat;
        //or if the script is on the same object you can just do
        //GetComponent<ScriptName>();
        playerMovementScript = GetComponent<PlayerMovement>();
        heatBar.SetMaxHeat(maxHeat);
    }

    void Update()
    {
        if (currentHeat <= 40)
        {
            //here we set the moveSpeed variable of playerMovementScript to the new
            //speed!
            playerMovementScript.moveSpeed =  2;
        }
       else
       {
           //You can reset the value here if you go above 40 heat, or not, upto you!
            playerMovementScript.moveSpeed =  2;
       }

        currentHeat -= heatLossPerSecond * Time.deltaTime;
        if (currentHeat <= 0)
        {
            currentHeat = 0;
        }
        heatBar.SetHeat(currentHeat);
    }

    public void Heat(float amount)
    {
        currentHeat += amount;
        if (currentHeat > maxHeat)
        {
            currentHeat = maxHeat;
        }
        }
   }

```

---
Tags: unity, 2d
---


# Question
Title: How can I find a good fixed ratio between buying and selling prices for the player in an in-game market?
I'm developing a single player game containing gathering and crafting where I'm still struggling to find base values for the prices of gathered resources and crafted items. (But this is part of Constructing a game stock market)

Since it's a single player game and just one in-game market that offers items, I **do not** want to use dynamic pricing, I'm looking for a reasonable ratio between the buying and selling price. I was not able to find any hints on how to determine a good starting point.

Is for example 2:1 a reasonable ratio between the buying and the selling price for the player?

Things to consider:

* Of course the buying price has to be higher than the selling price or otherwise players could just make fortune by buying and selling the same item.
* Only some randomly chosen items will be available to buy in a certain time period and rarer items will be seen less often in the shop to buy.
* The offer should be reasonable enough to tempt the player to buy the item instead of farming the ingredients and craft the item for themselves.

Updated the question to fit the constraints.

# Answer
I don't know if 2:1 is reasonable, but better than that, It is well known and probably expected by the player, and accepted as fair.

In brief: I would say to go for it.

How do you decided it? Because you considered various historical examples.

Answer this requires a review of historical titles, I will concentrate on JRPGs, that I believe are familiar to most people.

The 2:1 ratio is used in many titles, including the Final Fantasy series. While I cannot speak of the latest ones, the 2:1 ratio is present in all of the 2D ones.

Now, I want to switch attention to God's forgotten Suikoden series. I can confirm that at least in Suikoden V, they did this:

```
Buy shell ratio is fixed, I believe to 2:1, but prices differs from city to city.

```

While Suikoden V prices are actually dynamic due to the Rumors mechanic, you can always remove that part.

And, of course, this is more useful if you have many towns. Why?

Let's accept the 2:1 ratio as good and switch to pricing.

You don't want dynamic pricing, but you have dynamic stocks. Items that some times aren't available. We can use that.

Teleportation, that is also very common, may get in the way of this, but that effect can be mitigated by making it somewhat costly.

When traveling between cities has an associated cost, including time, buy and sell, or craft and sell (or craft to not having to buy), doesn't have to break the game. If done right.

If you want buy and sell to provide profit for players some times, as alternative to crafting or sell raw materials, to make the game world feel more believable, but without risking to end with a broken economy, stocks may have a set limit too, with a reset cycle.

What to do when there are only one city?

There is still farming and travel cost between farming areas and stores/store. I would say to let that cost decide prices, but as we don't want dynamic pricing, then let that cost decide stock limits and refresh times.

If you don't want to think in a good algorithm to manage that, you can always use hardcoded tables.

Fill those tables with "ideal" values will require a lot of try an error.

There is a gotcha: if you do radical modification to the game map, tables have to be reviewed.

Also, the risk of players finding a way to break the game economy is present no matter the path followed, either for tables or algorithm.

**Starting point**

You have complete freedom here. Specially if it's a fantasy world.

Example:

Start to build your table of prices by inserting the initial items, usually the ones the player starts with.

Give those a sell price (from player to stores) below 100, only because 100+ would not "look good" at the start of the game. While prices over 100 for those same items may be fine when buying them back (from stores to player).

Those 100, are 100 whatever the coin of your world is. Just one small consideration, warning with the overused word "gold", because gold is a real mineral. It takes away creative freedom from us. We cannot just use any number when pricing things. Most fantasy worlds work as Earth clones at the geological level, for simplicity. This has the effect of making the initial dagger cost being 10000 gold coins sounds absurd and even 10 gold coins sounds suspicious.

If gold it o be used, have also silver and copper coins, as many MMORPGs do.

I would advice to just think in an original name for your coin, and evade the question of "of what it is made".

Now that you have some items in the table, start adding new ones be asking questions that compare those new items with items already in the table. Example: this sword does twice the damage than this other sword, a good starting price for it, on this first pass, is to give it double the price.

When you have "all" your items in the table, you can re walk the table but asking different question, for example, you can consider the narrative or even game mechanics this time. "I want more distance between prices of swords and daggers" or "this category of item has to be cheaper because everyone in this kingdom have one".

Also, you have to ask yourself how many time are you expending on this versus the value for the final product. What else have your game to offer in addition to gathering and crafting? No table of prices will be perfect no matter what you do. Throw some numbers at it and debug until you think it's not worth any more.
> 1 votes

---
Tags: game-design, game-mechanics, economy
---


# Question
Title: Why shouldn't I release my app to all countries?
When releasing a mobile app on iPhone and Android, you can specify which countries you want to release your app to. Intuitively, you may want to just release it to all countries.

One example of why you should not release it to all countries (with made up numbers):

Your app uses ad revenue. You gain $0.03 per user in the United States. You gain $0.01 per user in India. Your server costs you about $0.02 per user. So you would want to release in the United States, but not India in this case.

Why else shouldn't I release my app to all countries?

*Disclaimer: This is not specifically a game development question, but it was the most fitting site I found.*

# Answer
* You might want to release localized versions of your game in different countries. You could of course always create an universal version which auto-detects the locale settings of the user. But you might have voice-overs in multiple languages which can result in a pretty hefty filesize if you include them all. Or you might have some cultural changes to the game which require more than your i18n system can handle and require different content and programming for different locales.
* Marketing strategy. You might have limited marketing resources, so you want to stagger releases around the globe to better utilize them. A possible strategy can be to release in one country at the time so you can focus 100% of your marketing resources on that one country and then move to the next country after a couple weeks.
* When your game is an action-oriented multiplayer game, then it might be crucial for the game experience that the players have a good ping to the server. You don't want players to give you bad reviews because they live too far away from any servers to play properly. So you don't give them the game until you have a server in their country.
* Legal reasons. You might not be able to release your game in certain countries without getting into legal trouble. Perhaps your game violates a local trademark or a software patent. Perhaps you bough an IP license which isn't valid all around the globe. Or perhaps your game itself violates some laws in some countries. Either with its content (nudity, violence, blasphemy, drug use, hate speech, political activism...) or its features (gambling, privacy violation, money laundering...).
> 3 votes

# Answer
You can do a “soft-launch” of an app by releasing it only to a smaller country that has a similar demographic to your main audience. In the past, I have worked on projects released to just Canada, just New Zealand, and just Ireland, (they were games with different expected demographics based on genre).

This can be done as a public beta to iron out any kinks and to monitor user behavior, adjusting features (eg. gameplay, for balance) with a smaller set of users affected by the changes.

Once you are confident that you’re ready, you can then launch it worldwide.
> 2 votes

---
Tags: mobile, release
---


# Question
Title: How does Unity pick which sprite atlas to load?
I plan to use sprite atlases for my 2D game. All my animation is sprite animation so I'm going to use sprite atlases for my characters' sprites.

My question is, if I put the same sprite in two different atlases, how does Unity decide which atlas to load?

EX: I have a sprite atlas per level that contains the background for that level. Sometimes, there's space left over in the atlas. So, if I want to put a sprite, which already exists in another atlas, in the empty space for that level's atlas, how does Unity know not to load both atlases?

# Answer
It picks one randomly. In fact it gives a warning when you have a sprite in multiple atlases, telling you to not do that.

See here for relevant details: https://docs.unity3d.com/Manual/SpriteAtlasScenarios.html

You’re looking specifically at scenario 3 on that page:

> **Scenario 3: One Sprite in two Sprite Atlases**
>
> 1. Sprite Atlas A and Sprite Atlas B both include Sprite 1 in their Objects for Packing lists.
> 2. Both Sprite Atlas A and Sprite Atlas B have Include in Build enabled.
> 3. Both Sprite Atlases have different Texture output settings in this example.
> 4. Result: The Project’s published build includes both Sprite Atlases. ***Unity randomly chooses which Texture to render Sprite 1 with, in an internal process that is out of your control.***
> 3 votes

---
Tags: unity, spritesheet
---


# Question
Title: OnTriggerEnter error: The message parameter has to be of type: Collider
I have a crate and I want to make it so if you are in the trigger of the crate a UI appears and says "Click E to loot".

I have the UI setup but the script is not working. Here is my script and after it are the errors.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UI_Appear : MonoBehaviour
{
    [SerializeField] private Image image;

    void OnTriggerEnter(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            image.enabled = true;
        }
    }

    void OnTriggerExit(Collider2D other)
    {
        if (other.CompareTag("Player"))
        {
            image.enabled = false;
        }
    }
}

```

The errors say:

> Script Error: OnTriggerEnter
> The message parameter has to be of type: Collider
>
> Script Error: OnTriggerExit
> The message parameter has to be of type: Collider

# Answer
> 0 votes
Your error message tells you exactly what's wrong: when you implement the `OnTriggerEnter` message, Unity expects the parameter to be of type `Collider`.

But the way you wrote your `OnTriggerEnter(Collider2D other)`, its parameter is of type `Collider2D`.

These are completely unrelated types - one is from the 3D physics system using PhysX, the other is from the 2D physics system using Box2D.

If you want 2D physics, you need to use the 2D versions of these message functions, as shown in recent answers to your questions:

```
void OnTriggerEnter2D(Collider2D other)
{
    // ...
}

```

---
Tags: unity, c#, 2d, physics
---


# Question
Title: Unity 2020.1.8f1 cannot build xcode project for iOS
We recently updated a project to Unity 2020.1.8f1 But it will not build the xcode project for iOS because of missing plist key value pairs. This is really weird cus, before, I would build the xcode project, then fix the plist stuff, then build to iOS.

Here are the errors Im getting when I try to build.

```
WebCamTexture class is used but Camera Usage Description is empty. App will not work on iOS 10+.
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean &)(at / Users / bokken / buildslave / unity / build / Modules / IMGUI / GUIUtility.cs:189)

Microphone class is used but Microphone Usage Description is empty. App will not work on iOS 10+.
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) (at /Users/bokken/buildslave/unity/build/Modules/IMGUI/GUIUtility.cs:189)

```

I tried adding this script to Editor folder in assets

```
    using UnityEngine;
    using UnityEditor;
    using UnityEditor.Callbacks;
    using System.Collections;
    using UnityEditor.iOS.Xcode;
    using System.IO;

    public class AddStuffToplist {

        [PostProcessBuild]
        public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
        {

            if (buildTarget == BuildTarget.iOS) {

                Debug.Log("adding plist stuff");
                // Get plist
                string plistPath = pathToBuiltProject + "/Info.plist";
                PlistDocument plist = new PlistDocument();
                plist.ReadFromString(File.ReadAllText(plistPath));

                // Get root
                PlistElementDict rootDict = plist.root;

                rootDict.SetString("NSCameraUsageDescription","Natcorder unity asset uses this");
                rootDict.SetString("NSMicrophoneUsageDescription","Natcorder unity asset uses this");
                rootDict.SetString("NSPhotoLibraryUsageDescription","Natcorder unity asset uses this");

                //rootDict.SetString("Privacy - Photo Library Usage Description", "Natcorder unity asset uses this");
                //rootDict.SetString("Privacy - Microphone Usage Description", "Natcorder unity asset uses this");

                // Write to file
                File.WriteAllText(plistPath, plist.WriteToString());
            }
        }
    }

```

I get exactly the same errors if I use Privacy - Microphone Usage Description or NSMicrophoneUsageDescription as the key for example.

Also the debug line I added "adding plist stuff" never shows up in the console, so maybe this script is not working?

# Answer
Ok so I had a look in build settings. I was looking to see if maybe I could set a custom info.plist file before building, like setting a custom maintemplate.gradle for Android..

and I found this...

Thanks unity!
> 0 votes

---
Tags: unity, ios, xcode
---


# Question
Title: How can I move object to target then do something when reaching the target and then to move back to it's original position?
Inside Update :

```
if (finalLookWeight > 0.95f) // here you can play with a value between 0.95f -> 1.0f
                {
                    if (primaryTarget.interactableMode == InteractableItem.InteractableMode.Action
                        && IsAlreadyThrown == false)
                    {
                        // call your funtion to shoot something here
                        StartCoroutine(ThrowObject(objToThrow.transform, primaryTarget.transform, throwSpeed));
                        IsAlreadyThrown = true;
                    }
                }

```

I'm using a helper flag IsAlreadyThrown so the Coroutine will not start over and over again nonstop. But I also want to be able from outside this script using in other script to change the flag IsAlreadyThrown back to false at some places/times in the game. How can I make that I can change the flag to false from other scripts ?

And inside the ThrowObject method I did :

```
IEnumerator ThrowObject(Transform objectToMove, Transform toPosition, float duration)
    {
        float counter = 0;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            Vector3 currentPos = objectToMove.position;

            float time = Vector3.Distance(currentPos, toPosition.position) / (duration - counter) * Time.deltaTime;

            objectToMove.position = Vector3.MoveTowards(currentPos, toPosition.position, time);

            yield return null;
        }

        //StartCoroutine(ThrowBack(objectToMove, toPosition, duration));
    }

```

And :

```
IEnumerator ThrowBack(Transform objectToMove, Transform toPosition, float duration)
{
    float counter = 0;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        Vector3 currentPos = objectToMove.position;

        float time = Vector3.Distance(currentPos, toPosition.position) / (duration - counter) * Time.deltaTime;

        objectToMove.position = Vector3.MoveTowards(toPosition.position, currentPos, time);

        yield return null;
    }
}

```

The first part is working fine the ThrowObject but then I tried to start the second Coroutine ThrowBack but it's just not doing anything. The object is not moving and stay in the target position. It's getting to the line :

```
objectToMove.position = Vector3.MoveTowards(toPosition.position, currentPos, time);

```

but the objectToMove just stay in position.

This is what I want to do more or less :

```
IEnumerator ThrowObject(Transform objectToMove, Transform toPosition, float duration)
    {
        float counter = 0;

        while (counter < duration)
        {
            counter += Time.deltaTime;
            Vector3 currentPos = objectToMove.position;

            float time = Vector3.Distance(currentPos, toPosition.position) / (duration - counter) * Time.deltaTime;

            objectToMove.position = Vector3.MoveTowards(currentPos, toPosition.position, time);

            yield return null;
        }

        DoStuff(objectToMove, toPosition, duration);
    }

    void DoStuff(Transform objectToMove, Transform toPosition, float duration)
    {
        // do things when finish start the ThrowBack

        StartCoroutine(ThrowBack(objectToMove, toPosition, duration));
    }

```

At least this is the logic I want to do.

# Answer
> 1 votes
So from what I understand, you want a behaviour where, `ThrowObject` is run until completion, then you wait a specified time and start `ThrowBack`, for this I would use a third coroutine to control the execution of the first two.

So the idea being you start the `Throw` Coroutine, which then handles the running of the other two coroutines, with a `WaitForSeconds` between the calls.

```
IEnumerator Throw(Transform objectToMove, Transform toPosition, float duration)
{
    //we'll keep hitting ThrowObject every frame until it's while loop is done
    yield return ThrowObject(objectToMove, toPosition, duration);
    //if we're hitting WaitForSeconds then the loop is done, we move onto the next coroutine which is waitforseconds
    yield return new WaitForSeconds(10f);
    //now we're past the wait and back to yielding control to the ThrowBack coroutine
    yield return ThrowBack(objectToMove, toPosition, duration);
    //if we reach here we've finished
    yield break;
}

IEnumerator ThrowBack(Transform objectToMove, Transform toPosition, float duration)
{
    float counter = 0;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        Vector3 currentPos = objectToMove.position;

        float time = Vector3.Distance(currentPos, toPosition.position) / (duration - counter) * Time.deltaTime;

        objectToMove.position = Vector3.MoveTowards(toPosition.position, currentPos, time);

        yield return null;
    }
     yield break;
}

IEnumerator ThrowObject(Transform objectToMove, Transform toPosition, float duration)
{
    float counter = 0;

    while (counter < duration)
    {
        counter += Time.deltaTime;
        Vector3 currentPos = objectToMove.position;

        float time = Vector3.Distance(currentPos, toPosition.position) / (duration - counter) * Time.deltaTime;

        objectToMove.position = Vector3.MoveTowards(currentPos, toPosition.position, time);
        //yield return null essentially means "return here every frame"
        yield return null;
    }
 ///we want these coroutines to end after the while loop now
 yield break;
}

```

You may need to modify the Throw function to pass both the toPosition variables since each call is likely throwing to a different position.

Using the `Throw` wrapper to control the flow of the code, can be used in quite a few ways, for example my Spell System uses coroutines to handle a spells logic, you could have the Throw coroutine, wait for a mouse click before throwing back, or as I originally thought you were asking, use a bool (determined by an outside source) to control the logic execution.

```
IEnumerator Throw(Transform objectToMove, Transform toPosition, float duration)
{
    //we'll keep hitting ThrowObject every frame until it's while loop is done
    yield return ThrowObject(objectToMove, toPosition, duration);

    //if we're hitting WaitForSeconds then the loop is done, we move onto the next coroutine which is waitforseconds
    yield return new WaitForSeconds(10f);

    //Start an infinite while loop
     //or even while(canMove == true) etc
    while (true)
    {
        if (Input.GetMouseButtonDown(0))
        {
            //only fire the coroutine once the mouse is pressed
            yield return ThrowBack(objectToMove, toPosition, duration);
            //once the coroutine is done leave the infinite while loop
            break;
        }
        //make sure we return at the end of the while loop or unity dies
        yield return null;
    }

    //end the entire Throw coroutine
    yield break;
}

```

---
Tags: unity, c#
---


# Question
Title: Unity3d Rigidbody movement along slope slowdown
I have a Rigidbody character controller (Unity, C#) which I'm trying to make work seamlessly when walking on sloped ground. I've got it working fine walking up and down a slope by changing the forward direction to always be parallel to the ground (using the surface normal). But a strange thing is happening when walking sideways on that same slope (and not up and down it)...the character slows to a crawl. Anyone have any idea why this might happen, or how to solve it?

```
private void Walk()
{
    isMoving = false;

    if (!inChatwithNpc && !ledgeChecker.isGrabbingLedge)
    {

        isMoving = true;

        playerRigidbody.AddForce(moveDirection * moveSpeed /** multiplier*/ * Time.deltaTime);

        if (playerOnGround)
        {
            playerRigidbody.velocity = Vector3.Lerp(playerRigidbody.velocity, moveDirection * playerRigidbody.velocity.magnitude, Time.deltaTime / 0.5f);

            if (!isRunning)
            {
                playerRigidbody.velocity = Vector3.ClampMagnitude(moveDirection * playerRigidbody.velocity.magnitude, 12f);
            }

            if (isRunning)
            {
                playerRigidbody.velocity = Vector3.ClampMagnitude(moveDirection * playerRigidbody.velocity.magnitude, 18f);
            }
        }

    }

    if(!isMoving && playerOnGround)
    {
        playerRigidbody.velocity = Vector3.Lerp(playerRigidbody.velocity, Vector3.zero, 0.2f);
    }
}
private void CalculateForward()
{
    if (!playerOnGround)
    {
        forward = transform.forward;
        return;
    }

    forward = Vector3.Cross(transform.right, touch.normal);

```

# Answer
Hatoru Hansou adviced that I set velocity instead of addforce, but for various reasons involving my other locomotion requirements (wallwalking and grappeling/swinging) this is something I want to avoid because I want to use the same forces and controls during swinging and wallwalking as I do while walking (just altering speeds and gravity multipliers). So instead what I eventually did was make a imperfect solution that's good enough for now but not ideal:

I noticed that the slowdown only happened when I used my custom forward direction for the movement direction, this was based on my local forward direction crossed with the surface normal of the ground I was walking on. Meaning that my forward direction was always paralell with the slope angle. So I made a if statement that said that if my local right (which I also made paralell with the ground normal) was above or below a certain perpendicular angle (it being 90 on perfectly flat ground) I would revert the forward and right directions to the regular local directions, uncrossed with the ground normal (see code below), I also put a lerp on it to smooth the transition a little bit. This solved the problem somewhat, but when you walk up a slop at extreme diagonal angles there is still a bit of slowdown, and similarly when you walk down there is some skipping (due to forward now pointing out from the slope instead of down along it).

If anyone has a better way to solve this problem I'd love to hear it!

```
moveDirectionSlope = -right * horizontal + forward * vertical;
moveDirectionFlat = transform.right * horizontal + transform.forward * vertical;          if (groundAngleRight >= 105 || groundAngleRight <= 75)
{    moveDirection = Vector3.Lerp(moveDirection, moveDirectionFlat, 0.5f);
     playerOnSlope = false;
} else if (playerOnGround || grapplingGun.isGrappling)
{    moveDirection = Vector3.Lerp(moveDirection, moveDirectionSlope, 0.5f);
     playerOnSlope = true;
}

```
> 1 votes

---
Tags: unity, c#, rigidbody, character-controller
---


# Question
Title: How do I scale my spell target indicator to match the radius of OverlapSphere
I have a spell system in which some spells have an Area of Effect. To get the targets I use `Physics.OverlapSphere`. I show the player an indication of the spell's radius by spawning a Unity plane primitive at the target position and scaling it to match the radius of the spell.

**How would I scale my spell target indicator visual to correctly match the radius of OverlapSphere?**

I have tried setting the scale of the plane's X,Y,Z to radius * 2, but this does not seem to align with the overlap sphere radius.

```
data.indicatorInstance.transform.DOScale(data.parent.radius * 2, 0.5f);

```

And just for completeness sake, below is the OverlapSphere call.

```
Physics.OverlapSphere(targetPosition, data.parent.radius)

```

# Answer
> 2 votes
The default Plane primitive in Unity has a width of 10 units, so its center-to-edge distance is 5 units.

So if you want the edges of your plane to kiss the edges of your OverlapSphere test, you'll want to divide your radius by `5.0f` to get the right scale factor for the plane..

However, the visible circles in your indicator are smaller than the extents of the plane itself, so you might want to use a smaller denominator to align the sphere check with these rings instead.

To find the appropriate number, place both your target indicator plane and a default Unity sphere primitive at the origin, with scale (1, 1, 1). Uniformly scale the sphere primitive until it lines up with the ring on your target indicator you want to match to the sphere check. The default sphere has a radius of 0.5, so this radius is half the scale factor you used.

eg. If I have to scale my sphere primitive to a scale of (6.2, 6.2, 6.2) to line up with the right circle on the indicator, then the radius of that circle is 0.5 * 6.2 = 3.1. So to match this to the radius of an OverlapSphere check I need to divide the check radius by `3.1f` to get my plane's scale factor.

---
Tags: unity, mathematics, geometry, scale
---


# Question
Title: How to convert relative position of child to parent into an absolute position?
I am modifying a game that stores object positions with a 3d vector `{ x, y, z }` and rotation as a 3d vector with degree angles `{ x, y, z }`.

I want to place an object in relation to a parent object accounting for its rotation. I do not have access to the game code, so I have to provide a position of the child as an absolute position.

For example, I would like to place a child object at a relative position `{ 50, 0, 100 }`: 50 units along the x axis and 100 units up the z axis from the parent's position.

Assuming the parent object is currently at position `{ 0, 0, 0 }` with rotation `{ 0, 0, 0 }` the resulting absolute position for the child object would be simply `{ 50, 0, 100 }`.

But, if the parent has a position of `{ 0, 0, 0 }` and a rotation of `{ 0, 0, 90° }`, the child's absolute position would be `{ 0, 50, 100 }`.

What would be the transformation function that, given the absolute parent position, parent rotation, and relative child position, outputs the absolute position of the child (taking into account all three axes of rotation)?

# Answer
First, construct a quaternion or rotation matrix from the parent's rotation angles.

Multiply your local position offset vector by this matrix or quaternion to get the offset in world space.

Lastly, add the parent position to get the child's absolute position in world space. (You can fold this into the previous step if you use a 4x4 homogeneous matrix with both rotation and translation combined)
> 1 votes

---
Tags: rotation, vector, position
---


# Question
Title: Diagonal discontinuity in perlin noise terrain
I'm using Bilinear filtering to interpolate perlin-noise based height data. However, when I render the resulting plane mesh, there is this obvious diagonal discontinuity in the generated terrain.

**See Edit below.** I'm guessing it could either be an error in how I'm interpolating the data, or in how I am assigning the heights back to the plane vertices. But I haven't been able to fix it. Anybody has seen this type of error? What could it be?

I'm using the bilinear algorithm technique found here. My vertices step laid bottom up, left to right (I.e. vertex 0 is at the bottom left).

**Edit:** I have tried using a heightmap texture instead of noise generated data and I think the problem lies in how I am flattening the 2D texture data into a 1D array. If I use the overload in those methods that explicitly uses a float\[,\] array it works with a real texture. If I convert the same texture to a 1D array I see the diagonal discontinuity.

This is the code I'm using to flatten the data

```
    public static float[] ConvertToXYflat(Color[] data, int res)
    {
        float[] converted = new float[data.Length];
        int idx = 0;
        for (int i = 0; i < res; i++)
        {
            for (int j = 0; j < res; j++)
            {
                converted[idx++] = data[(i * res) + j].r;
            }
        }
        return converted;
    }

```

The unity docs say that the texture pixels are laid row by row, left to right, bottom to top. That is also the pattern that my vertices have.

This is how the array of heights is constructed.

```
        // world size dimensions of the plane mesh
        Vector2 dimensions = new Vector2(terrainMesh.Width, terrainMesh.Height);
        int resolution = 1023;
        for (int i = 0; i < positions.Length; i++)
        {
            newHeights[i] = TerrainFilters.TerrainBilinear(nativeHM, positions[i].x, positions[i].z, MaxHeight, -dimensions/2, dimensions, resolution-1);
        }

```

Filtering method:

```
public static float TerrainBilinear(NativeArray<float> heightMap, float worldX, float worldZ, float height, Vector2 worldSize, Vector2 dimensions, int resolution)
    {
        float x = ((worldZ - worldSize.y) * resolution) / dimensions.x;
        float z = ((worldX - worldSize.x) * resolution) / dimensions.y;

        int fx = (int)math.floor(x);
        int cx = fx + 1;
        int fz = (int)math.floor(z);
        int cz = fz + 1;

        int res = resolution + 1;

        float hx0z0 = heightMap[fx * res + fz] * height;
        float hx1z0 = heightMap[cx * res + fz] * height;
        float hx0z1 = heightMap[fx * res + cz] * height;
        float hx1z1 = heightMap[cx * res + cz] * height;

        return hx0z0 + (hx1z0 - hx0z0) * (x - (int)x) + (hx0z1 - hx0z0) * (z - (int)z) + (hx0z0 - hx1z0 - hx0z1 + hx1z1) * (x - (int)x) * (z - (int)z);
    }

```

Then I iterate a second time and add those heights to the original plane vertices like so:

```
    public void UpdateHeights(float[] heights)
    {
        Vector3[] newVertices = new Vector3[vertices.Length];
        Array.Copy(vertices, newVertices, vertices.Length);

        for (int i = 0; i < heights.Length; i++)
        {
            newVertices[i].y += heights[i];
        }
        mesh.SetVertices(newVertices);
        mesh.RecalculateNormals();
    }

```

Clearly not the most efficient way, but I need to get the basics working correctly before improving it.

# Answer
> 1 votes
For future reference, the problem causing the diagonal discontinuity was due to the sampling in the filtering function happening on an array whose rows were 1 position too short. Simply making sure that the value of the "resolution" passed to the function had the correct value (+1) fixed the problem.

---
Tags: unity, terrain, heightmap, noise
---


# Question
Title: Workflow for authoring Pokémon-like game database content
I'm programming on a game that relies on a database for a lot of the creatures and items in the game (think Pokémon).

Currently, we have a Google Sheet that the designers are making. They will be using it to populate all of the items necessary for the game, so it acts as a 'source of truth'. However, to translate this into the database (SQLite) we'll need to write some code to pull the data, format it and put it into the database. The maintenance of this will also be pretty annoying, as we already need to maintain the database schema and the code representation (Unity C#). DB tables are can be static or dynamic, and the implementation on the Unity side for the DB is not an issue.

Before writing this code I'm exploring other options. I've looked into Microsoft Access (and similar programs) but they seem to be geared towards making applications now and don't have much in the way of SQLite integration. I'm leaning towards using a visualizer tool like DB Browser for SQLite or SQLiteStudio, but the lack of cloud syncing might mean a janky solution with Google Drive or AWS.

I'm looking for a workflow that:

1. will be accessible for game designers (who have little to no SQL experience, but willing to learn)
2. will keep changes between designers synced
3. will be easy to manage and maintain for the codebase and SQLite database.

How can we solve this problem?

# Answer
> 5 votes
I would generally not use a SQL database (not even SQLite) for handling static data in a singleplayer game. The only exception would be if I had so much data that it won't all fit into RAM. But when the data is less than a couple hundred MB, I would look for a solution which loads all the data when the game starts and then allow the game to access it directly.

## Solution within Unity: Scriptable Objects

A solution completely within Unity would be to work with scriptable objects. A scriptable object is a game-specific asset type. So you could create a `class CreatureType : ScriptableObject`. This enables you to create "CreatureType" assets in the Unity editor which you can then manage in the Unity project outline like any other Unity asset.

You can then assign these assets to inspector properties of `MonoBehaviour`'s and thus assign them to prefabs or objects within your scene. You can also have ScriptableObjects referencing other ScriptableObjects. So you can, for example, have another ScriptableObject type for the various attacks your creatures can perform and then assign attacks to creature types via drag&drop.

When the standard controls for public fields are insufficient for your purpose, you can use Editor Scripting to enhance the inspector of these assets to better fulfill your game designers needs.

## Solution with files

However, scriptable objects have their limitations when it comes to editor support. While the Unity editor is very extensible, it can take a lot of development resources to essentially reinvent what you can already do in a spreadsheet application.

So another solution is to keep the data in a file format editable with a spreadsheet application, import that file into a Unity project as a Text Asset and then load and parse that file at game start.

Perhaps the most developer-friendly format for that is CSV, because:

* It can be handled by most spreadsheet applications, but can also be edited with a simple text editor when in a pinch.
* It is very easy to write a parser for it.
* The raw files are pretty human-readable and use one text-line per data entry, which means it can be handled well by text-based version control systems like Git.

But depending on the needs of your designers you might need to compromise and use a more advanced spreadsheet file format.

# Answer
> 4 votes
Multi-user concurrent transaction support will be required if you have multiple designers who are not actively deciding who will work on the data at such-and-such a time. Without this, data can be corrupted. Implementing such an advanced feature yourself, would consist of far more effort than it would be worth, when you are only trying to write a game. Large / proprietary DBs do support this transaction model, but you'd still be stuck with designers using a raw DBMS to do their work.

On the other hand, Git is very good at synchronising the work of multiple users commiting at any time they like, if your designers are willing to work in pure text files. This provides a simple solution and your designers will quickly enough learn to work with CSV. Besides, you will not have to pay for expensive services or worry about (any single revision of) your data ever being lost.

**CSV (text)**, import CSV into Excel / Calc, then export to CSV before they commit/push to the git repository. This will also tie in easily with your development pipeline, since devs these days use Git for source control of code. Indeed - you could be using the very same source repository for *everyone* \- major win.

**JSON (text)** is another solution if your data is inherently more hierarchical in nature, as opposed to flat. This eliminates the traditional DB concept of joins, allowing for an easier-to-follow setup if designers are willing to use JSON editors, instead (there are some nice ones out there). This also is text, and so can also be pushed to Git and kept safe at every single revision.

---
Tags: unity, game-design, databases, workflow
---