# Question
Title: How should I organize the type advantages and disadvantages for my monster-catching RPG?
I’m making a Pokémon-like game called Beasts of Iatu. The problem I’m having is creating a chart for the attack and defense changes between types. There are fourteen types in Beasts of Iatu, though only twelve are relevant here (The Time and Soul types are neutral, taking no extra damage but dealing no extra damage as well). The twelve standard types

* Fire
* Earth
* Water
* Air
* Void
* Light
* Metal
* Plants
* Ice
* Sound
* Lightning
* Dust

Each type should deal heightened damage to two others, and deal lessened damage to two others. EDIT: Upon reflection, I realized there were too many types. I have removed Darkness, Gravity, and Cloud as a result.

# Answer
> 3 votes
A cute trick I like to use to investigate this kind of type advantage system to simulate how players might use those types when competing with each other.

Even if your game is purely PvE or doesn't have this type of random matchmaking, it can be useful to *imagine* it did - what *would* all my NPC trainers and gym leaders be choosing, if they had free will and were actually trying to win against each other?

If, given a variety of opponents, you're statistically less likely to win if you field a Water type, then players would tend to avoid that type, and as a developer you get less gameplay bang-for-buck out of the resources you've invested into making cool Water-type monsters. So imagining this competitive landscape can help us spot such issues, even if we haven't yet planned out the final parties of all the opponents in the game.

Here's what such a model could look like, using just the first five of your elements to keep things simple for a demo:

The basic idea is this: at any moment, the population of competing players has certain preferences for one type vs another. Maybe Fire is hot right now, and folks think Air is underpowered, so you don't see many players fielding Air monsters. That describes the current state of the game's "meta" - a probability distribution over the possible strategies you're likely to see from an opponent in a random match.

Based on that distribution, you can calculate how advantageous it would be to field a monster of each type. If not a lot of players are playing Air, then you're less likely to get your 2x damage bonus if you use Void, so Void becomes less likely to have an advantage in that mix.

Then we iterate. Based on which types were advantageous vs the meta in the previous time step, we simulate some portion of the players (controlled by the "Mobility" parameter) changing their strategies - moving away from types at a disadvantage in the current meta, and toward types that currently have an advantage. This gives us a new meta, with slightly different preferences for types, and we iterate again.

That's what this spreadsheet is doing. From an initially random set of preferences (maybe day 1 players choose monsters purely based on looks), each row simulates one state of the meta and how attractive each type is in that state, then the next row is the state after a portion of the players change their strategies.

You can see that with the perfectly symmetrical pattern of advantages and disadvantages, from any random starting state, the lines converge to approximately equal ratios (what would be a "mixed strategy Nash equilibrium"). In this simulation, there's still some oscillation around the true equilibrium point of 20% chance to encounter each type, because our fixed mobility percentage means our simulated players tend to over-correct for imbalances when they're small. But in practice, players have imperfect information and their strategic responses lag, so it's not unusual to find most players in "donkey space" like this.

So far, this seems like a lot of math to just graph what you already knew: if everything has 2 advantages, things balance out!

Well, *almost*. Here's another scheme where each type is strong against two other types, but I broke the symmetry so they no longer form a neat loop of mutual counters. I've left Earth with no strong counter at all:

Here, the lack of a cyclic counter allows Earth to climb up to nearly 80% dominance, with barely anyone daring to field a Water or Air monster (who would be weak to Earth).

So it's not just the number of strengths/weaknesses that matter, but also how they're arranged.

Symmetric arrangements (like Philipp's "place them in a circle" strategy) are consistently stable. But by playing with this kind of model you can find reasonably-stable arrangements even with non-symmetrical patterns of advantage.

This can help if you want to break the symmetry for the sake of gameplay variety and to create a more complex problem space for players to learn and master (e.g. Pokémon's type chart is famously chaotic).

But it can also help you plan for the case where asymmetries creep in via your monster design or other second-order effects. Maybe it's true that the type advantages are balanced assuming monsters within those types are otherwise interchangeable, but if Earth monsters tend to have more HP or higher Defense stats in addition to their type advantage, then the net effect might be more like...

Here I lowered all the numbers in the Attacks vs Earth Defender column by 10% to simulate this extra edge from toughness in the monster design. You can see Earth type does now get more popular because it's statistically better... but it doesn't completely dominate. Less than 30% of monsters fielded are Earth in the equilibrium - higher than 20% perfect balance, but not so lopsided as to sap all variety from the game.

This is the effect of the "Perfect Imbalance" Philipp described. Because Earth still has strong counters - monsters that do better when players get too greedy in fielding Earth monsters - even a fairly substantial "balancing error" in the monster design doesn't cause the meta to collapse into one type completely dominating or completely not worth playing.

Checking for robustness against deviations like this is useful, because in practice it's actually quite difficult to get two different monsters that have exactly equal odds of winning, without balancing them to bland sameness. So even those white "1x / no advantage" boxes will usually end up being something more like 1.05 or 0.8, just due to emergent interactions of your combat mechanics. Watch out for this with your Time and Soul types - relying on exactly equal balance without counters to catch emergent biases is fragile!

It's also interesting to see that one of Earth's counters, Air, stays more popular than the other, Water, because Water is weak to Air in this scheme. So this sim can be useful for seeing what second-order effects and emergent dynamics come out of different degrees of imbalance.

# Answer
> 2 votes
First of all, are you sure you need that many different types? Just because they are thematically appropriate does not necessarily mean they are useful from a game design perspective. When you are already struggling with how to balance them, then it might be easier to start out with fewer types (probably by merging some of them into one), prototype the game, look for design problems that become apparent during playtesting, and introduce additional types if those might help to fix those design problems.

The first step of the design process should be to start simple and then add additional complexity. In case of a damage-type mechanic like here, that would be a standard rock-paper-scissors setup where each type has as many other types it counters as there are types it is countered by. The simplest way to solve this is by arranging all the types in a circle. Every types counters those types to its left and is countered by the types to its right. You might have to experiment a bit with the order to make sure that all those weaknesses and vulnerabilities make thematic sense, and if you can't then that probably means that you might have to rethink your selection of types.

Assuming all other properties of the monsters being balanced against each other as well, this gives you a "perfect balance". No types is clearly dominant, and who wins depends on the matchup.

But while a perfect balance setup can be a simple and easy way to achieve balanced gameplay, it can also get a bit boring. There is no real strategy when all choices are equally viable by design. To spice things up, you can go for a design principle called "perfect imbalance". Perfect imbalance means that some choices are clearly superior to others, but are kept in line by having explicit counters. Those counters are otherwise inferior, but excel at countering the superior choices. For example, you could have a "dark" character who is ridiculously overpowered against everything except "light". And then counter that one with a "light" character who is overpowered against "dark" but underpowered against everything else.

# Answer
> 0 votes
Coming up with what beats what is not the kind of thing we do here. It is your game, your design, your rules.

With that said, we can still help you tackle the problem.

---

I believe the easier way to approach this is to use loops.

In the minimum case we have rock-paper-scissors, where each "element" beats the next. While the loops of three elements are the most common (for example cavalry-infantry-archery, water-plant-fire), bigger loops are also used.

Since you want each element to be weak to other two, and strong to other two, it means you want each element to belong to two loops.

Therefore, the minimum number of loops you need to create is: 2. In which case both loops use all the elements. Yet, you could create more loops, each one of them being smaller.

---

Thus, methodology:

Start by picking some element, come up with what element beats it, and then come up with some element that beats that one until you make a loop (you made it back to the first element).

Repeat that with the elements you didn't use, until there are no elements left.

Note that there is a failure mode here: you might end up leaving some element left alone and thus unable to make a loop with it, in which case you will have to go back and edit some of the loops you created to include it. A similar case is when you have two elements left, which I'm not sure if it is desirable, but that is for you to decide.

At this point every element belongs to a loop (each is weak against one other element, and strong against one other element). So do the process again but without repeating what you picked, that way element will belong to two loops (each will be weak against two other element, and strong against two other element).

Et voilà. *You can, of course, review and iterate on top of it if you want to.*

---

Of course, you might find some advantage hard to explain. Which, although it is more of a writing problem than a design problem... Conveying the design is important!

At some point you got to explain or otherwise allow the player to discover these advantages as part of the game.

I'm sure you can come up with story justifications. However what I'm getting to is this: if you can, be open to the possibility that changing some elements might better for the story - or better to convey their advantages as part of the story. *You never know when ideas will come, and sometimes the constraints of a system inform creativity.*

---
Tags: game-design, balance, combat
---


# Question
Title: Vertices index access violation when loading mesh by Assimp
Currently, i am implementing the model loading feature for my game engine using Assimp. But i got an access violation error when loading my FBX model. The problem is that although the `mNumVertices` is around 100629 vertices, I got this error at `i = 50314` in the `for` loop.

This is my code for loading the mesh.

```
   #include"Mesh.h"
   #include <assimp/scene.h>
   #include <assimp/postprocess.h>
   #include <assimp/Importer.hpp>
   #include <assimp/DefaultLogger.hpp>
   #include <assimp/LogStream.hpp>
   #include"Core/Log/Logger.h"
   #include"Renderer/Renderer.h"

  namespace {
    const unsigned int ImportFlags =
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_SortByPType |
        aiProcess_PreTransformVertices |
        aiProcess_GenNormals |
        aiProcess_GenUVCoords |
        aiProcess_OptimizeMeshes |
        aiProcess_Debone |
        aiProcess_ValidateDataStructure
    ;
}

struct LogStream : public Assimp::LogStream {
    static void Initialize()
    {
        if (Assimp::DefaultLogger::isNullLogger())
        {
            Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE);
            Assimp::DefaultLogger::get()->attachStream(new LogStream, Assimp::Logger::Err | Assimp::Logger::Warn);
        }
    }

    void write(const char* message) override
    {
        LIGHT_LOG_ERROR("Assimp error: {0}", message);
    }
};

Mesh::Mesh(const std::string& filePath) : mFilePath(filePath) {
    LogStream::Initialize();

    LIGHT_LOG_INFO("Loading mesh: {0}", filePath.c_str());

    Assimp::Importer importer;

    const aiScene* scene = importer.ReadFile(filePath, ImportFlags);
    if (!scene || !scene->HasMeshes()) {
        LIGHT_LOG_ERROR("Failed to load mesh at file path {0}", filePath);
    }

    aiMesh* mesh = scene->mMeshes[0];
    scene->mNumMeshes;
    LIGHT_ASSERT(mesh->HasPositions(), "Meshes require positions.");
    LIGHT_ASSERT(mesh->HasNormals(), "Meshes require normals.");

    mVertices.reserve(mesh->mNumVertices);

    for (size_t i = 0; i < mVertices.capacity(); i++)  {
        Vertex vertex;
        vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
        vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };

        if (mesh->HasTangentsAndBitangents()) {
            vertex.Tangent = { mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z };
            vertex.Bitangent = { mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z };
        }

        if (mesh->HasTextureCoords(0)) {
            vertex.TextureCoords = { mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y };
        }

        mVertices.push_back(vertex);
    }

    mVertexBuffer.reset(VertexBuffer::Create());
    mVertexBuffer->SetData(mVertices.data(), mVertices.size() * sizeof(Vertex));

    // Extract indices from model
    mFaces.reserve(mesh->mNumFaces);
    for (size_t i = 0; i < mFaces.capacity(); i++)
    {
        LIGHT_ASSERT(mesh->mFaces[i].mNumIndices == 3, "Each face must have 3 indices.");
        mFaces.push_back({ mesh->mFaces[i].mIndices[0], mesh->mFaces[i].mIndices[1], mesh->mFaces[i].mIndices[2] });
    }

    mIndexBuffer.reset(IndexBuffer::Create());
    mIndexBuffer->SetData(mFaces.data(), mFaces.size() * sizeof(MeshFace));
}

```

I also tried with other models too, but got the same error. I noticed that it always throws this error when the index `i` is roughly half of the `mesh->mNumVertices`.

* My model is totally fine, there is no problem with it.
* I use Assimp version v.5.25 and build it as a static library.
* The vertex position is also loaded with weird numbers.
* I also run a break point in the Assimp to see if model is loaded correctly and it did. But one strange thing here is that the scene pointer seems to be destroyed when returned from the ReadFile() function.

```
const aiScene* scene = importer.ReadFile(filePath, ImportFlags);

```
* I link this `assimp-vc143-mtd.lib` file after building the Assimp to my engine.

So, can you guys help me fix it? Does it have something to do with the memory allocation?

# Answer
It looks like you're using `capacity()` instead of `mesh->mNumVertices`  in your loop condition. Note that `reserve()` can make the capacity of the vector bigger than the capacity that you requested.

Given that it looks like you're iterating over a vector of pointers, that will probably be the cause of the crash because you'll be dereferencing uninitialized ones when you iterate out of bounds.

On top of that your loop condition is checking against the capacity of `mVertices`, instead of the size of `mesh->mVertices`.

Try something like this for your loop:

```
for (size_t i = 0; i < mesh->mNumVertices; i++)  {
    Vertex vertex;
    vertex.Position = { mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z };
    vertex.Normal = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };

    if (mesh->HasTangentsAndBitangents()) {
        vertex.Tangent = { mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z };
        vertex.Bitangent = { mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z };
    }

    if (mesh->HasTextureCoords(0)) {
        vertex.TextureCoords = { mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y };
    }

    mVertices.push_back(vertex);
}

```
> 0 votes

---
Tags: c++, assimp
---


# Question
Title: What is the difference between @onready and _ready()?
In Godot 4.x, is declaring @onready variable ***exactly*** the same as declaring it within the \_ready() function?

```
@onready var my_variable : = 10

func _ready():
   var my_variable : = 10

```

If not, when/what/how does it make a difference?

# Answer
> 7 votes
They are similar in the sense that both deferred assignment until after the node has entered the tree. However in the example you gave, **they differ with respect to their scope.**

```
@onready var my_variable : = 10

```

The first example you gave (shown above) has class/script level scope. In other words the variable is considered defined everywhere in that script and can be used to share data between functions.

```
func _ready():
   var my_variable : = 10

```

The second example you gave (repeated above) the variable has function level scope. It is only considered defined & usable on the lines that come after it and **only** within that function. For example if you try the following:

```
func _ready():
   var player_health : = 10

func take_damage():
   player_health -= 2

```

The result will give an error when the line `player_health -= 2` is reached because the scope of `player_health` is restricted to the `_ready()` function.

---

The example given isn't a particular useful application of `@onready` \- there's no clear reason why you might need to defer assigning an int as shown. In contrast, consider the example in the docs of assigning

```
var my_label

func _ready():
    my_label = get_node("MyLabel")

```

Note the key difference: in your example you used the keyword `var` inside the `_ready()` function whereas this here we do not.

In the above case, you *cannot* use a regular assignment because `get_node()` doesn't make sense if the Node has not yet entered the tree. So the code example above waits until the `_ready()` function to assign the value. Because this pattern is common in Godot, they added some syntactic sugar to save us some typing by shortening the above code block to the following:

```
@onready var my_label = get_node("MyLabel")

```

Whether you prefer the single line or the multiline version, they only make sense when you need to make an assignment that cannot be evaluated until after the Node is in the tree.

# Answer
> 4 votes
Pikalek answer is correct, but there is more we can say about the difference between `@onready` and `_ready`.

Also it can use a bit of nuance: both `@onready` and `_ready` will run when the `Node` has entered the scene tree... And after `@onready` and `_ready` has run for all children `Node`s... And only the first time... Unless you call `request_ready`, which will make it run again the next time the `Node` enters the scene tree. *You can check `is_node_ready` to know if they already ran.*

*And that is the main difference between using `_tree_entered` (which runs when the `Node` enters the scene tree, no matter what) and `_ready`. The other is that `_tree_entered` runs before `_ready`.*

Now for additional differences (aside from scope):

* What you have in `@onready` will run before `_ready`.
* `@onready` only applies to initializing variables. You can do other things in `_ready`.
* `@onready` is limited to expressions. While `_ready` can have statements.

Something related to scope is lifetime. In this case, local variables only take memory while the method/function (e.g. `_ready`) is running... But fields (class/script level variables) will be stored for the lifetime of the object (the `Node` in this case). In other words, your `@onready` variables will be around until the `Node` is freed (with `free` or `queue_free`).

So when it comes to splitting execution into multiple lines:

* Using `@onready`, since `@onready` statements run in order, you might use the result of prior ones... Yet, the `Node` would be storing those variables for its lifetime.
* Using `_ready`, you don't only can use temporary local variables, but you can also use statements.

Thus, `_ready` is preferible for complex initialization.

---

By the way, as you know, the point of `@onready` is to wait until the scene tree is available before initialization. Consequently any class/script variable without `@onready` is initialized early, but for them accessing the scene tree (e.g. with `get_node`) will fail.

Which begs the question, is there method/function that can be used to do early initialization? And yes, there is: `_init`.

---
Tags: godot
---


# Question
Title: Detect intersections between an `AABB` and a `CollisionShape3D`
I thought this would be a simple matter of getting the mesh that defines the `CollisionShape3D` and checking if any of the triangles of the mesh intersect with the `AABB`, but that didn't work. Let me explain.

I'm doing some custom volumetric 3D pathfinding in Godot 4. For this, I need to loop over all the `CollisionShape3D`s in a scene and check if they're in some region of space defined by an `AABB`.

I thought I'd loop over each `CollisionShape3D`, get its mesh, loop over each surface in the mesh, use `MeshDataTool` to loop over the faces in the surface, and then finally check each face for a collision with the `AABB`:

```
func check_for_colliders_in_aabb(colliders: Array[CollisionShape3D], box: AABB):
    for collider in colliders:
        var mesh = collider.shape.get_debug_mesh()
        for surface_idx in range(mesh.get_surface_count()):
            var mdt = MeshDataTool.new()
            mdt.create_from_surface(mesh, surface_idx)
            for face_idx in mdt.get_face_count():
                # Check if the face intersects with the AABB

```

But nothing happens. Specifically, I've figured out that `mdt.get_edge_count()` and `mdt.get_face_count()` both return zero. Also, while `mesh.get_aabb()` returns a correct-looking AABB, `mesh.get_faces()` returns an empty list.

I think this might be because the "primitive type" of the mesh is wrong. When I check `mesh.surface_get_primitive_type(0)`, the primitive type I get back is `1` which corresponds to `PRIMITIVE_LINES`, so I guess the mesh doesn't have any triangles, and therefore no faces? Each `CollisionShape3D` is just using a `BoxShape3D` as it's shape, no other adjustments have been made from the default `CollisionShape3D`.

Note that checking if any of the vertices/edges are in the `AABB` is NOT an option, because the faces of the `CollisionShape3D`s can be quite big, and my `AABB`s quite small so it's entirely possible that an `AABB` could be bisected by a face of a `CollisionShape3D` without any of the edges/vertices of that face actually intersecting with the `AABB`.

Is it possible to convert the mesh into one that does have triangles so that I can check each of the triangles for a collision with the `AABB`? If this is not possible, how would I check if some `CollisionShape3D` is intersecting/colliding with some `AABB`?

# Answer
I'll suggest to check the collision using Godot physics below.

But first, about the mesh you are getting...

---

## The Debug Mesh

It makes sense that you get lines from `get_debug_mesh`. The documentation says:

> Returns the ArrayMesh used to draw the debug collision for this Shape3D.

Which, yes, it is a mesh, it does not have triangles. For reference, this is how a `CollisionShape3D` with a `BoxShape3D` is drawn in the engine:

No triangles. *Yes, that is what you are getting.*

---

## On the conversion of a Shape to a Mesh

> Is it possible to convert the mesh into one that does have triangles so that I can check each of the triangles for a collision with the AABB?

Not really. The primitive shapes are not meshes internally, which allows for some optimizations.

Consider, for example, an `SphareShape3D`... If it were a mesh internally physics would have to checks tons of faces for it, but being an sphere handled as an special case allows to check collision based on the distance to the center, which makes one of the fasters colliders, if not the fastest.

Of course, you could go into the trouble of approximating them with meshes. The easier way to go about is probably to check the type, and use one of the built-in mesh types (A `BoxMesh` for `BoxShape3D`, a `SphereMesh` for a `SphareShape3D` and so on).

---

## Checking the collision from code

> If this is not possible, how would I check if some CollisionShape3D is intersecting/colliding with some AABB?

I believe the easier way is to create a collider with a `BoxShape3D` for you AABB and orquestarte Godot to check the intersectation.

For this is better to avoid using `Node`s (after all, if you drop a collider in the scene tree, other things might detect it, which might be problematic for the game).

Instead, let use `PhysicsDirectSpaceState3D`, which you can get from any `Node3D` like this:

```
var space := get_world_3d().direct_space_state

```

And now we have a few options for what we want:

* `collide_shape`: Returns contact points.
* `intersect_shape`: Returns a dictionary with collision information.
* `cast_motion`: unlike the other two, this one tests if moving the shape will collide. In other words: It is a a shape cast.

It is unclear to me exactly what you need, so I'll refer you to the documentation of `PhysicsDirectSpaceState3D`.

Regardless, they are both used similarly, you need to pass an `PhysicsShapeQueryParameters3D` and the maximum number of results you want, as arguments, in that order.

You can create the `PhysicsShapeQueryParameters3D` like this (here I'm setting some properties to their default values for illustration purposes):

```
var query := PhysicsShapeQueryParameters3D.new()
query.collide_with_areas = false
query.collide_with_bodies = true
query.collision_mask = 4294967295

```

It is important that you set `transform` and `shape`, so let us get them from our `AABB` (I'm assuming the `AABB` is in global coordinates):

```
var box_shape := BoxShape3D.new()
box_shape.size = aabb.size
query.transform = Transform3D.IDENTITY.translated(aabb.get_center())
query.shape = box_shape

```

And we can query (`collide_shape` in this case):

```
var result := space.collide_shape(query, 32)
prints(result)

```
> 2 votes

---
Tags: collision-detection, godot, 3d-meshes
---


# Question
Title: Draw a sprite x number of times in GDscript
Ok this has stumped me. In Godot 4.x, how do I programmatically (GDscript) draw a sprite x number of times (with an offset)?

I can manually add sprites in the editor over and over again. Only I don't want to do that or rely on add them and then switching off their respective visibility

```
var max_limit = 5
for n in range(max_limit):
    print(n)
    draw sprite at (x + 10*n,y)

... much later
max_limit -=1

```

So the above loop will draw four sprites, instead of five.

Currently I've added a sprites with a number of frames and change the frame number to control the number of sprites shown. - But that really is going the long way around.

# Answer
For what you say, I take you want to avoid using multiple `Node`s for this. And in fact, we can avoid using multiple objects.

Instead we will do it in `_draw`. To begin with you need an `Node2D` or a `Control`. *In this answer I'll be working with a `Node2D`, the main change with using a `Control` is that you would also want to update its `size` or `custom_minimum_size`.*

```
extends Node2D

```

And, of course, you need the texture you want to draw.

```
extends Node2D

@export var texture:Texture2D

```

Here `@export` tells Godot to allow setting this field (class/script variable) from the Inspector.

Now we are going to override `_draw`:

```
extends Node2D

@export var texture:Texture2D

func _draw():
    pass

```

And here we draw the texture using `draw_texture`:

```
extends Node2D

@export var texture:Texture2D

func _draw():
    draw_texture(texture, Vector2.ZERO)

```

We might want the texture to update when we change it in the editor, so let us make this a tool script, and give `texture` a setter:

```
@tool
extends Node2D

@export var texture:Texture2D:
    set(mod_value):
        if texture == mod_value:
            return

        texture = mod_value
        queue_redraw()

func _draw():
    draw_texture(texture, Vector2.ZERO)

```

The setter is a method that will run every time the field is set.

Here calling `queue_redraw` notifies Godot that the `Node2D` needs to be updated, so it calls `_draw` again.

So, just to be clear, Godot is not calling `_draw` every frame. Instead it caches the result.

Ah, we might want to handle a `null` texture:

```
@tool
extends Node2D

@export var texture:Texture2D:
    set(mod_value):
        if texture == mod_value:
            return

        texture = mod_value
        queue_redraw()

func _draw():
    if texture == null:
        return

    draw_texture(texture, Vector2.ZERO)

```

Better.

Now, about the loop, let us start with what you have:

```
@tool
extends Node2D

@export var texture:Texture2D:
    set(mod_value):
        if texture == mod_value:
            return

        texture = mod_value
        queue_redraw()

func _draw():
    if texture == null:
        return

    var max_limit = 5
    for n in range(max_limit):
        draw_texture(texture, Vector2(10*n, 0.0))

```

Ok, so what happened to `x` and `y`? Nothing, it is just that our drawing is attached to the `Node2D`, so you can move the `Node2D` to position it, which is why I have `Vector2(10*n, 0.0)` instead `Vector2(x + 10*n, y)`. *And yes, you can also rotate, scale or skew the `Node2D`.*

And, of course, you want to be able to change `max_limit`, so let us make it a field:

```
@tool
extends Node2D

@export var texture:Texture2D:
    set(mod_value):
        if texture == mod_value:
            return

        texture = mod_value
        queue_redraw()

@export var max_limit := 5:
    set(mod_value):
        if max_limit == mod_value:
            return

        max_limit = mod_value
        queue_redraw()

func _draw():
    if texture == null:
        return

    for n in range(max_limit):
        draw_texture(texture, Vector2(10*n, 0.0))

```

And that's it.

---

**Addendum**

You hard-coded a - depending who you ask - magic number `10`.

Without further context, I would suggest to promote it, either to a `const` or to an `@export` field.

However, if you wanted to use the width of the texture, well:

```
func _draw():
    if texture == null:
        return

    var width := texture.get_width()
    for n in range(max_limit):
        draw_texture(texture, Vector2(width*n, 0.0))

```

And, yes, it is also possible to clip/tile the texture, or draw it scaled. For that you would use `draw_texture_rect` or `draw_texture_rect_region`, respectively.
> 1 votes

---
Tags: sprites, godot-4
---


# Question
Title: How to Constantly Apply a Force to a Rigidbody Within a Coroutine?
For my game, I am trying to write an enemy behavior script, where the enemy walks forward for 1 second, then stands still for 1 second, then walks forward, stands still, etc. To implement this, I have written the following code:

```
bool isWandering = false;

void FixedUpdate
{
    if (!isWandering)
    {
        isWandering = true;
        StartCoroutine(Wander());
    }
}

IEnumerator Wander()
{
    Debug.Log("wandering");
    EnemyRB.velocity = new Vector2(walkSpeed * walkDir, EnemyRB.velocity.y);

    yield return new WaitForSeconds(1f);

    Debug.Log("waiting");

    yield return new WaitForSeconds(1f);

    isWandering = false;
}

```

For the most part, this seems to be working. The issue however, is that whenever the enemy moves forward, it moves for an extremely brief period before stopping. I have tried to increase the number of seconds it is supposed to walk, but it doesn't seem to make it walk for any longer than before.

How might I go about applying the force to the enemy's rigidbody for the entirety of the 1 second window? Thanks!

# Answer
Keep setting the velocity every physics tick until the one second has elapsed.

```
IEnumerator Wander() {
    Debug.Log("wandering");

    var wait = new WaitForFixedUpdate();
    for (float t = 0; t < 1f; t += Time.deltaTime) {
         EnemyRB.velocity = new Vector2(walkSpeed * walkDir, EnemyRB.velocity.y);

         yield return wait;
    }

    Debug.Log("waiting");

    yield return new WaitForSeconds(1f);

    isWandering = false;
}

```
> 0 votes

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


# Question
Title: Is it safe to store the state of a game in Javascripts localStorage?
I am going to be completely honest, this is not 100% about storing a game state in Javascript's localStorage, it is more to do with a utility program storing statistics. Since it can be related to games I am asking here, rather than on StackOverflow which is more to do with coding. I know how to code it.

My worry is this. I want a person to store their statistics for a web-app in localStorage. It will be stats they could be collecting over a year or so. It will be saved automatically so they do not have to worry about a thing.

The problem I have is they can accidently, without knowing it, delete these statistics when they delete cookies when they delete the browser's history.

Most web-app users are not experts and will not know they are deleting their localStorage for my Stats-Web-App when they delete all their other browser history.

**What can I do to make this safe?**

I could obviously let them save to the File/Directory system (which I also know how to code), but that is more cumbersome for them and through experience I find they often forget.

I just do not know what is considered best practices.

For a game, if they lost their save, its just a bit of bad luck. Maybe a week or so play. But for stats they have been collecting for a year, it could be soul destroying.

I value your opinion.

# Answer
> 0 votes
I'd agree that this question doesn't really belong in the Game Development stack exchange, but it doesn't really matter.

In general treat local storage as temporary. Nothing that needs to persist for long periods of time should be stored there.

The way I see it you have two options:

1. Do the local file saving thing you mentioned
2. Use some sort of database (probably a BaaS such as Supabase or Firebase)

Option two will provide more versatility over option one but will take more time to implement.

---
Tags: javascript, savegame
---


title: What does the Project Manager star do?

text:
# Question
Title: What does the Project Manager star do?
Can't seem to find any reference to this,

...but what does the star on the left hand side Godot Engine Project Manager actually do?

Yes, I also need better names for my projects.

# Answer
They mark a project as *favorite* so the project appears on top of the list.
> 1 votes

---
Tags: godot-4
---


# Question
Title: Why should a game include a range of possible damage values per hit?
I’m asking this because this reminds me of critical hits, preventing battles from being too predictable, BUT if I already have crits… why would I have damage ranges?

Especially in action games, there’s so much going on that you don’t get to notice the bigger hits (unlike turn-based games, where you can nearly feel them), so the question is…

Why would I keep damage ranges in my ARPG? What are the basic considerations? Are there common patterns like “always limit it to 10%” or “make it 30 if such and such…”?

In this game I’m talking about, it may be relevant to know you cannot dodge hits, so everything is RNG, from the odds of being hit to the amount of damage you take.

# Answer
> 5 votes
One thing that randomness of damage does is to make it so that the benefit of additional health behaves more linearly.

Consider the case where an attack always does 100 damage. In that case a health value anywhere between 101 and 200 has the same effect - it takes two hits to reduce that to zero. With some damage randomness, it's no longer the case that having 101 health is twice as good as having 100 health.

Obviously that example is fairly extreme, and those effects are reduced when the damage is small relative to the quantity of health, and where you have a variety of different attacks.

# Answer
> 2 votes
This all comes down to your goals for your game. You need to ask yourself: "why am I considering adding variable damage? What problem does it help fix, or what player experience does it help serve?"

As you note, randomized damage provides roughly the types of gameplay impacts we get from critical hits, so most of the reasons discussed in that Q&A thread can also apply to non-critical damage variation, if you find your critical hits alone aren't fully serving those goals.

A reason to pursue randomized damage ranges beyond just discrete criticals could be verisimilitude: the real world is messy. Even an expert in a skill usually doesn't perform it identically every time. So an element of randomness in the exact damage number can express that, and make the character's actions feel slightly more organically inconsistent, rather than mechanically same-y.

But if your game is about robots or computer programs battling in the digital world, maybe that kind of organicity actually speaks *against* your game's thematic goals.

One reason to *not* have randomized damage is if you want to make it easy for the player to predict the outcome several steps into the future, like a tactics game, or one with RPG elements where you want the player to be able to make analytical judgements about which build to use. And where you want this type of min-maxing gameplay to be clearly legible and learnable, not obfuscated behind a layer of superficial variation.

But if you're designing a game for more casual play and don't want players getting sucked into analysis paralysis where they try to min-max every encounter, a little random fuzz can help them resist that temptation.

The more random variation you add, the more inconsistent the gameplay can feel. On the plus side, this can keep the player on their toes, or force them to mix up their play when the random rolls don't always come out the same, increasing variety and combatting stagnant dominant strategies. But too much can make the game feel capricious, like it's "cheating", or de-value player agency, and also make your mechanics harder to learn (especially if you have small percent damage buffs whose effects can get swamped by random noise).

So you need to interrogate what you want out of your game's combat system, what you're getting out of your existing critical mechanics, and whether there's a delta left over that needs to be served by additional variation or other changes to your systems.

# Answer
> 0 votes
## Some baseline effects to consider

**Slow games**
If your game has only few instances of damage happening at a time (for example turn based games), having damage variation adds unpredicatability beyond the binary of crit vs non-crit. With just **crit** or **non-crit** you can find yourself for example in a situation where you "need" at least one crit in your next three attacks to win the encounter with a certain strategy. That is easy to math out and appeals to an audience that likes to plan ahead with a very good sense of probabilites and then see if their plan is supported by their luck or not. Damage variation to a reasonable degree can quickly make the needed calculations for "how many hits do I need?" almost unmanageable, appealing more to a audence that plans less and just makes decisions on the get go for the next move based on the current situation. On a sitenote, having damage variation that is more influential than crits can leave a bad taste. Example: you deal 1-6 damage and have a 10% chance to crit for 2x damage. Then you can have "crits" deal only 2 damage (often accompanied by some extra oomph animation) while a normal hit might deal 6 damage (without that animation), leading to the feeling of a "wasted" crit. Therefore I'd suggest either keeping the damage variation below the "crit-multiplier" or having other mechanics preventing that kind of experience.

**Fast games**
In fast games with LOTS of hits damage variation evens out really quick and is often not very interesting as a game mechanic. In contrast to critical hits which often have a possibility to "invest" into as a mean to increase your damage output, most games do not feature such an opportunity into "damage variation".
However there are games that do allow investment into that factor. For example Path of Exile, where for some builds only the hardest hit in the last few seconds is important, so they invest into an item that increases the damage variation to higher highs but also to lower lows.

So for fast paced games where you don't want to give the player the possibilty to "invest" into damage variation, the main factor to consider might be @Adams answer, that damage variation helps to flatten out the impact of damage buffs.

# Answer
> 0 votes
The other answers are great, but I wanted to add another perspective to your question.

Dealing the same amount of damage makes a battle more predictable, which could make the game boring. If you have one attack only that deals `100` damage, and your enemy only has one attack that deals `50` damage, and you both have `500` health, your brain can pre-calculate most of the encounter already before it even starts!

For a game to be fun, there needs to be an amount of unpredictability. As you noted critical hits can do that, also dealing variable amounts of damage can also do that.

Having said that, having damage be variable doesn't automatically make a game fun. You need a good balance of, the battle has some unpredictability, but it's also not pure chaos. Different games apply this in different ways, up to you to discover what works for your project!

---
Tags: mathematics, game-design, game-mechanics
---


# Question
Title: Interacting with UI with a locked cursor?
It seems like Unity has disabled UI interaction while the cursor is locked, which is frustrating because the store in my game is an actual in-world one, and thus means the player has to look at the buttons and click. What are some ways around this?

# Answer
> 1 votes
> the player has to look at the buttons and click

So you have a fixed reticule and you need to aim and click at buttons? Add colliders and raycast to detect hits on the buttons. You can put all of your UI on another layer (maybe name it InWorldUI) and limit your raycasts to that layer and another layer that blocks visibility (so you can't click buttons through walls).

Your UI is essentially the same as shooting a gun at buttons to click them, so you can set up your logic the same way.

To support hover, do your raycast regularly instead of only on click.

# Answer
> 1 votes
You need to override `StandaloneInputModule.GetMousePointerEventData(int id)` and remove the lines that prevent this from happening:

```
if (Cursor.lockState == CursorLockMode.Locked)
{
    // We don't want to do ANY cursor-based interaction when the mouse is locked
    leftData.position = new Vector2(-1.0f, -1.0f);
    leftData.delta = Vector2.zero;
}

```

# Answer
> 0 votes
You can interact with the UI with the cursor locked, but cannot use the mouse, only the keyboard, which is indeed not ideal. We all manage the locking/unlocking in code using a state machine approach so that you lock/unlock the cursor depending on the game state. When the player enters a store you unlock the cursor and lock it again when the player leaves the store.

# Answer
> 0 votes
To riff off of @nicholas-zhang's answer, replacing the StandaloneInputModule component on EventSystem with this new component seemed to do the trick:

```
using UnityEngine;
using UnityEngine.EventSystems;

public class CustomInputModule : StandaloneInputModule {
    protected override MouseState GetMousePointerEventData(int id) {
        if (Cursor.lockState == CursorLockMode.Locked) {
            try {
                Cursor.lockState = CursorLockMode.Confined;
                return base.GetMousePointerEventData(id);
            } finally {
                Cursor.lockState = CursorLockMode.Locked;
            }
        }

        return base.GetMousePointerEventData(id);
    }
}

```

`Cursor.lockState` looks like it's a native call, so it's probably not the most performant, but also...seems to work fine.

---
Tags: unity, gui, unity-ui
---


# Question
Title: How to make a moving GameObject push a CharacterController smoothly?
I have a GameObject called **Player** with a CharacterController component attached that has the following settings.

**Player** also has a script called `PlayerController` attached.
Gravity is applied to the CharacterController through the following function, which is called in `Update()`.

```
private void ApplyGravity()
{
    if (!characterController.isGrounded)
    {
        moveDirection.y -= gravity * Time.deltaTime;
    }
}

```

The **Player** has a child GameObject called **PlayerModel** which just has a default CapsuleCollider attached.

The `PlayerController` has an additional function called `MoveAround()`, which is also called in `Update()`; incase this is related to the issue.

```
public void MoveAround()
{
    Vector2 moveInput = playerInputActions.Player.Move.ReadValue<Vector2>();

    currentInput = new Vector2(moveInput.y, moveInput.x);

    float moveDirectionY = moveDirection.y;

    float speed = isSprinting ? sprintSpeed : walkSpeed;

    moveDirection = (transform.forward * currentInput.x + transform.right * currentInput.y) + boatController.boatRigidbody.velocity;

    moveDirection.y = moveDirectionY;

    moveDirection.Normalize();

    moveDirection *= speed;
}

```

I have a GameObject called **Boat**, which has a default BoxCollider, Rigidbody and `BoatController` script attached; the Rigidbody has the following settings.

The **Boat** is floating on water, therefore moving up and down.
The **Player** is resting on the surface of the **Boat**.
When the **Boat** floats up, the **Player** is pushed upwards with it. When it floats back down, the `ApplyGravity()` function is called, bringing the **Player** back down with it.

The Scene setup looks like this.

> The problem is this process is not smooth.
> The **Player** jitters at the collision point when being pushed up, and when falling back down.

I have attempted trying to snap the **Player** position to the surface of the **Boat**, however this causes the same issue.
Building on from that, I have also tried using the combination of `Physics.Raycast()` and `Vector3.Lerp()` to grab the surface position and smoothly move the **Player** to that position respectively; this caused some strange bugs (but I could've implemented it incorrectly).

Any advice on how to solve this is much appreciated.

# Answer
Generally the best way to handle a character on any sort of moving platform is to make the character object a child of whatever it is standing on.

That way, movements of the platform will perfectly translate into movements of the character.

Just remember to unparent them when the character is no longer supported by the platform.
> 0 votes

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


title: Error in DataStore2

text:
# Question
Title: Error in DataStore2
I'm trying to make a clicker type game in roblox, although im pretty new to datastore2. I know how to use datastore but after getting just a :SetAsync() a few times a minute is too much for it as most people know. I watched an AlvinBlox tutorial on DataStore2, and have made a test with it (DataStore2 is successfully installed).

Error (also when using this the leaderstats aren't working): `Model.MainModule:566: DataStore2() API call expected {string dataStoreName, Instance player}, got {string, nil}`

Scripts

Main Script In ServerScriptService with datastore2 (i know that dnacps wont be saved as im justing using that for a test rn):

```
local DataStore2 = require(1936396537)
local onClick = game.ReplicatedStorage:WaitForChild("onClick")
local displayClicks = game.ReplicatedStorage:WaitForChild("displayClicks")
local default = 0
local dnapc = 1

game.Players.PlayerAdded:Connect(function(player)

    local DNADS = DataStore2("dna",player)

    local leaderstats = Instance.new("Folder",player)
    leaderstats.Name = "leaderstats"

    local dna = Instance.new("IntValue", leaderstats)
    dna.Name = "DNA"

    local function dnaUpdated(updatedVal)
        dna.Value = DNADS:Get(updatedVal)
    end

    dnaUpdated(default)

    DNADS:OnUpdate(dnaUpdated)

end)

onClick.OnServerEvent:Connect(function(val)
    local DNADS = DataStore2("dna", player)

DNADS:Increment(dnapc, default)
    displayClicks:FireClient(val)
end)

```

LocalScript (in with gui, this game is gui focused):

```
local onClick = game.ReplicatedStorage:WaitForChild("onClick")
local displayClicks = game.ReplicatedStorage:WaitForChild("displayClicks")

script.Parent.Activated:Connect(function()
    onClick:FireServer()
end)

displayClicks.OnClientEvent:Connect(function(val)
    script.Parent.Parent:WaitForChild("DNA").Text = "DNA: "..val
end)

```

I hope this is enough to help.

Any help appreciated!

# Answer
`Player` is local because function parameters are always local. You are attempting to access it in a different function. You may want to try this:

```
[...]
local thePlayer -- thePlayer is local, however, it can be accessed in functions which are in the same script

game.Players.PlayerAdded:Connect(function(player)
    thePlayer = player
    [...]
end)

onClick.OnServerEvent:Connect(function(val)
    local DNADS = DataStore2("dna", thePlayer)
    [...]
end)

```
> 0 votes

---
Tags: roblox
---


# Question
Title: Pathfinder is making my NPC follow my oldest position only
I am trying to make a maze/horror game. I used an online template in the Roblox library as my enemy. I used pathfinder as you will see in the code below. It's finding me like it's supposed to, except it only goes for my LAST position. As you can see in the image below, it completely skipped me, went to my LAST position, then started chasing me. I don't know why it only goes for my last position, and not my current position.

```
local PathFindingS = game:GetService("PathfindingService")
local humanoid = script.Parent:WaitForChild("Humanoid")
local rootPart = script.Parent:WaitForChild("HumanoidRootPart")
local Players = game:GetService("Players")
game.Workspace.Fruity.Humanoid.WalkSpeed = 60

--To calculate the path
while wait() do

    for i, player in pairs(game.Players:GetPlayers()) do
        local character = game.Workspace:WaitForChild(player.Name)
        local characterPos = character.PrimaryPart.Position
        local path = PathFindingS:CreatePath()
        path:ComputeAsync(rootPart.Position, characterPos)
        game.Workspace.Fruity.HumanoidRootPart:SetNetworkOwner(nil)

        local waypoints = path:GetWaypoints()

        for i, waypoint in pairs(waypoints) do
            local part = Instance.new("Part")
            part.Shape = "Ball"
            part.Material = "Neon"
            part.Size = Vector3.new(0.6,0.6,0.6)
            part.Position = waypoint.Position + Vector3.new(0,2,0)
            part.Anchored = true
            part.CanCollide = false
            part.Parent = game.Workspace
            humanoid:MoveTo(waypoint.Position)
            humanoid.MoveToFinished:Wait()
        end
    end
end

```

# Answer
> 0 votes
So, your code is just telling the character to move to a certain position. What you would need to do is make a loop so it runs and updates constantly.

# Answer
> 0 votes
Your code tells the character to pathfind to your position and then walk there and not stop going on that path until it gets there.

Try making the character only go to the first waypoint that the pathfinding algorithm finds, then recalculating the pathfinding. This is what it would look like:

```
while wait() do
    for i, player in pairs(game.Players:GetPlayers()) do
        [...]
        local waypoints = path:GetWaypoints()

        for i, waypoint in pairs(waypoints) do
            local part = Instance.new("Part")
            [...] -- Do the other stuff you did to the part
            part.Parent = game.Workspace
        end
        humanoid:MoveTo(waypoints[1].Position)
        humanoid.MoveToFinished:Wait() -- Note that this approach (recalculating after every waypoint) can be very resource-intensive with many players or long distances
    end
end

```

---
Tags: lua, roblox
---


# Question
Title: Synchronizing in-game clock vs real world clocks across servers started at different times
Regardless if you know how Roblox works or if you know Lua syntax, I just need an algorithm/equation here.

Currently, at the start of each server, I reference the seconds of a centralized clock since 00:00:00 June 1, 1970 (UTC). I want to synchronize all servers in-game times by referencing the same clock and then run at a fraction of real world's time in each server separately. So I have a ratio of a real-world second to my in-game second.

Where I'm stuck at though is when I start a server, then a second one at 100 seconds later, I'm referencing real-world time at the start of both, but the first one has already ran 100 in-game seconds so it's now out of sync.

I'm trying not to have to make a shared value from which to pull the only clock onto every server. So is there any possible way to use like a catch-up function? So I catch up from the time missed out between those real world 100 seconds that is now like 1 hour differential between servers?

Any algorithms or equations for that?

# Answer
Try `os.date`:

```
local date = os.date("!*t")
local minute = (date.hour + [A number for timezones]) * 60 + date.min

```
> 0 votes

---
Tags: lua, synchronization, roblox, time
---


# Question
Title: My Roblox Gui does not update while in game
In my Roblox game, I'm trying to do 2 things with my UI: 1. I am trying to make the "Coins: " text = "Coins: " plus the number of coins the player has. 2. I am trying to make a shop Gui show up when you touch a part. But whenever it's updated, it doesn't show up in-game. I checked the properties while running the game and it says "Coins: 10" and "Enabled: True" but it doesn't show up in game, here are some images:

here is the coins script:

```
local part = script.Parent
local click = part.ClickDetector
local coinsGUI = game.StarterGui.ScreenGui2.TextLabel2
_G.damage = 1
local health = 10
local dealingDamage = false
_G.coins = 0
local coinsWorth = 10

local function onClick()
    while health > 0 do
        dealingDamage = true
        wait(1)
        health -= _G.damage
        print(health)
    end
    dealingDamage = false
    health = 0
    part.Transparency = 1
    part.CanCollide = false
    print("okay that works")
    _G.coins += coinsWorth
    print("that works too")
    coinsGUI.Text = "Coins: " .._G.coins
    print("okay")
    part.Transparency = 0
    print("i dont see what the problem is then")
    health = 10
    part.CanCollide = true
end

click.MouseClick:Connect(onClick)

```

and here is the shop script:

```
local part = script.Parent
local confirmGui = game.StarterGui.ScreenGui
local yesButton = confirmGui.TextButton2
local noButton = confirmGui.TextButton

print(confirmGui.Enabled)

--local function onTouch(coolPerson)
local function onTouch(coolPerson)
    print("function ran")
    local parent = coolPerson.Parent
    if game.Players:GetPlayerFromCharacter(parent) then
        confirmGui.Enabled = true
        print("detects player")
    end
end

part.Touched:Connect(onTouch)

```

# Answer
> 1 votes
You are modifying the value in StarterGui, not the one in the player's GUI. StarterGUI is only used when a new player joins to give them the GUI.

Modify the GUI inside of `game.Players.[PlayerName].PlayerGUI`.

In your case, you should do the following:

Script 1:

```
[...]
game.Players:GetPlayerFromCharacter(parent).PlayerGui.Enabled = true
[...]

```

Script 2:

```
[...]
local function onClick(plr)
    [...]
    plr.PlayerGui.ScreenGui2.TextLabel2.Text = "Coins: " .._G.coins
    [...]
end
[...]

```

---
Tags: gui, roblox
---


# Question
Title: Is it possible to have a fixed camera without a CameraSubject?
I have created a very simple script to set up a fixed camera with no subject. In other words, I want a camera in a static position looking down at the world (a top-down style camera that doesn't follow anything), but regardless of what I do, the camera always attaches to a "Humanoid".

Is there a way to prevent this?

For reference, here is my script, which I name CameraScript and place in the StarterPlayerScripts group:

```
local cameraHeight = 150

local camera = game.Workspace.CurrentCamera
local player = game.Players.LocalPlayer

repeat
        wait()
until player.Character

local function setupCamera()
    camera.CameraType = Enum.CameraType.Fixed
    camera.CameraSubject = nil
    camera.CFrame = CFrame.new(Vector3.new(0,cameraHeight,0), Vector3.new(0,0,0))
    print(tostring(camera.CameraSubject))
end

setupCamera()

```

# Answer
Your script errors on the line:

```
repeat
        wait()
until player.Character

```

With `.`, it gives an error when trying to access nil, however `FindFirstChild` simply returns nil. Try:

```
repeat
        wait()
until player:FindFirstChild("Character")

```
> 0 votes

# Answer
create a part above said world and have a camera fixed on it, make it transparent though
> -2 votes

---
Tags: lua, roblox
---


# Question
Title: Gaps between terrain chunks generated with marching cubes
My generated terrain chunks have gaps between them:

I'm using Compute Shader and Simplex Noise from FastNoiseLite library to generate noise:

```
 #pragma kernel GenerateNoise
#include "Includes\FastNoiseLite.compute"

RWStructuredBuffer<float> _Weights;

static const uint numThreads = 8;

int _chunkSize;
int _seed;

float _NoiseScale;
float _Amplitude;
float _Frequency;
int _Octaves;
float _GroundPercent;

float chunkPosX;
float chunkPosY;

int coordToIndex(int x, int y, int z)
{
    return x + _chunkSize * (y + _chunkSize * z);
}

[numthreads(numThreads, numThreads, numThreads)]
void GenerateNoise (uint3 id : SV_DispatchThreadID)
{
    fnl_state noise = fnlCreateState(_seed);
    noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
    noise.fractal_type = FNL_FRACTAL_RIDGED;
    noise.frequency = _Frequency;
    noise.octaves = _Octaves;

    float3 pos = id * _NoiseScale;
    float ground = -pos.y + (_GroundPercent * _chunkSize);

    float n = ground + fnlGetNoise3D(noise, id.x + (chunkPosX * _chunkSize), id.y, id.z + (chunkPosY * _chunkSize)) * _Amplitude;
    _Weights[coordToIndex(id.x, id.y, id.z)] = n;
}

```

Chunks have **size** of 16. I tried to increase my chunks size by 1, but this is impossible because **numThread** = 8 and as a result when I dispatched shader I have threads per group equal to **2** so my noise values for "extended parts" of chunks don't calculated.

Any ideas how to fix these "gaps"?

# Answer
> 1 votes
I fixed this problem.

There were 16x16 vertices per mesh and new chunk coordinates were calculated as:

```
Vector2 chunkCoord = new Vector2((currentLocalChunkCoordX + x), (currentLocalChunkCoordY + y));

```

Now, I assume that there are 17x17 vertices per mesh, and the updated new chunk coordinates would be:

```
Vector2 chunkCoord = new Vector2((currentLocalChunkCoordX + x) * 0.9f, (currentLocalChunkCoordY + y) * 0.9f);

```

Now the problem is fixed:

Thanks for your responses.

---
Tags: unity, procedural-generation, terrain, compute-shader, marching-cubes
---


# Question
Title: Find force feedback device for joystick device
Because SDL 1.3 is still a long way coming, I implemented native force feedback (rumble) support for Aquaria

However, I could not find a way to find the corresponding event device (force feedback device) for any given joystick (gamepad) device. I looked in the SDL 1.3 source and I thought this might be how it is done:

```
std::ostringstream os;
os << "/dev/input/js" << sdl_index;
std::string jsdevice(os.str());
char evdevice[128];
evdevice[0] = 0;

int fd = open(jsdevice.c_str(), O_RDONLY, 0);
if (fd <= 0) {
    std::cerr << "Could not open joystick [" << jsdevice << "]: " << strerror(errno) << std::endl;
    return;
}

if (ioctl(fd, EVIOCGNAME(sizeof(evdevice)), evdevice) == -1) {
    std::cerr << "Could not get event device for joystick [" << jsdevice << "]: " << strerror(errno) << std::endl;
    close(fd);
    return;
}

close(fd);

// ...

```

But it always just prints this:

> Could not get event device for joystick \[/dev/input/js0\]: Invalid argument

Currently, I use an environment variable to indicate the force feedback device that should be used. Does anyone know how to automatically find the correct device? What I've got is the input device as an index (e.g. the 0 in `/dev/input/js0`) and therefore the path.

# Answer
The joystick devices (/dev/input/js\*) can be queried via the ioctl function code defined in "joystick.h" (codes starting with JSIOC). The general input devices (/dev/input/event\*) can be queried with the codes defined in "input.h" (codes starting with EVIOC).

Of course each joystick device has an associated event input device. I do'not know if this is for true for all distributions, but on my OpenSuse system, there are mappings like

/sys/class/input/js0/device/event7

Google for libjoyrumble.c to find some example code to detect the matching event device.

Heiko
> 2 votes

# Answer
Use the tool `evtest` from the force feedback/joystick suite. It listed the necessarz device nicely for me:

```
# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
...
/dev/input/event23: Microsoft SideWinder Force Feedback 2 Joystick
Select the device event number [0-23]:

```

See also https://askubuntu.com/questions/1450181/force-feedback-joystick-support-ms-sidewinder-ff2/1450223#1450223
> 0 votes

---
Tags: input, linux, joystick, force-feedback
---


# Question
Title: How can I do something after an audio has finished
How can I enable the `SetActive()` property of a game object after the audio has finished?

# Answer
> 12 votes
you need wait until `audiosource.isPlaying == false`

> Suspends the coroutine execution until the supplied delegate evaluates to true. WaitUntil can only be used with a yield statement in coroutines.

https://docs.unity3d.com/ScriptReference/WaitUntil.html

```
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(AudioSource))]
public class AudioManager : MonoBehaviour
{
    public GameObject obj;
    public AudioClip audio;
    private AudioSource audiosource;

    void Start()
    {
        audiosource = GetComponent<AudioSource>();
        audiosource.clip = audio;
        audiosource.Play();
        StartCoroutine(WaitForSound(audio));
    }

    public IEnumerator WaitForSound(AudioClip Sound)
    {
       yield return new WaitUntil(() => audiosource.isPlaying == false);
       // or yield return new WaitWhile(() => audiosource.isPlaying == true);
    if(obj != null)
    obj.SetActive(true); //Do something
    }
}

```

---

perhaps you ask what is `()=>` mark? this is Lambda Expression

> A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls. Lambda expressions are particularly helpful for writing LINQ query expressions.

https://msdn.microsoft.com/en-us/library/bb397687.aspx

what is different between WaitUntil & WaitWhile? this post will help you:

The Mystery of WaitUntil & WaitWhile in Unity 5.3 Revealed!!

---

**Update**:I find simple way for do something after an audio has finished.each sound have length, so we can `WaitForSound(duration)`.

```
using UnityEngine;
using System.Collections;
using UnityEngine.Events;

[RequireComponent(typeof(AudioSource))]
public class AudioFinish : MonoBehaviour
{
    public AudioClip audioclip;
    private AudioSource _audiosource;
    private float _duration;
    public UnityEvent onFinishSound;

    private void Awake()
    {
        Initialize();
        StartCoroutine(WaitForSound());
    }

    public void Initialize()
    {
        _audiosource = GetComponent<AudioSource>();
        _audiosource.clip = audioclip;
        _audiosource.Play();
        _duration = audioclip.length;
    }

    IEnumerator WaitForSound()
    {
        yield return new WaitForSeconds(_duration);
        print("FinishAudio");
        onFinishSound.Invoke();
    }
}

```

# Answer
> 0 votes
Many posts indicate issues with using WaitForSeconds as well as WaitWhile(AudioSource.isPlaying) giving incorrect values if the clip is paused, game loses focus, or if the pitch of the audio is altered.

So I believe I've found a better solution:

```
public void PlayClipAndActivate()
{
    StartCoroutine(PlayAudioThenActivateGameObject(myAudioClip));
}

private IEnumerator PlayAudioThenActivateGameObject(AudioClip clip)
{
    audioSource.clip = clip;
    clipSource.Play();
    yield return new WaitUntil(() => audioSource.time >= clip.length);
    gameObject.SetActive(true); //Whatever it is that you're wanting to do.
}

```

By using the AudioSource.time and AudioClip.length you're comparing the playback position to the length of the clip, which should always be correct. I have tested this successfully with pauses and pitch changes.

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


# Question
Title: How to make real-time pvp game where both players perceive in-game time normally while actual relative time-flow speed between them is different?
I was thinking about making a real-time (not tour-like) PvP game where both players among other attributes would have 'speed' attribute that would define their movement and attack speed.

But because the speed can be very fast (for example 50 attacks within one second), too high speed would make it difficult for players to fully utilize it (as they would have very hard time reacting on time on the events in the fight and instead of definite advantage the would struggle with controlling their characters).

Therefore the best solution would be changing time flow speed between players - so for faster players the in-game time would flow slower comparing to players with slower speed.

Ideally I would like to make it like the player with higher speed sees themselves in normal speed and their opponent seems slowed down while players with slower speed would see themselves in normal speed while their opponent seems abnormally fast.

And here I encounter the problem.

While implementing such mechanics in single player games (player vs AI) wouldn't be difficult, I can't find the way to do that for PvP. The time flow for both players in their real life is obviously the same which kinda leads to paradoxes if we assume different time flow in in-game world.

One way could be making the player with slower speed perceiving the slow motion effect while the opponent moves normally - but it won't be realistic (especially if there are more than 2 players - because then only fastest player moves normally and all other players on ENTIRE battlefield experience being more or less slowed down just because there is one fast guy - feels like killing the purpose).

So my question is.. is there any way to do this or it is really entirely impossible to achieve the effect?

Thank you in advance for help! \<3

# Answer
## Combining different techniques

There are multiple techniques to achive this and all of them will feel really bad for the player if overdone. To reduce the "bad feeling" I suggest to combine multiple ones to have just a bit "bad feeling" in multiple ways instead of one big "bad feeling".

## Slowing down and speeding up

This you already mentioned yourself. The "faster" player moves faster and the "slower" player moves slower. This works reasonably well for a few percentage difference but becomes unpractical when the difference is big. Examples For one player to be 20% faster than the other one player having 108% speed and their opponent having 90% speed would be playable, achieve the purpose and feel ok. For one player being 10x as fast as the other one player having 300% speed and their opponent having 30% speed would be unplayable, would not achieve the purpose of increased reaction time for the faster player and feel generally bad.

Also note that the slowing effect should be limited to when enganging in combat with a faster player. While not engaged even a 10% slow can be frustrating.

## Artifical lag

The increase of reaction time in comparsion with their opponent can also be achived via artifical lag. The slower Player could get some lag added to reduce their reaction time in comparsion with their faster opponent. Again, in small amounts (From the top of my head I'd say in the \<2000 ms range) this doesnt feel to bad and achives the purpose. If overdone the game becomes unplayable for the slower player.

## Local perception filters

As in the paper linked by DMGregory local perception filters can also help in granting the bullet time effect, especially in long ranged combat. In close combat they don't work.

## how I would combine it all

While the players are not engaged, I would just increase the speed of fast players without slowing down the other players. When running down a street "the flash" doesn't need the increased reaction time and can just experience their full speed.

When engaging at a distance I would slow the fast player a bit and use the local perception filters and also give the slower player some artifical lag. (e.g. the faster player goes from 200% to 150% and simulating the remainging 50% via lag and perception filters).

When engaging in close combat the perception filters don't work so good anymore so that is replaced by actually slowing down the slower player.

Now it would be up to you to try this out and to tweak the numbers.
> 1 votes

# Answer
I think this part "only fastest player moves normally and all other players on ENTIRE battlefield experience being more or less slowed down" is where you are having difficulty. If you consider that the entire game is run on the server clock and, for each observer, their time scale is their own (a speed factor relative to server speed = 1), then there is no paradox because one's personal time cannot affect the other observers. To implement: for the observer that has faster time, you can simulate that by multiplying deltatime by the \> 1 factor to increase movement in proportion, and similar with the number of attacks. Ditto for the slower player with factor \<1. This is actually very similar to the realtime difference in deltatime due to faster/slower framerates that people with faster machines experience, except you are making the number of attacks scale with the artificial time speed.
> 0 votes

---
Tags: multiplayer, game-mechanics, realtime, timing, time-management
---


# Question
Title: Character walks too fast when browser's hardware acceleration is turned off
I have posted a project on itch.io (here). **My character walks with the speed I intended when Chrome's hardware acceleration is turned on but walks much faster when it is turned off**. First, my friend tested on his PC and I thought it was about different devices, but when I toggle hardware acceleration on and off the problem shows on my PC as well...

Here is the code I have used to move the character:

```
void Update()
{
    change = Vector3.zero;
    change.x = Input.GetAxisRaw("Horizontal");
    change.y = Input.GetAxisRaw("Vertical");
    if(Input.GetButtonDown("attack") && currentState != PlayerState.attack){
        StartCoroutine(AttackCo());
    } else if(currentState == PlayerState.walk){
        UpdateAnimationAndMove();
    }
}

void MoveCharacter()
{
    change.Normalize();
    myRigidbody.MovePosition(
        transform.position + change.normalized * speed * Time.deltaTime
        );
}

void UpdateAnimationAndMove()
{
    if (change != Vector3.zero){
        MoveCharacter();
        animator.SetFloat("moveX", change.x);
        animator.SetFloat("moveY", change.y);
        animator.SetBool("moving", true);
    } else {
        animator.SetBool("moving", false);
    }
}

```

Here's the character walking at normal speed (hardware acceleration turned on):

Here's the character walking super fast (hardware acceleration turned off):

Moreover, on my friend's PC, it was moving so fast he'd clip through walls.

# Answer
> 2 votes
I found the solution.

Quoting this discussion thread: "Inputs are provided by the player on a frame-by-frame basis. They never need to be scaled based on framerate, since you don’t want the same mouse movement to have an arbitrary effect in-game."

I just removed `* Time.deltaTime` from the `MoveCharacter` method and now his speed is consistent through devices.

---
Tags: unity, webgl, unity-webgl, hardware-acceleration, deltatime
---


# Question
Title: How to assign a Resource Array to a variable in Godot 4?
In Godot 3, you could do this:

```
export var (Array, Resource) test_variable

```

I tried to recreate this in Godot 4, but I could not figure out how. This is what I tried:

```
@export var test_variable : (Array, Resource)

```

It does not work. How could I accomplish this in Godot 4?

# Answer
> 1 votes
I have figured out the answer to this question. The answer is simple:

```
@export var test_variable : Array[Resource]

```

You can do this to create an Array of any node type. Just put the node type within the square brackets of the Array class and that's it!

---
Tags: godot, gdscript, godot-4, array
---


# Question
Title: How are character controllers built upon complex gameplay systems?
I would like some industry advice. I feel like the starting part to every game I create is the character controller. My goal is to create a solid base character controller that I can expand upon for any type of game that I create. That way I'm not recreating the same system over and over again and start focusing on what makes my game unique. I was wondering what system design principles are used to create character controllers that are modular and can easily interact with numerous gameplay features. Here are the features that I think pretty much 90% of character controllers need:

* process Input
* movement
* Animations
* Abilities/ways to interact with the world.
* Reaction/modifiers: how the game world affects the controller/player.
* Some way of dynamically adding and removing abilities and modifiers and allowing and disallowing the ability to use them.
* (optional) replicate and reconcile in a multiplayer context

The most common way I see to achieve this in tutorial land is with a finite state machine. The problem with that approach is as your character controller rises in complexity you come across these issues:

* State explosion
* difficulty to debug and test
* lack of ability to add dynamic behavior

My gut tells me that there is a better way than just state machines.

A new approach that I have seen is Unreal 5 Gameplay ability system (GAS) the problem I hear with that is that it is overly complex and limited to Unreal.

Are there any examples of greatly designed character controllers on the internet? Perhaps if you worked on your own character controller you could share some insight on how it was designed?

# Answer
> 5 votes
It sounds to me like you are trying to accomplish the impossible. There are limitations to how flexible and reusable you can make a system. Remember that ***a system with infinite flexibility will also be infinitely complex***. It's also incredibly difficult to anticipate and solve problems for potential future projects that haven't even reached the drawing board yet.

You should start by answering some basic questions:

**1. *What kind of games am I making?***

Obviously your character controller needs will be drastically different between a 2D platformer, first-person shooter, or third-person brawler. Are all of the games you create in the same genre, or do you change it up each time? Are there a standard set of features you use in every game that you develop?

**2. *How often do I create a new game?***

It can take years to develop a complex game. If you're only starting on a new game once every few years, the overhead of creating a new character controller for each game is probably less than the effort you'd spend trying to create a perfect all-in-one character controller.

If you're cranking out simple games on a constant basis, you might benefit from creating a starter template - an unfinished character controller with the infrastructure in place for you to quickly build what you need. **It's also perfectly acceptable to start with the completed character controller from a previous game and modify it to suit the needs of your new game**. Even AAA studios do this all the time.

If you're frequently starting on new games *because you never finish the games that you are developing* \- you're focused on the wrong problem here. Identify *why* you aren't finishing the games that you start and what you can do differently to help you see through your projects until the end.

**3. *Is this a problem that someone else has already solved?***

There are many commercial character controllers on the Unity Asset Store already, as well as various free open-source options on GitHub. Is there a package/library that already meets your needs? (Keep in mind this is not a place to get recommendations for specific packages).

---

Essentially, you should do a cost-benefit analysis. Is the cost (time spent developing your all-in-one system now) outweighed by the benefit (time that you'll save in the future)?

---
Tags: unity, architecture, character-controller
---


# Question
Title: Why does Unity have no official gameplay framework?
As a generalist developer, I have made many server and backend apps and also client-side UI apps. Most of these environments have a certain architecture. For example, in most backend apps, even in different languages, we have MVC that helps us structure the project in many different types of projects.

Probably you may say that frameworks make a developer limited. But they make developers much faster, as they don't need to think about architecture. They also reduce mistakes of the team as they prevent overlapping mistakes and reading the code as different projects have same standards.

I recently started using Unreal, and it seems that it follows the same rule. For example, it provides the gameplay framework. Classes like GameState, GameMode, and CharacterController are part of the gameplay framework that forces the developer to write code in the right place.

Why does unity have no such official framework? There are many plugins and tools that are written for Unity, and all of them provide different approaches.

Some examples: Zenject, VContainer, and... for dependency injection, **DI** helps with loosely coupled code, but many believe that it slows prototyping. So still **singleton** and **Service Locator**.

There are many different types of MVC and MVVM frameworks that work completely differently. Recent Unity NetCode official tutorials have used VContainer for DI, and they answered me it's because the system lacks a good framework.

# Answer
**1. There's no one-size fits all system.**

For example, you use MVC for your backend. Other teams might use MVP or MVVM or HMVC or MVA...

Unity attempts to be as flexible as possible. In some cases this means not including a built-in implementation of something because there's no one solution that will work for everyone. In other cases, when they *do* attempt to build a system that works for everyone, they end up with very complex packages that have a higher performance cost and are difficult to make changes to.

**2. Growing pains**

Unity started out as an indie engine targeting indie developers of various skill levels. They entered the market as a less expensive alternative to existing engines like Unreal and started with a much smaller feature set than what they have today.

As time has passed, bigger studios have been licensing the engine for bigger projects and with bigger expectations. The Unity team is now scrambling to add new features and overhaul legacy features that don't scale well or meet modern expectations. They've encountered a variety of issues from trying to grow too fast, such as feature fragmentation and systems that just don't work well together.

**3. Limited resources**

Hand-in-hand with the previous point - the Unity team only has so many staff members they can allocate to so many features. If you asked around in the Unity community, I think you'd get a general consensus that the Unity team is already trying to develop too many things at once. Many features already languish and die in the "Experimental" phase. Adding a general gameplay framework would mean one more thing that they have to allocate developers to, and one more thing they'd be getting complaints, feature requests, and bug reports about.

**4. Backwards compatibility**

These days, the Unity team tries very hard to maintain backwards compatibility with legacy projects. In my personal experience, migrating a project from Unity 4 to Unity 5, or Unity 5 to Unity 2017, is an absolute nightmare. However, upgrading from 2017 to any newer 20xx version is much easier.

Of course, this is a double-edged sword. Backwards compatibility allows games to be upgraded to newer versions of the engine so that they can be published on the latest platforms. However, it means that the Unity team is stuck supporting legacy features, and afraid to make major changes that would improve the engine but break backwards compatibility.

**5. The Asset Store**

The Asset Store is a core part of the Unity team's business model. Features that aren't built into the engine can be developed by third parties and sold on the Asset Store, where the Unity team gets a percentage of each sale. This gives the Unity team some incentive *not* to build certain features into the engine, because then the relevant asset packages would stop selling (and the creators of those packages might be very unhappy).

That said, they are gradually adding new things to the engine that used to only be available from third parties, and occasionally adopt a third-party asset as an official engine feature (e.g. TextMeshPro).
> 5 votes

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


# Question
Title: How time zone differences affect play time of early access N-day window?
I have seen a couple of game developers that grant early access for their video games N days before release date noting that "actual game time is subject to applicable time zone differences". An example of this is COD MW3 for which I saw the above mentioned note. I have also seen someone on another forum for Starfield(which also had early access for 5 days before global release) complaining how they will only have around 4 days of game time total due to them being from Australia, but that doesn't make sense to me. Can anyone explain why game developers add these notes?

# Answer
## Simple: legal stuff

They add these notes to be sure that they can't be sued in anyway. 5 days sonds simple but what exactly is "5 days". Does it mean if the game releases on say the 7th of febuary, the early access has to start on 2nd of febuary? Does it mean 5 full days from midnight to midnight, so if the game releases at 8pm the release day would be one of the "5 days" resulting in early access having to start on the 1st instead? Does it mean 5 x 24hours? You can never be sure how a court might rule that, so you include this sentence to make sure you don't get sued by someone claiming they haven't had the promised 5 days. And having one early access buyer getting a refund for this reason would lead to an avalanch of refunds leading to loss of all the extra income you wanted to generate with the early access pack.
> 1 votes

---
Tags: release
---


# Question
Title: Making contributions to a Unity project without having Unity editor installed
I'm interested in setting up a small Unity open source project so that non-Unity devs can contribute.

I would limit their involvement to making a small change to only one script, say adding a new entry to a dictionary or list that a method then loops through.

My question is: is this even possible? Theoretically, if someone cloned a Unity repo from GitHub, would they be able to make changes to a script in the project without having the Editor installed? I foresee there being issues when opening the script and having the Miscellaneous Files issue pop up in Visual Studio so contributors might have to work without proper Intellisense.

# Answer
> 3 votes
You said your data is strings. Since you haven't explained the nature of the data, I'll describe an example scenario: let's say you can talk to random NPCs in a town, and each time you talk to an NPC, they display a random line of dialog text. In this example, we want players to be able to add new lines of random dialog.

Rather than having non-Unity devs contribute by editing a *script*, you could put the data in a text file. Continuing with the example, let's say there's a Guard NPC with unique lines of dialog. We could simply create a file "GuardRandomDialog.txt" with one line of dialog on each line of the file:

**GuardRandomDialog.txt**

```
Man, my feet are getting sore.
Move along, there's nothing to see here.
I really wish someone would clean the barracks...
Please stay out of trouble.

```

With this setup, we can load the dialog with one line of code:

```
IEnumerable<string> guardRandomDialog = File.ReadLines("Dialog/GuardRandomDialog.txt");

```

We would then create a separate text file for each type of NPC with random dialog. Simple and easy to work with!

---

What if the data needs to be in key-value pair format? In this case, you can still use a text file, where the first word of each line is the key. For example, a simple localization file:

**GuardScriptedDialog.txt**

```
go-see-king "The king has requested your presence in the throne room."
find-blacksmith "You can find the blacksmith in the south part of town, just east of the fountain."
garden-no-entry "Only members of the royal household can enter the garden."

```

For this approach, you would need a few lines of additional code to parse the entries from the file into a dictionary. I don't have time to write up an example at the moment, but you can find plenty of examples online.

---
Tags: unity, c#, open-source
---


title: Stay Upright Within Rotating Area

text:
# Question
Title: Stay Upright Within Rotating Area
I am making a game that takes place in space and I want you to be able to stay upright in a spaceship even if it rotates. I have this set up:

Its a platform and an area that rotates. I have calculated a Vector based on the area's rotation that I use for the gravity and applied it to the cube and the player. It works somewhat but not well. When it rotates the cube slides off and hen the player is on it it doesn't go well. Basically I just take the rotation of the area and add it to the player and it works but not well. I need another way for approaching this.

My Player is a `CharacterBody3D` and the rotating ground is a `RigidBody3D`, but I am willing to change them.

# Answer
> 1 votes
## Direction of gravity

Since you might need `RigidBody3D` to change their direction of gravity… Have the `Area3D` override gravity (you can set its `gravity_space_override`, and set its `gravity_direction`). This direction is global, so you need to update it with the rotation of your `Area3D`:

*Code in the `Area3D`*

```
gravity_space_override = Area3D.SPACE_OVERRIDE_REPLACE
gravity_direction = global_transform.basis * Vector3.DOWN

```

---

Since you might need `CharacterBody3D` to follow the modified direction of gravity, have it read the gravity from the world space. For example:

*Code in the `CharacterBody3D`*

```
var direct_state := PhysicsServer3D.body_get_direct_state(get_rid())
var total_gravity := direct_state.total_gravity

```

However, you also need to tell the `CharacterBody3D` what is the new up which is used to identify what is a wall, a floor, or a ceiling:

```
up_direction = -total_gravity.normalized()

```

---

Then it gets tricky, because presumably you want the `CharacterBody3D` to rotate so it is standing up according to the new gravity direction.

I do not know how your code looks like, but you will have to review anywhere you have hardcoded `Vector3.UP`, and consider if it should be `up_direction` instead. For example, anywhere you are using `look_at`, you probably need to change it.

Character controllers often assume `Vector3.UP` is more implicit ways, for example mapping motion input to the horizonal axis, that code might need to be updated too.

---

## Moving inside the spaceship

Up to this point I have only talked about gravity. If the "spaceship" need to actually move it will bring more trouble.

First of all, having the `CharacterBody3D` is snapping to the floor will take care of situations of the floor moving away from it (at least at slow speeds).

The recommendation for a moving platform is an `AnimatableBody3D` and with `sync_to_physics` set to true. The `CharacterBody3D` when standing on the `AnimatableBody3D` moves with it.

**Thus: make the spaceship an `AnimatableBody3D`.**

But the `CharacterBody3D` won't change its orientation with whatever it is standing on. For that you need to detect the ground (e.g. use a `RayCast3D`), identify if it is the rotating platform, get how much it rotated last frame and rotate the `CharacterBody3D`.

I suggest you decompose the rotation in two parts:

* Rotation to align with the `up_direction` (make `global_transform.basis * Vector3.UP` go to `up_direction`). *Do this one first.*
* Rotation around the `up_direction` (the same way as the ground does).

*Be aware that the `CharacterBody3D` rotates around its own origin. If you want to have the origin in one place, but rotate around another ("center of mass") you need to handle do the translation that compensate for the difference after you rotated the `CharacterBody3D`.*

To do either of the mentioned rotations you want to get an axis and angle to have the `CharacterBody3D` rotate.

You might find it useful to use the `cross` product between vectors to use as axis. Be aware that `cross` product will be the zero vector if the inputs are either the same direction or opposite. You can use the `dot` product to discriminate which is the case.

It is also very useful to get an arbitrary perpendicular vector to another vector for these sort of things. This is what I'm currently using for that:

```
func get_perpendicular(direction:Vector3) -> Vector3:
    if direction.is_zero_approx():
        return Vector3.ZERO

    direction = direction.normalized()
    var vectors:= PackedVector3Array([Vector3.RIGHT, Vector3.UP, Vector3.BACK])
    for vec in vectors:
        var attempt = vec.slide(direction)
        if not attempt.is_equal_approx(Vector3.ZERO):
            return attempt.normalized()

    return Vector3.ONE.slide(direction).normalized()

```

This will return `Vector3.ZERO` if the `direction` given is zero. Otherwise it will try to get a perpendicular vector by taking the X, Y, Z axis vectors and substracting their projection on `direction`. Since there is no way the `direction` is perpendicular to all of them, one of them is bound to give you a valid perpendicular vector. *As a result the last line shouldn't run ever, but it is there so Godot does not complain that the method does not return, which is fine, since it does not handle pathological cases (i.e. `NAN` and `INF` coordinates), you should get an error trying to project on those.*

*You might also find this Q&A useful: How to compare a vector to a rotation in Godot 4.1?.*

---

## High speed

The above solution is bound to break a high speed. While you can try continuous collision detection on the `RigidBody3D`, the `CharacterBody3D` will always discrete collision detection.

Furthermore, at long distances you might run into floating point issues.

See Moving player inside of moving spaceship?.

*Thus DMGregory suggestion in comments is not unfounded.*

You can keep move everything so the "spaceship" is near the origin, by translating the root of the 3D world.

Yet, for rotating everything *except* your "spaceship", you want to set `top_level` on the "spaceship" so it is not affected by the transformation of the root of the 3D world (so you would also have to handle its offset translation). When you rotate the 3D world, since, presumably you want the rotation to happen around the "spaceship" you translate so the origin of the 3D world is on the "spaceship", rotate, and translate back.

---

And yes, it could also be done visually...

Doing it with materials is possible. But this is not as easy in Godot, since it imply making a transformation in the `vertex` shader *for everything* and *before* their regular material. So it can be quite an undertaking to set it up. At least, if you use Shader Global (you define them in project settings) you could control the transformation centrally.

Instead, I'd suggest to use a `SubViewport`s and `Camera3D`s trick: Have a `SubViewport` set to be rendered on top the regular world, and will have `own_world_3d` set to true. And inside of it you will have the "spaceship", and it will not move at all. To fake the motion, synchronize a `Camera3D` moving on the regular world with the local `Camera3D` of the "spaceship" scene plus the pretended motion of the "spaceship" itself.

Although this means that lights from the world won't affect the interior of the "spaceship", so you might want to replicate directional light and any other nearby lights that might affect it... And there will be edge cases (e.g. the light in the world would be inside the ship), but presumably you would have the "spaceship" fly at a safe distance from everything by design.

---
Tags: godot, gdscript, godot-4
---