# Question
Title: How do I fix this Minecraft type game bug?
I'm making a building game similar to minecraft, except you can place other types of objects as well. I am right now building the functionality of placing cubes. I'm using unity. here's my code.

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

public class Player : MonoBehaviour
{
    Camera cam;
    [SerializeField] GameObject brick;
    float pointX;
    float pointY;
    float pointZ;

// Start is called before the first frame update
void Start()
{
    cam = FindObjectOfType<Camera>();
}

// Update is called once per frame
void Update()
{
    Ray ray = cam.ScreenPointToRay(Input.mousePosition);
    RaycastHit hitInfo;

    if(Physics.Raycast(ray, out hitInfo))
    {
        if(Input.GetMouseButtonDown(0))
        {
            pointX = hitInfo.point.x;
            int roundedX = Mathf.RoundToInt(pointX);
            pointY = hitInfo.point.y;
            int roundedY = Mathf.RoundToInt(pointY);
            pointZ = hitInfo.point.z;
            int roundedZ = Mathf.RoundToInt(pointZ);
            Vector3 clickedPlace = new Vector3(roundedX, roundedY, roundedZ);

            Instantiate(brick, clickedPlace, transform.rotation);
        }

    }
}
}

```

the brick variable is assigned to a prefab which s 1 unit by 1 unit. this code works when placing the brick on the ground or on top of another block, but it only has a 50% chance of working when clicking on one side of the brick like you can do on minecraft. Sometimes the block will be placed right on top of another block, and sometimes it will be placed above the block and in front of it. does anyone know a way to fix this? I tried making the collider on the block bigger, but it didn't work.

# Answer
> 4 votes
Just rounding the coordinates alone won't work.

You need to figure out which block the ray collided with (the coordinates), and then which face of the block, the ray intersected.

From there, you can get the surface normal of that block face. Using that normal vector, you can then compute the next integer coordinate of where the block should be placed.

For example, if you are looking at the top of a block (assuming Y axis is "up"), the surface normal should be (0,1,0). If your blocks are all unit size of 1, then you can just add that surface normal to the position of the intersected block to get the placement coordinate:

```
if(Physics.Raycast(ray, out hitInfo))
{
    if(Input.GetMouseButtonDown(0))
    {
        pointX = hitInfo.point.x;
        int roundedX = Mathf.RoundToInt(pointX);
        pointY = hitInfo.point.y;
        int roundedY = Mathf.RoundToInt(pointY);
        pointZ = hitInfo.point.z;
        int roundedZ = Mathf.RoundToInt(pointZ);
        // The rounding may cause some issues: You will likely
        // need some logic to compute the coordinates of the *nearest* block
        Vector3 clickedBlock = new Vector3(roundedX, roundedY, roundedZ);
        Vector3 newBlock = clickedBlock + hitInfo.normal;

        Instantiate(brick, newBlock, transform.rotation);
    }
}

```

---
Tags: unity, c#, content-generation
---


# Question
Title: Game server simulation loop updates to fast even if the fixed steps are implemented
Today I wanted to ask you about the server world simulation loop that I have implemented and it acts weird.

I am using Java, LibGDX and KryoNet to create 2d rpg co-op game based on server-clients architecture where server should update clients with game state 20 times per second. Unfortunetly even if I use fixed step on below while(running) loop the game state is sent almost each ms and i honestly cannot see why.

Server simulation loop:

```
public void gameServerLoop(){

        new Thread(() -> {
            double simulationTicks = 1000000000.0 / 60.0;
            double gatherDataTicks = 1000000000.0 / 20.0;
            double simulationDelta = 0;
            double gatherDataDelta = 0;

            long lastTime = System.nanoTime();
            long lastTimeDataGathered = System.nanoTime();
            boolean running = true;

            while (running){
                long now = System.nanoTime();
                simulationDelta += (now - lastTime) / simulationTicks;
                gatherDataDelta += (now - lastTimeDataGathered) / gatherDataTicks;
                Gdx.app.log("GatheredData Delta", LocalDateTime.now() + " : " + String.valueOf(gatherDataDelta));
                while (simulationDelta >= 1){
                    update();
                    simulationDelta--;
                    lastTime = now;
                }
                while (gatherDataDelta >= 1){
                    Gdx.app.log(String.valueOf(LocalDateTime.now()), "updaing...");
                    gatherDataDelta--;
                    gatherPlayerDataAndSend();
                    gameStateId++;
                    Gdx.app.log("Server ", "Game State id: " + gameStateId);
                    lastTimeDataGathered = now;
                }
            }
        }).start();
    }

```

logged time until game state updated

```
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0035180000000135858
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.004894000000013585
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.006374000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.007930000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.009562000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.011266000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.013046000000013587
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.014900000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.016828000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.018832000000013584
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.020908000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.023056000000013586
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.025278000000013588
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.02757600000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.03030400000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.03326200000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.03638400000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.03964400000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.043040000000013595
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.046592000000013595
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0503000000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0541440000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.058118000000013596
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.062238000000013595
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.06650000000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.07089400000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.07543800000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0801180000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0849320000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.08988200000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.0949660000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.1001880000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.1055660000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.11110000000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.11679000000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.12261400000001359
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.1285760000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.1346680000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.14089600000001362
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.14725800000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.15375800000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.16039000000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.16716800000001364
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.17407800000001364
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.18112600000001364
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.18830400000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.19563800000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.20309600000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.21068800000001361
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.21840800000001362
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.22625800000001361
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.23425200000001362
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.2423800000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.25064200000001363
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.2590640000000136
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.26763800000001364
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.27635600000001365
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.2852080000000137
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.2942140000000137
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.30335400000001367
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.31262000000001366
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.3220220000000137
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.3315700000000137
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.34125600000001366
[GatheredData Delta] 2019-09-16T08:31:30.880 : 0.35108400000001366
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.3611020000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.3712600000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.38155800000001366
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.3920100000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.40260200000001367
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4133360000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4242100000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4352420000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4464180000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4577300000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4691840000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4807800000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.4925300000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5044640000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5165500000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5287840000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5412060000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5538840000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5667540000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5798100000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.5930340000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6064300000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6200580000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6339320000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6480500000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6623740000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6769040000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.6916760000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7066700000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7218920000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7373600000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7530160000000137
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7688480000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.7848340000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8009800000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8172820000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8337180000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8503120000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8670500000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.8839320000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9009560000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9181240000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9354260000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9528620000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9704600000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 0.9881960000000136
[GatheredData Delta] 2019-09-16T08:31:30.881 : 1.0060820000000137
[2019-09-16T08:31:30.881] updaing...
[Server ] Game State id: 4298

```

Basicly there are 3 loops in total. the base one which runs as fast as processor allows (while(running)), 2nd which is a world simulation 60 times per second, and a third one which is a game state update that should run 20 times per second. Unfortunetly I end up with a game state being updated each ms. It just looks like time passed is calculated faster (?). I can't find a root cause of this.

I will appreciate any suggestions and help.

# Answer
You're updating your lastTime / lastTimeDataGathered values inside your fixed update loops, rather than every time you accumulate a time interval.

That means the interval you add to your simulationDelta and gatherDataDelta accumulators keeps growing with every cycle.

So the first loop after a simulation update, you add one outer loop's worth of time to the accumulator.

On the second loop after a simulation update, you add two outer loops' worth of time to the accumulator, for a total of three.

On the third loop after a simulation update, you add three loops' worth, for a total of six.

Your accumulator values end up growing as a triangular number, quadratically in actual wall time.

So, to fix this, make sure the increment you add to each accumulator in the outer loop is only the time passed since the last outer loop.

You may also want to add a sleep in here somewhere, otherwise your server will keep the thread continually busy, burning most of its time adding tiny fractions nowhere near your thresholds, instead of doing useful work for you.
> 0 votes

---
Tags: networking, game-loop
---


# Question
Title: Testing Multiplayer Browser Game on Single Computer
I am writing a multiplay browser based game and am running into an issue with playtesting simple interactions. When a browser window loses focus is stops running requestAnimationFrame calls. This effectively pauses the state all visuals when focus is lost.

I would like to have two instances of the game running at the same time. I could playtest in one window and observe how a thirdparty would see those actions in another window.

Right now I am only able to toggle between the two windows and see teleportation like behavior as the client state catches up to the new server state.

I am not sure how, without setting up a second computer, I might test this. Anyone have any experience with this or any advice?

# Answer
> 2 votes
By default, `requestAnimationFrame` does not pause when switching window focus. Your game engine is probably adding this behavior for you. Check the documentation for your game engine, you can probably just turn this behavior off.

As proof, try opening two browser windows, both visible, and run a simple rAF based animation in both. You’ll see both animations update.

# Answer
> 2 votes
As schteppe point out, `requestAnimationFrame` does not stop when a window loses focus. Thus, try having you may also have to keep the browser windows visible on screen. For example you can split the screen to have two browser windows visible at the same time.

Another thing that worked for me is sending the browser window to another desktop. *By the way, the visibility API is unaware of the current desktop.*

---

Note that the game engine can still detect a loss of focus (Focus/Blur demo), and it can overwrie `window.requestAnimationFrame`.

I do not know if the game engine you are using add focus/blur events, much less if it is viable to remove them.

---

I also played with chromium flags (`about:flags`), `Stop non-timer task queues background` in particular seemed promising. Also tested `Throttle expensive background timers`. However, when a window is minimized or the page is not on the current tab, `requestAnimationFrame` does not trigger regardless of these flags.

# Answer
> 0 votes
As per the comment posted by Theraot above: VirtualBox is a solution that allows you to playtest on one screen and see the results in another browser like a third party would.

VirtualBox will maintain browser focus even when the virtual machine is not in focus.

I was able to use VirtualBox with an Ubuntu image and installed Chrome to test. It took me a few hours to get the VirtualBox environment setup.

I do not think this is an optimal solution, but it works.

---
Tags: multiplayer, browser-based-games, testing, playtesting, browser
---


title: Shore fading in a water shader

text:
# Question
Title: Shore fading in a water shader
I am modifying an old water shader for the game "MTA San Andreas" (the multiplayer modification). MTA uses HLSL and comes with some builtin predefined variables and functions. The water shader itself is already modified by me, but now I want to add shore fading to it. Objects slightly below water surface should be visible, but objects deeper in the water should be completely invisible and that effect should be configurable. I found a water shader that has shore fading included, but it was covered within very complex other things in a very large file. I managed to extract most of the necessary information (i think) but I get an error message in the game: `Invalid PS 3_0 input semantic "POSITION" in water.fx 139,23` I know that this line 138 has no errors and the only reason why the game throws this error is actually line 268... Debugging HLSL is a pain, horrible language. And there may be much more wrong stuff. This is the water shader:

```
#include "mta-helper.fx"

float Time : Time;
texture skyBoxTexture1;
texture skyBoxTexture2;
float3 skyRotate = float3(0, 0, 0);
float fadeValue = 0;
float4 WaterParameters1 = float4(1,1,1,1);
texture causticTexture;
texture reflectionTexture;
texture refractionTexture;
texture normalTexture;
texture gDepthBuffer : DEPTHBUFFER;

float flowSpeed = 0.0;
float reflectScale = 0.0;
float refractScale = 0.0;
float reflectionStrength = 0.0;
float refractionStrength = 0.0;
float causticStrength = 0.0;
float4 waterColor = float4(0.0, 0.0, 0.0, 0.0);
float waterAlpha = 0.0;
float brightness = 1.0;
float dayTime = 1.0;
float3 sunPos = float3(0, 0, 0);
float4 sunColor = float4(0.0, 0.0, 0.0, 0.0);
float specularSize = 4;
float waterShiningPower = 1;
float fogStart = 50;
float fogEnd = 550;

///////////////////
// SAMPLE STATES //
///////////////////

sampler CausticSampler = sampler_state
{
    Texture = <causticTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler ReflectionSampler = sampler_state
{
    Texture = <reflectionTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Mirror;
    AddressV = Mirror;
};

sampler RefractionSampler = sampler_state
{
    Texture = <refractionTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Mirror;
    AddressV = Mirror;
};

sampler NormalSampler = sampler_state
{
    Texture = <normalTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler SamplerDepth = sampler_state
{
    Texture = (gDepthBuffer);
    MinFilter = Point;
    MagFilter = Point;
    MipFilter = None;
    AddressU = Clamp;
    AddressV = Clamp;
};

samplerCUBE SkyCubeSampler1 = sampler_state
{
    Texture = <skyBoxTexture1>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

samplerCUBE SkyCubeSampler2 = sampler_state
{
    Texture = <skyBoxTexture2>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

float3x3 eulRotate(float3 Rotate)
{
    float cosX,sinX;
    float cosY,sinY;
    float cosZ,sinZ;

    sincos(Rotate.x,sinX,cosX);
    sincos(-Rotate.y,sinY,cosY);
    sincos(Rotate.z,sinZ,cosZ);

//Euler extrinsic rotations
//http://www.vectoralgebra.info/eulermatrix.html

        float3x3 rot = float3x3(
        cosY * cosZ + sinX * sinY * sinZ, -cosX * sinZ,  sinX * cosY * sinZ - sinY * cosZ,
        cosY * sinZ - sinX * sinY * cosZ,  cosX * cosZ, -sinY * sinZ - sinX * cosY * cosZ,
        cosX * sinY,                       sinX,         cosX * cosY
    );

return rot;
}

struct VertexInputType
{
    float3 position : POSITION;
    float3 normal : NORMAL0;
    float2 textureCoords : TEXCOORD0;
};

struct PixelInputType
{
    float4 position : POSITION;
    float2 textureCoords : TEXCOORD0;
    float4 reflectionPosition : TEXCOORD1;
    float4 refractionPosition : TEXCOORD2;
    float3 skyTextureCoordinate : TEXCOORD3;
    float Depth : TEXCOORD4;
    float3 worldPosition : TEXCOORD5;
    float3 lightDirection : TEXCOORD6;
    float3 worldNormal : TEXCOORD7;

};

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType WaterVertexShader(VertexInputType input)
{
    PixelInputType output;
    matrix reflectProjection;
    matrix refractProjection;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = MTACalcScreenPosition(input.position);
    output.worldPosition = MTACalcWorldPosition(input.position);
    output.lightDirection = normalize(gCameraPosition - sunPos);
    output.worldNormal = MTACalcWorldNormal(input.normal);

    // Store the texture coordinates for the pixel shader.
    output.textureCoords = input.textureCoords;

    // Create the view projection world matrix for reflection.
    reflectProjection = mul(gWorldViewProjection, gWorld);
    reflectProjection = mul(gWorld, reflectProjection);

    // Calculate the input position against the refractProjection matrix.
    output.reflectionPosition = mul(float4(input.position, 1), reflectProjection);

    // Create the view projection world matrix for refraction.
    refractProjection = mul(gWorldViewProjection, gWorld);
    refractProjection = mul(gWorld, refractProjection);

    // Calculate the input position against the refractProjection matrix.
    output.refractionPosition = mul(float4(input.position, 1), refractProjection);

    float4 vertexPosition = mul(float4(input.position, 1), gWorld);

    // compute the eye vector
    float4 eyeVector = vertexPosition - gViewInverse[3];
    output.skyTextureCoordinate = mul(eulRotate(skyRotate), eyeVector.xyz);

    output.Depth = output.position.z;

    return output;
}

////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 WaterPixelShader(PixelInputType input) : COLOR0
{
    float2 refractTexCoord;
    float2 reflectTexCoord;
    float3 skyBoxReflectTexCoord;
    float3 skyBoxTexCoord;
    float4 normalMap;
    float3 normal;
    float4 reflectionColor;
    float4 refractionColor;
    float4 causticColor;
    float4 skyColor;
    float4 color;
    float timer = (Time/12) * flowSpeed;

    // Move the position the water normal is sampled from to simulate moving water.

    // Calculate the projected refraction texture coordinates.
    reflectTexCoord.x = input.reflectionPosition.x / input.reflectionPosition.w / 2.0f + 0.5f;
    reflectTexCoord.y = -input.reflectionPosition.y / input.reflectionPosition.w / 2.0f + 0.5f;
    refractTexCoord.x = input.refractionPosition.x / input.refractionPosition.w / 2.0f + 0.5f;
    refractTexCoord.y = -input.refractionPosition.y / input.refractionPosition.w / 2.0f + 0.5f;
    skyBoxReflectTexCoord.x = -input.skyTextureCoordinate.x / 1 / 2.0f + 0.5f;
    skyBoxReflectTexCoord.y = -input.skyTextureCoordinate.y / 1 / 2.0f + 0.5f;
    skyBoxReflectTexCoord.z = input.skyTextureCoordinate.z / 1 / 2.0f + 0.5f;
    // Sample the normal from the normal map texture.
    float2 NormalTex = input.textureCoords;
    NormalTex.y = NormalTex.y + timer;
    normalMap = tex2D(NormalSampler, NormalTex);

    // Expand the range of the normal from (0,1) to (-1,+1).
    normal = (normalMap.xyz * 2.0f) - 1.0f;

    // Re-position the texture coordinate sampling position by the normal map value to simulate the rippling wave effect.
    reflectTexCoord = reflectTexCoord + (normal.xy * reflectScale);
    refractTexCoord = refractTexCoord + (normal.xy * refractScale);
    skyBoxReflectTexCoord = skyBoxReflectTexCoord + (normal * reflectScale);
    // Sample the texture pixels from the textures using the updated texture coordinates.
    float2 CausticTex = input.textureCoords;
    CausticTex.y = CausticTex.y  + (sin(CausticTex.y * 10) * 0.01) + timer;
    causticColor = tex2D(CausticSampler, CausticTex);

    float4 skyColor1 = texCUBE(SkyCubeSampler1, 1 - skyBoxReflectTexCoord.yzx);
    float4 skyColor2 = texCUBE(SkyCubeSampler2, 1 - skyBoxReflectTexCoord.yzx);
    float4 finalSkyColor = (skyColor2 * fadeValue) + (skyColor1 * (1 - fadeValue));

    reflectionColor = tex2D(ReflectionSampler, reflectTexCoord) * reflectionStrength;
    refractionColor = tex2D(RefractionSampler, refractTexCoord) * refractionStrength;

    // Using Blinn half angle modification for performance over correctness
    float3 lightRange = normalize(normalize(gCameraPosition - input.worldPosition) - input.lightDirection);
    float specularLight = pow(saturate(dot(lightRange, normal)), specularSize * 2);
    float4 specularColor = float4(sunColor.rgb * specularLight, 1);
    specularColor += pow(saturate(dot(lightRange, input.worldNormal)), specularSize / 2) / 2;
    specularColor *= normalMap.g * normalMap.g;

    // Combine the reflection and refraction results for the final color.
    color = lerp(reflectionColor * reflectionStrength, refractionColor * refractionStrength, 2.0f);
    color *= causticColor * causticStrength;
    color += finalSkyColor * waterColor * reflectionStrength;

    float distanceFog = saturate((input.Depth - fogStart)/(fogEnd - fogStart));
    float4 finalColor = lerp(float4(color.rgb, 1), float4(reflectionColor.rgb/2, 1), distanceFog);
    finalColor.rgb += specularColor.rgb * normalMap * waterShiningPower * 0.7;
    finalColor.rgb *= brightness;
    finalColor.a *= waterAlpha;
    finalColor = float4(MTAApplyFog(finalColor.rgb, input.worldPosition), finalColor.a);
    float diffGray = saturate( 0.1 + (( finalColor.r +finalColor.g+finalColor.b )/3 ) * dayTime);
    finalColor = lerp( float4( diffGray, diffGray, diffGray, finalColor.a ), finalColor, saturate( dayTime ));

    float objdepth = input.position.z/input.position.w;
    float nonlinearobjdepth = objdepth;
    objdepth = 1.0/max(1.0-objdepth, 0.000000001);
    float planardepth = tex2D(SamplerDepth, input.textureCoords.xy).r;
    float depth = tex2D(SamplerDepth, input.textureCoords.xy).r;
    if (nonlinearobjdepth>depth)
    {
        depth = planardepth;
    }

    float scenedepth = depth;
          planardepth = 1.0/max(1.0-planardepth,0.000000001);
          depth = 1.0/max(1.0-depth,0.000000001);
    float depthfact = (depth-objdepth)*WaterParameters1.z;
          depthfact = depthfact*WaterParameters1.x;
          depthfact = depthfact/(depthfact*0.50+1.0);
    if (scenedepth>0.99999) depthfact = 1.0;
    float backside = saturate(WaterParameters1.w*10.0);
          depthfact*= 1.0-backside;
    float shorefade = (planardepth-objdepth);
          shorefade = shorefade*WaterParameters1.x;
          shorefade = saturate(13.40*shorefade*1000.0 - 0.05);
          depthfact*= shorefade;
    finalColor.a *= shorefade;

    return finalColor;
}

////////////////////////////////////////////////////////////////////////////////
// Technique
////////////////////////////////////////////////////////////////////////////////
technique WaterTechnique
{
    pass pass0
    {
        ZEnable = true;
        ZWriteEnable = true;
        ZFunc = 4;
        DepthBias = 0.000001;
        SlopeScaleDepthBias = 2;
        VertexShader = compile vs_3_0 WaterVertexShader();
        PixelShader = compile ps_3_0 WaterPixelShader();
    }
}

// Fallback
technique fallback
{
    pass P0
    {
        // Just draw normally
    }
}

```

I started my modifications in line 268, where `objdepth` seems to be "wrong" and causes the compile error:

```
float objdepth = input.position.z/input.position.w;
float nonlinearobjdepth = objdepth;
objdepth = 1.0/max(1.0-objdepth, 0.000000001);
float planardepth = tex2D(SamplerDepth, input.textureCoords.xy).r;
float depth = tex2D(SamplerDepth, input.textureCoords.xy).r;
if (nonlinearobjdepth>depth)
{
    depth = planardepth;
}

float scenedepth = depth;
      planardepth = 1.0/max(1.0-planardepth,0.000000001);
      depth = 1.0/max(1.0-depth,0.000000001);
float depthfact = (depth-objdepth)*WaterParameters1.z;
      depthfact = depthfact*WaterParameters1.x;
      depthfact = depthfact/(depthfact*0.50+1.0);
if (scenedepth>0.99999) depthfact = 1.0;
float backside = saturate(WaterParameters1.w*10.0);
      depthfact*= 1.0-backside;
float shorefade = (planardepth-objdepth);
      shorefade = shorefade*WaterParameters1.x;
      shorefade = saturate(13.40*shorefade*1000.0 - 0.05);
      depthfact*= shorefade;
finalColor.a *= shorefade;

return finalColor;

```

# Answer
> 1 votes
The best would be working with linear depths for this effect. You will need two depths.

1. Depth of water mesh you are rendering. input.position.w should be the linear depth value of the water mesh.
2. Depth of the underlying geometry that was rendered beforehand. You will read it as a texture from screen coordinates. If you have a native depth buffer available for that render pass, you will need to convert that to linear depth. The reason is that you will want the "water depth fog" to look like linearly increasing.

This is a function to convert native depth buffer value to linear depth:

```
inline float getLinearDepth(in float z, in float near, in float far)
{
    float z_n = 2.0 * z - 1.0;
    float lin = 2.0 * far * near / (near + far - z_n * (near - far));
    return lin;
}

```

You will want to calculate the difference of these two depths and make the water more transparent when the difference is small. For example fading out a blue water color could be this:

```
float water_depth = input.position.w; // linear depth spanning from near plane to far plane
float scene_depth = tex2D(SamplerDepth, input.textureCoords.xy).r;
scene_depth = getLinearDepth(scene_depth, my_nearplane, my_farplane); // if your texture contains native depth buffer, use this to convert to linear
float fade_strength= 0.1; // how strong the fade effect is
float depth_difference = saturate(abs(water_depth - scene_depth) * fade_strength);
float4 watercolor = float4(0,0,1,depth_difference); // transparency fade

```

I suggest to simplify your code, and output different pieces to debug, like output linear depths, depth difference and see how they look like on screen if something doesn't look right from the start. Good luck!

# Answer
> 0 votes
I have found a possible solution, but its not "final" and i will try János solution next. The problem is that my solution produces strange artifacts that may be related to GTA San Andreas rendering problems. This is the full shader as it is "working" now with its issues:

```
//-- Include some common stuff
#include "mta-helper.fx"

float Time : Time;
texture skyBoxTexture1;
texture skyBoxTexture2;
float3 skyRotate = float3(0, 0, 0);
float fadeValue = 0;
float4 deepness = 0.5; //this value must be adjusted depending on flight height / wearing jetpack (??)
float4 ScreenSize = float4(0,0,0,0);
texture causticTexture;
texture reflectionTexture;
texture refractionTexture;
texture normalTexture;
texture gDepthBuffer : DEPTHBUFFER;

float flowSpeed = 0.0;
float reflectScale = 0.0;
float refractScale = 0.0;
float reflectionStrength = 0.0;
float refractionStrength = 0.0;
float causticStrength = 0.0;
float4 waterColor = float4(0.0, 0.0, 0.0, 0.0);
float brightness = 1.0;
float dayTime = 1.0;
float3 sunPos = float3(0, 0, 0);
float4 sunColor = float4(0.0, 0.0, 0.0, 0.0);
float specularSize = 4;
float waterShiningPower = 1;
float fogStart = 50;
float fogEnd = 550;

///////////////////
// SAMPLE STATES //
///////////////////

sampler CausticSampler = sampler_state
{
    Texture = <causticTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler ReflectionSampler = sampler_state
{
    Texture = <reflectionTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Mirror;
    AddressV = Mirror;
};

sampler RefractionSampler = sampler_state
{
    Texture = <refractionTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Mirror;
    AddressV = Mirror;
};

sampler NormalSampler = sampler_state
{
    Texture = <normalTexture>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

sampler SamplerDepth = sampler_state
{
    Texture = (gDepthBuffer);
    MinFilter = Point;
    MagFilter = Point;
    MipFilter = None;
    AddressU = Clamp;
    AddressV = Clamp;
};

samplerCUBE SkyCubeSampler1 = sampler_state
{
    Texture = <skyBoxTexture1>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

samplerCUBE SkyCubeSampler2 = sampler_state
{
    Texture = <skyBoxTexture2>;
    MinFilter = Linear;
    MagFilter = Linear;
    MipFilter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

float3x3 eulRotate(float3 Rotate)
{
    float cosX,sinX;
    float cosY,sinY;
    float cosZ,sinZ;

    sincos(Rotate.x,sinX,cosX);
    sincos(-Rotate.y,sinY,cosY);
    sincos(Rotate.z,sinZ,cosZ);

//Euler extrinsic rotations
//http://www.vectoralgebra.info/eulermatrix.html

        float3x3 rot = float3x3(
        cosY * cosZ + sinX * sinY * sinZ, -cosX * sinZ,  sinX * cosY * sinZ - sinY * cosZ,
        cosY * sinZ - sinX * sinY * cosZ,  cosX * cosZ, -sinY * sinZ - sinX * cosY * cosZ,
        cosX * sinY,                       sinX,         cosX * cosY
    );

return rot;
}

struct VertexInputType
{
    float3 position : POSITION;
    float3 normal : NORMAL0;
    float2 textureCoords : TEXCOORD0;
};

struct PixelInputType
{
    float4 position : POSITION;
    float2 textureCoords : TEXCOORD0;
    float4 reflectionPosition : TEXCOORD1;
    float4 refractionPosition : TEXCOORD2;
    float3 skyTextureCoordinate : TEXCOORD3;
    float Depth : TEXCOORD4;
    float3 worldPosition : TEXCOORD5;
    float3 lightDirection : TEXCOORD6;
    float3 worldNormal : TEXCOORD7;
    float4 vposition : TEXCOORD8;

};

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType WaterVertexShader(VertexInputType input)
{
    PixelInputType output;
    matrix reflectProjection;
    matrix refractProjection;

    // Calculate the position of the vertex against the world, view, and projection matrices.
    output.position = MTACalcScreenPosition(input.position);
    output.worldPosition = MTACalcWorldPosition(input.position);
    output.lightDirection = normalize(gCameraPosition - sunPos);
    output.worldNormal = MTACalcWorldNormal(input.normal);

    // Store the texture coordinates for the pixel shader.
    output.textureCoords = input.textureCoords;

    // Create the view projection world matrix for reflection.
    reflectProjection = mul(gWorldViewProjection, gWorld);
    reflectProjection = mul(gWorld, reflectProjection);

    // Calculate the input position against the refractProjection matrix.
    output.reflectionPosition = mul(float4(input.position, 1), reflectProjection);

    // Create the view projection world matrix for refraction.
    refractProjection = mul(gWorldViewProjection, gWorld);
    refractProjection = mul(gWorld, refractProjection);

    // Calculate the input position against the refractProjection matrix.
    output.refractionPosition = mul(float4(input.position, 1), refractProjection);

    float4 vertexPosition = mul(float4(input.position, 1), gWorld);

    // compute the eye vector
    float4 eyeVector = vertexPosition - gViewInverse[3];
    output.skyTextureCoordinate = mul(eulRotate(skyRotate), eyeVector.xyz);

    output.Depth = output.position.z;
    float4 pos = float4(input.position.x,input.position.y,input.position.z,1.0);
    float4 tpos = mul(pos, gWorldViewProjection);
    output.vposition = tpos;
    return output;
}

////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 WaterPixelShader(PixelInputType input) : COLOR0
{
    float2 refractTexCoord;
    float2 reflectTexCoord;
    float3 skyBoxReflectTexCoord;
    float3 skyBoxTexCoord;
    float4 normalMap;
    float3 normal;
    float4 reflectionColor;
    float4 refractionColor;
    float4 causticColor;
    float4 skyColor;
    float4 color;
    float timer = (Time/12) * flowSpeed;

    // Move the position the water normal is sampled from to simulate moving water.

    // Calculate the projected refraction texture coordinates.
    reflectTexCoord.x = input.reflectionPosition.x / input.reflectionPosition.w / 2.0f + 0.5f;
    reflectTexCoord.y = -input.reflectionPosition.y / input.reflectionPosition.w / 2.0f + 0.5f;
    refractTexCoord.x = input.refractionPosition.x / input.refractionPosition.w / 2.0f + 0.5f;
    refractTexCoord.y = -input.refractionPosition.y / input.refractionPosition.w / 2.0f + 0.5f;
    skyBoxReflectTexCoord.x = -input.skyTextureCoordinate.x / 1 / 2.0f + 0.5f;
    skyBoxReflectTexCoord.y = -input.skyTextureCoordinate.y / 1 / 2.0f + 0.5f;
    skyBoxReflectTexCoord.z = input.skyTextureCoordinate.z / 1 / 2.0f + 0.5f;
    // Sample the normal from the normal map texture.
    float2 NormalTex = input.textureCoords;
    NormalTex.y = NormalTex.y + timer;
    normalMap = tex2D(NormalSampler, NormalTex);

    // Expand the range of the normal from (0,1) to (-1,+1).
    normal = (normalMap.xyz * 2.0f) - 1.0f;

    // Re-position the texture coordinate sampling position by the normal map value to simulate the rippling wave effect.
    reflectTexCoord = reflectTexCoord + (normal.xy * reflectScale);
    refractTexCoord = refractTexCoord + (normal.xy * refractScale);
    skyBoxReflectTexCoord = skyBoxReflectTexCoord + (normal * reflectScale);
    // Sample the texture pixels from the textures using the updated texture coordinates.
    float2 CausticTex = input.textureCoords;
    CausticTex.y = CausticTex.y  + (sin(CausticTex.y * 10) * 0.01) + timer;
    causticColor = tex2D(CausticSampler, CausticTex);

    float4 skyColor1 = texCUBE(SkyCubeSampler1, 1 - skyBoxReflectTexCoord.yzx);
    float4 skyColor2 = texCUBE(SkyCubeSampler2, 1 - skyBoxReflectTexCoord.yzx);
    float4 finalSkyColor = (skyColor2 * fadeValue) + (skyColor1 * (1 - fadeValue));

    reflectionColor = tex2D(ReflectionSampler, reflectTexCoord) * reflectionStrength;
    refractionColor = tex2D(RefractionSampler, refractTexCoord) * refractionStrength;

    // Using Blinn half angle modification for performance over correctness
    float3 lightRange = normalize(normalize(gCameraPosition - input.worldPosition) - input.lightDirection);
    float specularLight = pow(saturate(dot(lightRange, normal)), specularSize * 2);
    float4 specularColor = float4(sunColor.rgb * specularLight, 1);
    specularColor += pow(saturate(dot(lightRange, input.worldNormal)), specularSize / 2) / 2;
    specularColor *= normalMap.g * normalMap.g;

    // Combine the reflection and refraction results for the final color.
    color = lerp(reflectionColor * reflectionStrength, refractionColor * refractionStrength, 2.0f);
    color *= causticColor * causticStrength;
    color += finalSkyColor * waterColor * reflectionStrength;

    float distanceFog = saturate((input.Depth - fogStart)/(fogEnd - fogStart));
    float4 finalColor = lerp(float4(color.rgb, 1), float4(reflectionColor.rgb/2, 1), distanceFog);
    finalColor.rgb += specularColor.rgb * normalMap * waterShiningPower * 0.7;
    finalColor.rgb *= brightness;
    finalColor.a *= waterColor.a;
    finalColor = float4(MTAApplyFog(finalColor.rgb, input.worldPosition), finalColor.a);
    float diffGray = saturate( 0.1 + (( finalColor.r +finalColor.g+finalColor.b )/3 ) * dayTime);
    finalColor = lerp( float4( diffGray, diffGray, diffGray, finalColor.a ), finalColor, saturate( dayTime ));

    float2 txcoord;
    txcoord.xy = (input.vposition.xy / input.vposition.w) * float2(0.5, -0.5) + 0.5;
    txcoord.xy += 0.5 * float2(ScreenSize.y, ScreenSize.y*ScreenSize.z);

    float objdepth = input.vposition.z / input.vposition.w;
    objdepth = 1.0/max(1.0-objdepth, 0.000000001);
    float planardepth = tex2D(SamplerDepth, txcoord.xy).r;
    planardepth = 1.0/max(1.0-planardepth,0.000000001);

    float shorefade = planardepth-objdepth;
    shorefade = saturate(shorefade*deepness);
    finalColor.a *= shorefade;

    return finalColor;
}

////////////////////////////////////////////////////////////////////////////////
// Technique
////////////////////////////////////////////////////////////////////////////////
technique WaterTechnique
{
    pass pass0
    {
        ZEnable = true;
        ZWriteEnable = true;
        ZFunc = 2;
        DepthBias = 0.000001;
        SlopeScaleDepthBias = 2;
        VertexShader = compile vs_3_0 WaterVertexShader();
        PixelShader = compile ps_3_0 WaterPixelShader();
    }
}

// Fallback
technique fallback
{
    pass P0
    {
        // Just draw normally
    }
}

```

---
Tags: shaders, hlsl
---


# Question
Title: How do I get an object to rotate in world space via RigidBody.AddTorque?
I'm getting really discouraged because I can't seem to figure how how to rotate my object via Rigidbody.AddTorque like it is on a figurative global turn table rather than a local turn table. Another way of describing it is that I want to c calculate a torque vector that will rotate the object's yaw and keep it upright regardless of its pitch without rolling it around. This is a problem for me because I want my player to remain upright without ending upside down because they were pitched and decided to turn.

Someone else had posted about the same problem on a different forum but he didn't receive much in the line of help, however he did provide this really helpful image describing the problem:

Notice how the left object is tilted and then rotating with respect to its own local coordinates but the one on the right is rotating with respect to the global coordinates instead of rolling around like the one on the left.

How can I achieve this? Is there something obvious I am overlooking or forgetting? Am I explaining it right?

EDIT:

In the following image the top half illustrates what I want while the bottom half is showing what is actually happening. What I want is to be able to tilt the player's pitch and have them be able to rotate almost like a turret. I was able to accomplish this for demonstration purposes by first rotating the player and then pitching. Instead what I am getting is if the player tilts their pitch and then turns they start to bank, or in other words they start to roll.

My code looks something like this:

```
        _rigidBody.AddTorque(Vector3.up * _horizontal *
            RotateImpulse * Time.fixedDeltaTime, ForceMode.Impulse);

        _rigidBody.AddTorque(Vector3.right * _vertical *
            RotateImpulse * Time.fixedDeltaTime, ForceMode.Impulse);

```

I sincerely appreciate you all offering to help me with this.

# Answer
> 0 votes
You can do it by accessing the `angularVelocity` directly as i commented earlier, however if you want to use the `addTorque()` you could use something like

```
rigidbody.AddTorque(Vector3.up * speed, ForceMode.Acceleration);
// or
rigidbody.AddTorque(Vector3.up * speed, ForceMode.VelocityChange);

```

Notice the second parameter, `Acceleration` and `VelocityChange` both applies the torque and ignores the `mass` of the object, only difference is `Acceleration` continuously applies the torque while `VelocityChange` instantly change the velocity,

Or you can use `Force` or `Impulse` which are similar to `Acceleration` and `VelocityChange` respectively, but consider the `Mass` in the calculation,

While using any of these two force modes if your object is **not scaled evenly in all 3 axis** then you will get weird rotation because of the `Mass` of the object.

---
Tags: unity, physics, 3d, mathematics
---


# Question
Title: What is the best way to implement the story functionality (dialogue and cutscene management, etc.) in an RPG?
I would like to know what the best way to implement the story functionality of an RPG would be. I am writing the game in C++ using the SFML library for graphics, and I have implemented drawing tiles, level loading and player movement, but I am not sure on how exactly to go about implementing the story. How would I implement when to do cutscenes, what to do in cutscenes, changes in dialogue, and have dialogue options affect the game? I am planning to have the dialogue in JSON files in a format similar to this

```
"dialogue" :[
        {"type" : "dialogue", "character" : "player", "text" : "dialogue here", "result" : "next"},
        {"type" : "dialogue", "character" : "character", "text" : "more dialogue", "result" : "next"},
        {"type" : "option", "options" : [{"text" : "option 1", "result" : "goto 4"}, {"text" : "option2", "result" : "goto 5"}]},
        {"type" : "dialogue", "character" : "character", "text" : "from option 1", "result" : "next"},
        {"type" : "dialogue", "character" : "character", "text" : "from option 2", "result" : "next"}
]

```

Is this a good way to go about this? Should I also consider embedding a scripting language like Lua for cutscenes and other high-level tasks?

# Answer
RPG elements in a home-brew game engine aren't difficult, but are hilariously complex to code. Look at the number of bugs in Skyrim, which still exist years after release.

Each npc entity has it's own dialogue when the player interacts with it, and that dialogue will very likely change when quests are completed, abandoned or failed. It may even change depending on some kind of reputation like mechanic.

First, map out your interaction tree on paper in a logical way:

1. Each entity should have N dialogues (which may be cut scenes).
2. Each dialogue should have M conditions which need to be met (M can be zero)

Functionally, each entity should have a collection of dialogues/scripted cut-scenes, and a script of some kind which will select the dialogue out of the collection depending on some data that the player entity contains. This will likely involve writing a scripting system. I recommend using LUA and luabridge. There are some really nice tutorials on this, so I won't cover it here. A very simplistic example of such a LUA script would follow:

```
function getDialogue(entity, player)
    local progress = player.getQuestProgress()
    local questProgress = progress.getProgress(entity.getQuestID())

    entity.setDialogue(questProgress)
end

```

In this example, each quest has a unique id, and each dialogue is unique within each npc.

The "progress" object is just a collection of integers, which store data on each quest in the game (0, for not default, 1 for in progress, 2 for complete).

If quest progress is 0, then the entity will offer the quest to the player when interacted with.

If 1, then the quest is in progress, and so a sort of "How are you progressing?" sort of dialogue should be used.

If 2, then a generic "Thanks for your help!" type dialogue.

In the case of cut scenes, this is more complex, but the basic idea is to shut off player controls (except maybe skip cut-scene), and then allow the script to control the camera and dialogue/animation.

To do this, you will have to tie up pretty much all your game engine and entity functions to your scripting engine, allowing C++ functions to be called from LUA. This will take some time, but is worth it in the end, as it allows you to test your scripts without recompiling your source.

Once you have an adequate amount of control of your engine from scripts, you will be surprised just how much control over your game you have.
> 3 votes

# Answer
There is *best*, however, I would argue for separating the concerns of deciding what text to show and getting the text itself.

You can hard code the decisions, it is a finite state machine. And, I would argue for reading the text from a file (which you can replace when the time comes for translations).

Or not. The text can be hard-coded too... read from a database, come from a web request, whatever. At this state it only matters that you separate it, so you can replace it later – and even replace how it is stored – without worrying of messing up the structure.

---

Now, since you mention cut-scenes, and not just dialog, I want to mention that there are cut-scenes systems. They take more data than just the text and options. They take the location, characters and animations to use. *Even lighting and camera movement.*

You can even have a separate tool to create them – something that is more practical to writers, artists and game designers – and it would output a file that can be embedded or otherwise loaded by the game... and of course there would be code to play it.

*These are – of course – not for talking with some random NPC, but – you know – cut-scenes.*

---

Or you can use a *script*, sure.
> 1 votes

# Answer
As others have noted, how you store the story files is not that important: When you feel comfortable with Lua, it's an amazing tool to "remote control" your game engine to

* block user input
* move character models/sprites around
* display dialogue

aka implement cut-scenes.

You can also encode all this in JSON files, as an array of action steps. Your game will have to read and interpret the instructions on its own, as opposed to Lua directly controlling your engine. Either way, then you need triggers to load the script at specific player positions, or when the player interacts with objects or NPCs.
> 0 votes

# Answer
My answer will be based on how dialogue and cutscene system worked in my top-down and platformer games.

**Long story short**:

Ini files for simple actions and dialogues, Lua scripts for more advanced logic.

**Simple scenes**

My .ini files looked like that:

```
[dialog]
1 0=ifi val m3p3event 1 10 15 1
1 1=ifi val m3p3event 3 11 12 13
1 10=setb 100
1 11=setb 200
1 12=setb 300
1 13=setb 400
1 15=setb 0
100 0=scene
100 1=w8 1
100 5=str Obi-Wan: Hello there.
99=str Grievous: General Kenobi.
98=str Obi-Wan: What's up?
97=str Grievous: An unit vector pointing in Z direction, what about it?
...
83=str Obi-Wan: And that's why communism is bad. See you later!
82 0=save val m3p3event 1
82 1=unscene
82 2=setb 0

```

Each NPC had information which .ini file it should launch when talked to.

First number (due to historical reasons called "B") is the step in dialogue - player presses Enter -\> number decreases by 1. Second number ("i" cause, well, it's the loop index) is used for handling multiple actions in single dialogue step. "i" goes from 0 up to 100. At each step of this internal loop I read string for key "\[B\] \[i\]" and parse it. First word is the action, rest are the arguments.

**Advanced cutscenes and logic**:

In the above example is the line:

```
82 0=save val m3p3event 1

```

In the background there is a lua script (to be specific, there was a background one and one for each NPC - this one was for the NPC). If the value "m3p3event" is set to 1 it assumes the cutscene is started. Code for the cutscene:

```
function update()
    if(mode==0) then
        local dbv=getDBValue("m3p3event")

        if(dbv==1) then
            mode=1
            end
    elseif(mode==1) then -- Event started
        x, y=getPosition() -- Get this NPC's position

        if(testCollision(x+48, y+96, 4, 4)) then
            jump(108)
        elseif(testCollision(x+24, y+16, 4, 4)) then
            jump(48)
            end

        if(x<=1670) then
            moveRight()
        else
            timer=timer+dt

            if(timer>=1) then
                timer=0
                mode=2

                setNpcBounceLeftByID("m3", 384, 400)
                end
            end
... and so on.

```

Additionally I could define Lua mini-scripts in the .ini files, eg.:

```
10=str Jump if you're happy!
9=lua playerJump(64)
9 1=str Player: Yay!

```

Lua is better at handling mathematical operations than my ini-script, so whenever i needed to calculate something (spawn NPC relative to the player, detect player's position and start cutscene...) i used Lua. For most of the dialogues i only used ini-script.

To sum it up:

Pros:

* Ini files are fairly easy to parse,
* Ini-script is more than easy to parse,
* No tools needed to edit the ini-script (format is human-readable),
* No recompilation needed to see the changes in the script during development (as files are stored outside of the code),
* For the most of the dialogues using Lua would be overkill,
* Writing dialogues is really fast (in your JSON example you have to repeatedly write a lot of stuff).

Cons:

* Adding something in-between existing command requires reordering of later actions (that's why i always left space for around 100 entries between different scenes/dialogue options),
* Localization is difficult, as the cutscene code is mixed with the texts,
* Tricky communication between Lua and ini-script.

Hopefully looking at other answers and my example you'll find a way to implement your cutscene system.
> 0 votes

---
Tags: c++, architecture, game-mechanics, rpg
---


# Question
Title: What is "u" and "v" in this Navier Stokes implementation?
reference: https://pdfs.semanticscholar.org/847f/819a4ea14bd789aca8bc88e85e906cfc657c.pdf

```
while ( simulating )
{
    get_from_UI ( dens_prev, u_prev, v_prev );
    vel_step ( N, u, v, u_prev, v_prev, visc, dt );
    dens_step ( N, dens, dens_prev, u, v, diff, dt );
    draw_dens ( N, dens );
}

```

Is u,v the same as x,y?

# Answer
> 2 votes
So, yes and no. According to your paper, **u and v are vector fields.**

As read on the bottom of Page 3:

`In practice we allocate two arrays for both the density and the velocity of size,`

`size=(N+2)*(N+2):static u[size], v[size], u_prev[size], v_prev[size];static dens[size], dens_prev[size];`

U and V contain an array of vectors for each 'grid'- this method takes the particles that end up at grid 'centres' and backtraces them compared to a previous snapshot. In other words:

1) Take a snapshot;

2) Run for a bit of time;

3) Take an end snapshot and look at the points that ended up in grid centres;

4) Look at where these points were at the start;

5) Draw a nice smooth line between the start and end points

6) Call it a vector.

In this paper, **u is the field of x coordinates for the vectors and v is the field of vector y coordinates.** I appreciate it's a longwinded post, but I feel I'd be being cruel just to say 'yeah sure' because it's not actually the answer.

Of course, I'm sure you'll be able to work out that `u_prev` and `v_prev` are just the coordinates before the timer started.

Hope it helps!

---
Tags: fluid-dynamics
---


# Question
Title: If a MMORPG does not have a limit on the number of players, will all players eventually focus on the same server?
Consider a WOW-like MMORPG game. The only difference between it and WOW is that there is no limit on the number of players (Suppose that there is no limit on hardware performance and network bandwidth).

For such a game, developers can still open multiple servers for players to play.

My question is:

Assuming that the game can run steadily over a long period of time, will it eventually lead to the concentration of all players on the same server?

Whether the answer is yes or no, is there a corresponding economic, sociological and ecological model behind it?

(This may be an open question, I am not sure if I should ask questions here, but there seems to be no better place to ask. I hope that I can get some inspiration through discussion)

Thanks.

# Answer
> 5 votes
---

## New answer

Due to the comments, I will assume that network latency is not a problem, and forget about the server side.

At the end it depends on whatever or not the developers facilitate (or enforce) player migration.

There are few reasons for the developers to want to keep multiple servers despite not having hardware or network limitations.

And yes, there are reason why people might want to stay on a server or move to a different one.

I am throwing a broad net here. Brevity eludes me.

---

**On content and the level gap**

There are features that affect player migration. One of them is whatever or not there is support to copy or move characters across servers. Being unable to move to a new server without bringing your character with you means that for some people migrating to another server has a psychological cost (you can't use your character). For other this is not a problem...

IN fact, for some people, to start over with friends (not bringing their old character) is a plus! That is, given a conventional MMORPG, having a large level gap between the characters means there is little content they can enjoy together.

Which brings me to the next feature: the ability to reset your character. If I cannot reset my character to start over with a friend, we might as well decide to start over in a different server.

By the way, another motivation to change to another server – aside from friends who are starting over – is because there is no new meaningful content for the player. There are no more quests, no more areas to explore, no more relevant items to collect. Perhaps some new stuff was added, but it is the kind of stuff that only new players would enjoy. A good example are quests that cannot be repeated getting an update. *Until developers add new quests and additional content, at which point we might want to go back.*

---

**On social structures**

> (A) player (Player 1) can initially play in Server A. He play for one year and then quit the game. After two years later, he return to the game due to his friend (Player 2). At this time, he create a new account on Server B, because Player 2 is in Server B.

If the Player 2 is new, in theory Player 2 has less to lose in changing servers that Player 1. And I do not mean characters, but social structures.

MMORPGs have a social difficult curve. Go back to Bartle taxonomy of players. It makes sense to have features intended in attracting and keeping players of different kinds, and given that some players are there for the social experience, some features are going to be social... like what? contact lists, friends, groups, squads, teams, guilds, clans, alliances, etc... building and maintaining these social structures takes time and effort.

It could be that the old player is unable to enjoy the same content as the new player... yet, the old player could have access to a guild or clan that is not available in the other server. The old player does not only not want to lose the social structure... the new player would benefit from joining it.

Well, of course, if after a year the old player was not kicked out.

Social structures has advantages. It is not only finding people to play with. It is also access to know-how, and people to trade with.

A larger social structure is better... However, game developers we want to keep balance. Because of this we will introduce features that scale with social structures... as a result, we put pressure on those structures to keep players active (and we, game developers, want active players), which in turns means inactive players get kicked out of these social structures.

In fact, a social structure that cannot *stay afloat*, will likely dismantle.

In fact, if players leaving a social structure will make more likely that other players leave it. This is similar to how a few soldiers breaking an infantry line can precipitate a retreat. Or, you know, a financial crisis.

---

**Player identity and sense of belonging**

People like to belong to a team. Yet, people like to compete. *Refer back to Bartle's work.* Because of that, it makes sense to have teams that compete. These can emerge naturally, or artificially.

For example, we can have clans complete against each other as a game feature. Similarly, we can have people of different servers complete by unofficial means.

At clan level, we probably want to join one with people with which we have some commonality. Players can develop a sense of identity with the clan. Language is very important. So is time zone (who is online when). And so are interests and values. The same thing can happen at server level.

In fact, you will find that clan/guilds – once the game has a large enough player base – will advertise outside of the game. They want you to join their server so you can join their clan/guild.

---

**Conflicts**

Going beyond a conventional WoW-like MMORPG. We also need to consider player generated content. It can be a motivation to visit other servers.

Also, if the game has faction wars and limited area... a new server is "free" real state.

Another reason to go to a different server is to get away from "them". People are people, and there is spam, trolling, bullying, harassment, etc… *That sense of identity people have, could motivate to attack others.* If moderation tools are not enough, a close second to consider before leaving the game is to go to another server. In particular if you can move there with a group of friends in agreement.

Yes, you can have something resembling fascism in the server. *The trolls are ruining the game. The new players are ruining the game. “They” are ruining the game. Not us. Let us make them want to leave the game.*

---

Thus, we need good moderators. We need them around the clock. We need them to handle a huge number of people who speak different languages and come from different cultures. They have to deal with people who might bring their real conflicts into the game, and even their nationalistic views.

Does it not make sense to partition people, so that each moderator is responsible to handle a fraction of them? *At a given time, because there ought to be rotation.* It can make sense to move people to a different *logical* server.

---

For reference, a moderation technique that began in forums is making it so that only trolls and spammers can see trolls and spammers. This means that the quality of the forum is low for them, while it does not affect the rest. The result is that people are more likely to just leave the forum, while banning them would result in them creating a new account. *I used to know this as being "Hellbound", however I think that terminology has fell out of favor.*

Something similar can be done in games with cheaters. So that if you are a cheater you get to play with all the cheaters. *Apex Legends announced they were going to do this, not sure if they did.*

---

**Testing**

One other advantage of having multiple servers is to have different set of game rules. We might even – wait, no. I would encourage to – use a server as test bed for new features. This can help balancing before deploying to all servers. *And there will be people who wants to test the new features first.*

---

**A bit on server...**

I know I am staying away from the server side. However, have you considered logical vs physical servers? The thing is, as far as the client is concerned, a server could be anything from a process in a computer to a distributed system across thousand of computers.

On the other hand, changing from a server to another does not have to imply to go to different hardware.

The server will already have ways to partition people. One evident one is by their position in the world (for example, if you are in a map, you should be getting updates about the movement of people in another map). We could even consider each map a logical server.

---

Again, goith outside of the conventional MMORPG...

It could make marketing sense – in particular if servers are magical – to sell logical servers, which are nothing more and nothing less that logical partitions of the physical server. *Think, instances. They might as well be virtual machine instances.* And even let the buyer configure the server with their own game rules, perhaps even mods.

They can result in a more intimate experience for the buyers. They could be closer to good old single player RPGs... except, you know, with other people, people who the buyer invites to join.

For example, a company could be interested in buying one of these logical server for employees of our company. *And we do not have to see, you know, “them” (for example people form a competitor company) in the server.*

Now, of course, people are part of what you are selling with an MMORPG. It is hard to convince people to play an MMORPG that nobody plays. However, that does not mean that there is market for them. Which is why I think a game to be marketed like this would not be the conventional MMORPG, but one designed for a more intimate experience.

---

**Addendum**: Dungeons are a resource.

Some memories have come to me. Memories of rushing to get to a good leveling position in a dungeon. People in the clan would try to hold our ground by rotating people. We would funnel players as they log into the game, and have reserve tanks and healers to take turns... why? Because as soon as we leave the spot, the people of another clan would take it. *And we would do the same thing.*

Some days we could not find a spot. We would go from dungeon to dungeon searching something appropiate for our level... and end up killing random mobs in the overworld.

I can imagine that if the server were more crowded that could go on for weeks. And if that were the case, it could make migrating, as a clan, to another server an interesting proposition.

---

## Original answer

> Suppose that there is no limit on hardware performance and network bandwidth

You still have latency. "Bandwidth", is transfer rate... I mean, how much data can be send and received in a given period of time.

That says nothing of how much time a particular piece of data takes to reach its destination. That is, latency.

Why would there be bad latency? Because of the network. I will let Grace Hopper explain nanoseconds to you.

Now, bad latency in a game means that the response from the server takes time to reach the clients. a.k.a. Lag. It is, of course, not the only source of lag. Regardless, network latency causes lag.

So, you can have a magic server that have infinite storage space and execute instructions in virtually zero time, and the game still have lag.

Which means, that regardless of how magical the servers are, there is still value in having multiple servers distributed geographically around the world. And of course, everybody would connect to the one nearest to them.

---

There is of course, the chance that you will have multiple magic servers and you do load balance between them, which will prevent all uses to be put in a single one... yet, there is no need for load balancing if your servers are magical...

...except, well...

If we have a hub town with millions of characters moving around... perhaps your server is magical, but the client isn't. It is a good idea to – if not physically – logically separate entities so that the client does not have to render all that. Why? Because the hardware of the client is another source of lag.

Since, you have perfect magical server, they can decide exactly what each client should be able to see, so that clients does not have to expend time deciding what to draw...

...wait...

---

> (This may be an open question, I am not sure if I should ask questions here, but there seems to be no better place to ask. I hope that I can get some inspiration through discussion)

Welcome to Worldbuilding Stack Exchange.

In a world where servers are magical, the server can render for the clients.

> is there a corresponding economic, sociological and ecological model behind it?

**Economy**

In this universe, computing power is unlimited. That does not mean it is free. We have said nothing of energy consumption.

I do not know if it holds in your fictional universe, but in ours there is a Maximum theoretical data density. Which means that your magical servers take an unbounded amount of physical space (I will assume they grow as needed).

Similarly, we have a theoretical minimum time. The plank time. Since we cannot really execute something in less time than a plank time... in order to execute more things in the same time, we need more CPUs.

**Sociology**

*In game*

If we have a conventional MMORPG, there is a chat window. Just imagine that chat window with messages in all languages of the world going by at ridiculous speeds. Even if not separated by physical servers, it is a good idea to be able to filter by language.

There is also the problem of crowds. It is a good idea to have less channels to separate people. Not only because of performance (of the client), but because large crowds can be detrimental for the experience of the game.

*Out of game*

A server that can grow without bounds will certainly catch the attention of authorities. What if it grows out of a legal jurisdiction? Will different laws apply to different parts of the server?

**Ecology**

Back to energy consumption. We do not have a growing server that could eat ecosystems... we need to feed the beast, and power plants have an impact on the environment.

I would need to actually do the computations – I'm not taking this answer seriously – to figure out if you need a Type I civilization to have these servers.

See also: Matrioshka brain.

---

Let us be honest, you do not really have the problem of having magical servers. All you need to know – as far as game development is concerned – is that network has latency.

---

**Addendum**: The part about a growing server is not entirely fictional. Companies could build larger and larger data centers. Except they cannot do it as fast as this answer could make you imagine. There constraint in resources. They need to buy land, the need to hire people, they need to buy hardware... the hardware needs to be manufactured, people needs to do maintenance to it... is the business good enough to support unbounded growth?

# Answer
> 1 votes
it all depends on your infrastructure. we never have an unlimited player on the same server as we have no unlimited server capability.

when you hear unlimited, it means big number of players but player number always depends on server responsibility, authority and game Logic. in some games server only receives the data and broadcasts it but in some other server should do processing and....

if you have a high power server you can connect all your clients to one server but you have to solve latency problem.

# Answer
> 1 votes
Most games discourage player movement between servers by making it impossible for players to transfer their progress. So there is usually very little movement of players between servers.

The main reason why player numbers on servers fluctuate are onboarding and offboarding players.

However, when a game runs for a very long time, player numbers usually go down overall. When there are less players, then the reasons why there are multiple servers disappear. So the developers usually try to find some way to consolidate servers in order to reduce running cost and concentrate the community for better gameplay. But doing a server merge or switching off a server altogether is a conscious decision by the developers, not a natural development.

# Answer
> 0 votes
The only reason I can think of to have all players consolidated on a single server given your theoretical super server is economic. It would not make sense for a developer to pay for multiple servers, whether they are physical or logical, if all players could fit on a single server. In this situation, the game developer would most likely heavily incentivize players with exp/drop boosts to either move their existing character over or create a new character on a specific server. Game devs currently use this strategy to help spread players to less populated servers.

There are very few reasons that players themselves would want to consolidate to a single server. Taking your example of a WoW like game, a single server would make the experience of playing the game awful. Since spawns are limited, it would take substantially longer for players to complete quests that require killing specific mobs or field bosses. Many positives that are associated with playing on a single server are negated with dungeon/raid finder in WoW since those allow cross server play for shorter queue times. From a players perspective, the only reason to switch servers would be to play with a friend or for some boost to progress speed. A single server would have significant impact on the end game and leveling systems of many popular MMOs/MMORPGs.

---
Tags: game-design, mmo, economy, social
---


title: Unity AR Ground Plane Detector

text:
# Question
Title: Unity AR Ground Plane Detector
I need to check a "ground plane" to put objects over it without a marker, using Unity.

Right now I'm using Vuforia, but the Ground Plane on Vuforia only works on some devices, I tested on mine and my mother's Android phone, both modern and from different brands, didn't work. So it's not an option, because many many people couldn't use it.

Same with ARCore, asked me to install some sort of Google Services AR, which the download is locked for my phone.

Is there any way to use Unity with some kind of ground plane detector that many phones can "read" it? Any API, code, anything different that I didn't try yet?

Thanks!

# Answer
Being modern phone is not important.

first you need to check that your phone has **Gyro** asits most important feature that markerless AR use.

next you have to check android device supports ARCORE and for Iphone Device You need to check if it Supports ARKIT. you can find list here: https://developers.google.com/ar/discover/supported-devices

you need to enable XR and ARKIT support in unity.

if all of these are done, its your bug. you can edit you question with you code or project image for better answer
> 1 votes

---
Tags: unity, augmented-reality, vuforia
---


title: Unity move arrows along path

text:
# Question
Title: Unity move arrows along path
I am not sure how to go about what might be a simple task. I want directional arrow sprites to move along a curved path in 2d to show the player when to go.

I can use DoTween to create a path. But not sure if I should Instantiate a load of sprites(arrow) and move them along. Its seems wasteful.

# Answer
Here is the following code I added to the `LineRenderer` to scroll the tiles texture.

```
public class LineArrow : MonoBehaviour
{
    public float scrollSpeed = 1f;
    public Renderer _renderer;
    // Start is called before the first frame update
    void Start()
    {
        _renderer = GetComponent<LineRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        float vOffset = Time.time * scrollSpeed;
        _renderer.material.SetTextureOffset("_MainTex", new Vector2(vOffset, 0));
    }
}

```
> 0 votes

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


# Question
Title: How to make sure that at least one element in a collection has a certain value?
In my game, I assign each agent a random direction. However, at least one of these agents has to have a direction of `Vector2.up`. How can I ensure that?

```
private void AssignRandomDirection()
{
    var directions = new List<Vector2>
    {
        Vector2.up,
        Vector2.down,
        Vector2.left,
        Vector2.right
    };

    foreach (var agent in FindObjectsOfType<Agent>())
    {
        var random = Random.Range(0, directions.Count);
        agent.direction = directions[random];
    }
}

```

# Answer
> 0 votes
Just use a boolean to keep track of whether you've ever assigned a value of up. If not, inject a value of up at a random position in your collection.

```
private void AssignRandomDirection()
{
    // No need for this to be a list, since you never add/remove elements.
    var directions = new Vector2[]
    {
        Vector2.up,
        Vector2.down,
        Vector2.left,
        Vector2.right
    };

    boolHasAssignedUp = false;

    var agents =  FindObjectsOfType<Agent>();

    foreach (var agent in agents)
    {
        var random = Random.Range(0, directions.Length);
        hasAssignedUp |= (random == 0);
        agent.direction = directions[random];
    }

    if(hasAssignedUp == false)
        agents[Random.Range(0, agents.Length)].direction = directions[0];
}

```

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


# Question
Title: Load scene without being in build settings and without using AssetBundle
This is the closest I've gotten:

```
    EditorSceneManager.OpenScene(
        AssetDatabase.GUIDToAssetPath(
            AssetDatabase.FindAssets(
                "t:SceneAsset " + MenuSceneName,
                new string[] { "Assets" }
            )[0]
        )
    );

```

However this generates an error at runtime:

```
InvalidOperationException: This cannot be used during play mode, please use SceneManager.LoadScene()/SceneManager.LoadSceneAsync() instead.

```

I can't follow its suggestion because those functions require the scene to be in build settings or an asset bundle. So, is there any other option?

I wonder how (and if) Addressables achieve this? Note: I'm not willing to switch to Addressables - I'm quite enjoying working with AssetBundles.

**Why?**

My game uses AssetBundles for general loading of EVERYTHING, so there's only one blank scene in build settings. However, during development I'd rather not have to continuously build and load from AssetBundles, so I'm trying to dynamically load scenes WITHOUT having to add them to build settings.

# Answer
Turns out there's `EditorSceneManager.LoadSceneInPlayMode` which does exactly what I'm looking for! Awesome.

I had asked on the Unity Forum and found the answer there
> 2 votes

# Answer
Unfortunately, the only ways to load scenes are the two options you already mentioned. However, just because it’s in the list of scenes, doesn’t mean it needs to end up in the built game. There are two options here.

The first option is to manually uncheck the checkboxes in the build settings next to all of the scenes that you don’t want to include whenever you do a build. Simply click on scene 1, then shift-click on the last scene, and toggle any of the checkboxes.

The alternative is to write a small script which automatically modifies the build settings whenever you do a build. This shouldn’t be too difficult, but if you are not doing a lot of builds it may not be worth the effort.
> 1 votes

---
Tags: unity, loading, scene, asset-management, editors
---


# Question
Title: What is the cleanest way to code predictable client/server components
Lots of classic games that I've read the source code to do things like

```
if (clientside)
    // ...

```

or the same but with `serverside`. The code is littered with this and it becomes an extreme nightmare to test. This is especially so when the games I've looked at all happen to use global variables for the above so testing goes out the window, and I am fortunate enough to be able to write tests for such things (hobby projects with no time constraints!)

I'm at a point where I need to care about this now (especially with having to deal with prediction and actions, scripts, etc, in a level). As such, I've gone searching for how people architected solutions to this problem such that there was the ability to have clientside prediction of some stuff, while preventing the code from becoming a gigantic series of `if` statements strewn about everywhere.

What is the best way to approach this? I am willing to trade a bit speed for clean code with good OOP. Is there a good example that I can learn from? Or am I stuck with littering `if (client/serverside)` everywhere?

Ideally I want to write the least code possible, write it in the cleanest way possible, and have something that I can easily reason about without having a ton of branching thinking "ok what if condition A, not B, C and D, not E" when trying to figure something out.

I've been trying to see if there's a way to make some kind of common base class which shares all the code between them, and then making a bunch of `abstract` methods that either the Client implementation or Server implementation would do their own stuff on top of it, but part of me is worried that because I've neither done anything like this before *nor* seen anyone ever do it this way, I'm scared of wasting a significant amount of time on something that may be architecturally bad. This is primarily why I'm posting this.

In short: What is the cleanest way to architect the code? Are there any examples or articles I can learn from?

**Edit**: The code should all be in one binary, so people can host a multiplayer server from an offline experience.

**Note**: This question is completely different from how to do prediction, unlagged, etc, and as such is not about that (and I already know exactly what I need to do). It's about the implementation of such things such that I can write a client that supports predicting and server code that reduces the amount of duplication as much as possible.

# Answer
> 1 votes
**Edit:** The code does **not** need to be in one binary to allow people to host a multiplayer server from an offline experience. A player **is never a server** A player *might* be a **host** this means the server is *hosted* on their machine. (or a machine they control) They still connect as a **client** just they have admin credentials!!!!

This is a fundamental OOP concept known as Relationsip: "Is a" versus "Has a". A player might *have* a server, but they are objectively *not* a server.

There are very few games which hot-swap between SP and MP and the ones that do, simply run a SP server while the player is playing SP, then open up to MP connections if requested.

A possible exception might be a game which relies heavily on a database, but even then the SP instance is still treated like a client. Upon switching to MP, the single player game ends, loads into a server, and the player re-joins as a client.

You would only use this exception if there wast the database reliance, and if the server code was only relaying the absolute minimum amount of information between players. Positions, events, etc. Things the client would have to know to send to the server in the first place.

There are a number of ways to divide responsibilities between server and client (such as a "lightweight" server, which lets both clients handle their own logic and does it's best to sort things out (which opens a big cheating / hacking risk)) Absolutely **ZERO** designs involve treating client and server as the same entity however.

Yes. You *can* brute force client and server code into the same binary. No, you should never actually do that. It would not be "clean" (or proper) server architecture. It would be demonstrably *wrong* architecture.

The entire premise of a server is inherently based on client & server being separate things. If these things are not separate you are not building a client / server, you are building peer-to-peer, and this requires a completely different approach, cautions, considerations & designs.

Just Use a .dll if your program is C++/C# or .jar if it's Java based. This is one of the exact purposes these things exist to be used for. Any code that contains anything that even remotely looks like `if(client){//do stuff} else if (server){//do other stuff}` is a massive red flag that something has gone horribly wrong in the design. (Even if you just stuff your server code into it's own class(es) it still has to be *conceptually* treated as an entirely different program for the sake of properly dividing responsibilities)

When using a .dll or .jar there is absolutely **no** practical difference in how you write the code. Code hints, function calls, etc all work the same as they would if the .dll content were a class directly in the project source. What a .dll does do is encapsulate code to keep it more modular, and organized.

There should never be an instance of `if (client/server)` present in code because it should *never* be ambiguous or subject to a variable / property. `if (instanceof server)` shouldn't even be present, since no correct code should ever need to ask this in the first place.

Clients and Servers communicate through a Port / Connection. A correctly designed client knows it's talking to the server because it's talking through a port or a connection.

A server on the other hand might ask something like: `if(player.getCredentials()==server.AdminKey())`

Examples:

Minecraft (mobile editions): While playing single player, another player on the same wifi can join your game. When this happens your screen will freeze with a "please wait" dialog. In the background, you are leaving single-player instance, and joining a multi-player server as a client. One player being the "host". (Leightweight Server. Hacking not a big issue)

99% of games with single player campaign / multiplayer modes. You will notice these are separate menu options. The single player campaign is a standalone program. The multiplayer mode is basically a separate "client" program. (Code redundancy here is between the Client and an instance of Singleplayer which isn't even a Client, since it's not connecting to the server. Redundancy only exists specifically to encapsulate the server in the first place)

FarCry 5 / Darksouls upon a player joining single player client ends, and you join a server as a client. (Basically the same as above but hidden to create the illusion of seamless transition) OR the player is just already connected to a server to begin with.

Ark / Empyrion The single player experience takes place on a server set to single-player mode, that can be switched to multi-player if desired.

```
//end edit

```

The question of how to architect *any* code comes largely down to three factors:

1. Best Practices
2. Design Patterns
3. Opinion

The answer to: "What is the cleanest way to architect (server) code" really depends on what the server is doing.

However, there is one really important thing to keep in mind: Encapsulation.

It doesn't matter if you are writing a video game or bank software, "Server" and "Client" are best treated as two *different* pieces of software which communicate with each other.

Speaking from a C++ / C# background:

I would put the server code in a .dll and create a UI in the client app to interact with this library. (And if necessary a standalone UI for server management). All server code would be run entirely standalone.

(If you are using Java .jar is a close equivalent to .dll)

If you want reference material a good place to start would be looking at a simple client-server chat program tutorial.

From there you also want to look into multi-threaded design.

Finally do some research into systems analysis (specifically diagramming a system in a flow-chart). The secret to making *ANY* code "clean" is to design it as a flow chart first.

Ultimately, it will come down to standard design patterns and OOP principles. But it will be a good head start to: A. Treat "client" & "server" as separate programs entirely. and B. view "server" as any other type of software, as in code that executes instructions. (A lot of people starting out with server-side coding view it as this unique special type of program. It's not, it's just a program.)

Some examples:

Runescape is a great example of encapsulation.

The client is almost entirely UI. It displays visuals to the player, and takes input (text, mouse clicks). This input is sent to the server. The server then sends instructions back to the client as what to display.

Another example would be games like Empyrion, or Jedi Academy. These games run the server weather or not players are actually connected. While there are in-game ui features to control the server, the server itself is running as an independent program. (Often you can see a console window). When it comes time to exit, the client application simply sends a command to the server to shut down.

---
Tags: architecture, multiplayer
---


# Question
Title: Modifying Brackeys Unity Inventory Tutorial for Stackable Items?
I followed this tutorial: https://www.youtube.com/watch?v=w6\_fetj9PIw and the one after it, and it works fine, but now I'm in a situation where I want to be able to stack my items up. I saw there was a thread on the brackeys forums about this a few years(!!) ago, but the files aren't available and I saw people were having issues with it anyway. Can anyone think of a way to modify it and preferably allow for easy loading/saving as well down the road (though absolutely not necessary, I can go down that rabbit hole later), or alternatively point to a different tutorial that would do so? Thanks in advance!

---

Here's the link to the scripts, I only went up to video 6 so there might be some new stuff in there but it should at least help! https://github.com/Brackeys/RPG-Tutorial/tree/master/Finished%20Project/Assets/Scripts/Inventory

---

(note: I added a variable to the item script that keeps track of how many items of that type the player has, but the problem is that when I add a new item to the inventory it keeps adding it to a new slot and messing up the counter because I'm unsure where to check if the item already has a slot in the inventory and what to do about it.)

# Answer
> 1 votes
So you already have added a property for "quantity" on your objects. This is a good start. There are a lot of approaches to this but the most straightforward approach is to use an "InventoryManager" class.

So rather than directly adding items to your inventory, they would pass through the InventoryManager. This class simply scans your inventory contents to see if the item already exists, and adds to the stack. This idea can be handled as a standalone class, or implemented directly into the inventory logic.

A more advanced way of handling this would be to implement an event handler instead.

Ultimately it's an issue of adding some more loops / if statements to your code.

As for easy load / save functionality:

Brakcey's scriptable objects tutorial is where you should start.

---
Tags: unity, savegame, inventory
---


# Question
Title: How to check if a specific instance of a prefab is pressed?
This one is hard to explain, so I'll show the code first -

```
for (var i = 0; i < Input.touchCount; ++i)
{
    if (Input.GetTouch(i).phase == TouchPhase.Began)
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
        RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);

        if (hit)
        {
            clicksNeeded -= 1;
            GetComponentInChildren<TextMesh>().text = "" + clicksNeeded;
            Debug.Log(clicksNeeded);
            print("was a hit");
        }
    }
}

```

I need to check if hit touches the specific game object that the script is linked to, as at the moment if any of the circles are clicked, clicksneeded -= 1 to all objects currently instantiated.

Thanks for the help!

# Answer
A ray is not the right tool for this job. You want to check whether your circle collider contains the touched point, using OverlapPoint:

```
Camera camera = Camera.main;
float depth = Vector3.Dot(
                camera.transform.forward,
                transform.position - camera.transform.position
              );

for (var i = 0; i < Input.touchCount; ++i)
{
    var touch = Input.GetTouch(i);
    if (touch.phase == TouchPhase.Began)
    {
        Vector3 screenPoint = touch.position;
        screenPoint.z = depth;

        Vector3 worldPoint = camera.ScreenToWorldPoint(screenPoint);

        if (myCollider.OverlapPoint(worldPoint))
           HandleHit();
    }
}

```

Or, if you want to take the thickness of the touch into consideration, you could compare the distance vs your collider/touch radius:

```
var worldDistance = Vector2.Distance(
                        worldPoint,
                        transform.TransformPoint(myCollider.offset)
                    );

if (worldDistance < myCollider.radius + touch.radius)
    HandleHit();

```
> 1 votes

# Answer
in unity every gameobject has a unique instance id. so in instantiation moment you can get its id and check the id in raycast or any other event. its the code example:

```
string id =WantedGameObject.GetInstanceID().ToString();
      if ((Input.touchCount > 0) && (Input.GetTouch(0).phase == TouchPhase.Began))
    {
        Ray raycast = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
        RaycastHit raycastHit;
        if (Physics.Raycast(raycast, out raycastHit))
        {
            Debug.Log("Something Hit");
            if (raycastHit.collider.name == id)
            {
                Debug.Log("wanted hit");
            }

        }
    }

```
> 0 votes

---
Tags: unity, c#, android, raycasting
---


# Question
Title: What is the best way to handle simultaneous collisions in a physics engine?
I'm writing a 2d physics engine in javascript so that I can learn more about physics in video games. I have it working correctly for rigid body collisions, except for if any body collides with two or more other bodies at the same time.

Currently for each pair of colliding bodies (A, B) I modify their velocities and angular velocities based on the collision impulse, and nudge them out from each other so they aren't penetrating. But then collision detection and impulse calculations for other collisions involving A will be wrong.

What approaches can I explore to get my engine working for 3+ objects colliding with each other?

# Answer
> 12 votes
I use the following approach (similar to the mass splitting algorithm of Tonge http://www.richardtonge.com/):

* detect all colliding pairs in your scene/context. Let (A,B) be such a pair. Apply a ghost/mass splitting idea: if A is in contact with M bodies and B is in contact with N other bodies, then *temporarily* set the mass of A to `m_A/M` and that of B to `m_B/N`
* compute reaction/restitution force contributions for each pair (A,B) and store these contributions in A and B's own accumulators
* compute restitution velocities from impulses (as you stated) and store them in the same fashion (as *deltaV* velocity residues in their own accumulators for each (A,B) pair)
* compute penalty displacements (again, accumulate displacements, do not apply them instantly!)
    + reset the masses of all bodies previously designated as parties in collision pairs (`m_A = m_A * M` and `m_B = m_B * N`)

This approach is similar to how the Jacobi iterative algorithm works with linear simultaneous systems of equations. And it's not guaranteed to converge, but in my simulator it does the job quite smoothly.. in 3D (yes, an extra dimension adds twice the difficulty!).

**Caveat**: correct positions and velocities only after your collision detection/handling phase is over! That way you simultaneously update your colliding actors. Also, the restitution forces must be taken into account next time when you integrate for positions and velocities.

EDIT: Well, I guess you're using the already abused Verlet integration method (this one's become a household name within gamedev enthusiasts). In this specter of collision handling and integration, you might want to take a look here.

UPDATE: Some of the information on how to approach collision (and self collision for that matter of fact) can be found in these papers:

The approach I proposed is not by a long shot an original contribution, many games use it with plausible results and it was best employed by Jakobsen in his Hitman game engine.

From a somewhat practical experience, penalty forces (similar to linear or exponential springs getting their input from the penetration distance) do not properly solve penetrations when other forces from the bodies that collide manage to be greater than them. That's why I chose to combine three (almost redundant) approaches: Newtonian reaction forces (you push the wall, the wall pushes back), impulse derived velocities (snooker balls colliding) and a non-natural "move the bodies away from each other geometrically" solution. Together they seem to provide everything: get rid of *most* ugly interpenetration artifacts, colliding bodies tend to interact with each other on the long run (due to restitution velocities and forces - at least the forces that tended to drag the bodies in a collision scenario are cancelled out and the bodies bounce away from each other). Lastly, for further understanding of these simple but common concepts, I suggest analysing these slides.

My "abused method" epithet describing the Verlet integration steps is targeted at a popular culture belief that this is the Holy Grail of integration methods. It is just marginally better than its Symplectic Euler (also called by some semi-implicit Euler) cousin. Way more complicated integration methods exist (and all bear the implicit name in them). Powerful game engines make use of them, but indie developers don't have the time to experiment with those since Verlet, when tuned to a specific scenario, really does wonders. Also, there is absolutely no integration method that can deal with stiff constraints without a little cheating being involved (can't find the link, but the paper I'm referring to should be called "X.Provot - "Deformation Constraints in a Mass-spring Model to Describe Rigid Cloth Behaviour" ".

# Answer
> 1 votes
I suggest that, instead of changing velocities, you change the **forces** acting upon an object. Don't "nudge" them out, rather, do it smoothly and utilizing already existing code. By doing this the bodies wont immediately (and rapidly, I suppose) change their velocities.

Check out Box2DJS for an example: http://box2d-js.sourceforge.net/index2.html.

# Answer
> -1 votes
I've analytically solved impulse equation for groups of colliding bodies. The only problem I faced was lack of variables to find relative interaction strength among contacts in a group, which I've filled with depth of bodies intersection.

Solution for group contacts is not much harder then single contact. Unfortunately I lost a paper with calculations, thus unable to share it here.

Edit: Probably I've came up with something like this https://physics.stackexchange.com/questions/296767/multiple-colliding-balls

---
Tags: 2d, collision-detection, javascript, physics
---