# Question
Title: How to make good combinations of xp tables and xp rewards?
Is there a known **step by step** (automatable) to define mean xp reward formula/table to bases specific challenges rewards (generically, not only defeating enemies) and total xp table that set character level progression speed? Sounds complicated.

For example, if a character defeats about

\\$LevelUpEnemies(Lv) ≈ 120/max(1,6−Lv)!\ +\ 60∗clamp(0,Lv−5,3)\\$

enemies like self then character grows up, initial level is 1 and final level is 10 (like WCIII), characters has about `Hp≈(8+2*Lv)²`, `Atk≈(4+Lv)²` and `Def≈4+Lv`, no more data and a attack damage is

\\$Damage ≈ Attack\_{Attacker}\*\sqrt{ Attack\_{Attacker} }/( \sqrt{ Attack\_{Attacker} }+Defense\_{Target} )\\$.

How can I calculate the (fair) rewards base formula per level and the total xp table to do this?

> Notes:
>
> * How can I calculate ==\> the **step by step** text teaching or the algorithm
> * Fair ==\> preferably proportional to the difficulty (if not, nearly, well-reasoned)

In addition, I see big xp tables with a lot of rounded digits with no beat missing, looks closely handwritten (just not). Is there a method or algorithm that besides builds the data also (perhaps) rounds to maximum digits with no kink?

# Answer
> 1 votes
# Set Xp Rewards

The worst challenge is the fair average reward definition. There are several ways to gain experience: defeat enemies, accomplish mission, consume items, bonus and so on. It's generally effort with some difficulty, expended time and other things that should be measured using a criterion. How can we simplify it?

We can think about a lot of equivalences between xp farming ways as if all of this were as one. About the question example, it sets a `LevelUpEnemies(Lv)` to focus on. This suggests that killed enemy xp may be the unification. Indeed mostly all of it involves defeating a number (and quality) of enemies for xp to up. Even missions and other ways usually come down to that otherwise at least have equivalences with it. In this case the calculated mean xp rewards formula that bases all possible game xp sources can be summed up as the mean/expected balanced level enemy xp (`LevelUpEnemies(Lv)` of it to level up) and don't have more experience sources or in the other sources we compare with enemy xp and adapt it with the agreed equivalences.

For example, a quest can be as difficult as kill five wolfs (maybe it's the quest... or not) and long as hunt ten wolfs (maybe the quest is travel and hunt it... or not). Why not rewards it with the "five-ten" wolfs xp? In this case, we need to define reward influences of hardness and delay but we can assume that all comes down to a number of enemies and has some equivalence with expected time.

If we set

* generally `66.7%` xp is from defeat result (`x` enemies defeated),
* generally `33.3%` xp is from full defeat procedure time (`y` defeat time) and
* in wolfs case `DefeatWolf: XpReward = 30xp`

then `XpReward = 20*Wolf_Kills + 10*Wolf_Finds` such that

* generally the `finds` is total time to find (can include more actions time),
* generally the `kills` is number of defeated enemies and
* hunt a single wolf (one find time and one kill) makes `Wolf_Finds = Wolf_Kills = 1`.

The example quest xp reward is `20*Wolf_Kills + 10*Wolf_Finds = 20*5 + 10*10 = 200xp` (like hunt `≈6.67` wolfs). If leveled xp reward base formula on wolf level is `25xp` then kill wolf and finish quest is set up to gives `120%` and `800%` of expected xp reward.

In short, the point is made the challenge rewards formula and number of rewards table/formula be adapted and represented by defeating enemies xp reward formula and combine with the table/formula "number of enemies to level up" to solve it all. But... how we define defeating xp reward (fair) base formula?

### The Relative Character Power

Of course we expect duplicate reward for duplicate effort and risk after all. Fair enemies reward requires some relative power notions (when some character becomes `2x`, `3x`, `10x` stronger than was or be stronger than other). Let's use proportion with total damage done until fall as power criterion.

If double damage done (with no other data impact), double power. Triple damage done, triple power. Yes, obviously it is proportional. But if double vitality... hm... it doubles suffered hits until the end. Double combat time (yes, time that character can attack), double hits done, double damage, double power. Yeah, health proportion. If halves damage? Double suffered hits, double time... double power. Inverse proportion.

About the example, `power Hp` (obviously), but `Atk` and `Def` are harder. If we calculate it (I used Maplesoft Maple 15)

we see

* `Atk x 2 ⟹ Dmg x 2.343` every levels (3),
* `Atk x 3 ⟹ Dmg x 3.804` every levels (5),
* `Atk x 4 ⟹ Dmg x 5.333` every levels (7),
* `Def x 2 ⟹ (1/Dmg) x 1.5` every levels (10),
* `Def x 3 ⟹ (1/Dmg) x 2.0` every levels (13) and
* `Def x 4 ⟹ (1/Dmg) x 2.5` every levels (16).

A lot of `(X) x (fx) ⟹ (y=Y(x)) x (fy)`.
How do we deal with this?
What proportion do we set?
Generally...
How to make `T( fx*X ) = fy*T(X)`?

A way to do it is `T(X) = X^log_fx(fy)`.

\\$T(fx\*X)=(fx\*X)^{\log\_{fx}fy}=fy\*X^{\log\_{fx}fy}=fy\*T(X)\\$.

Then we have to choose `power Atk^1.23` or `power Atk^1.22` or `power Atk^1.21` and `power Def^0.58` or `power Def^0.63` or `power Def^0.66`.

But... why `fx = 2, 3, 4...` criterion?
Why not `fx = 1/2, 1/3, 1/4...`? Or... `fx⟶1`?

\\$Taylor:\ \ Y(X+ΔX)=Y(X)+\frac{d}{dX}Y(X)\*ΔX+O(ΔX^2)\\$
\\$Defin:\ \ ΔX=(fx-1)\*X\\$
\\$Y(fx\*X)=Y(X)+\frac{d}{dX}Y(X)\*(fx-1)\*X+O((fx-1)^2)\\$

\\$Defin:\ \ Y(fx\*X)=fy\*Y(X)\\$
\\$fy=1+\frac{d}{dX}Y(X)\*(fx-1)\*\frac{X}{Y(X)}+O((fx-1)^2)\\$
\\$\lim\limits\_{fx\to1}{log\_{fx}fy}=\frac{X}{Y(X)}\*\frac{d}{dX}Y(X)\\$

So we can use pontual formula `power x^( x * Y'(x) / Y(x) )`.

Maybe it works even in varying amounts across the levels (but I don't know). If `X=Atk & Y=Dmg` then `power Atk^1.25`. If `X=Def & Y=1/Dmg` then `power Def^0.5`. Finally, we can compare characters power with the proportion `power Hp * Atk^1.25 * Def^0.5` in the example context and we can call the proportion relative power (`RelativePower = Hp * Atk^1.25 * Def^0.5`).

### Power and Xp

It's expected that enemy xp reward is proportional to the power (yeah, `2x` difficulty is `2x` reward), but

1. enemies can give more/less xp and balanced more/less other things (quality items for example) therefore expected value is only a base,
2. the values magnitudes can be greater/lesser than the preferred by design or technical details (means that the final formula can be one of many),
3. the amount can be willfully unbalanced as part of challenge and
4. some rate of unbalance can be permissible or unnoticed,

so it may be convenient set parameters and find the formula that meets arguments conditions. I propose some data and utility for it.

Ideally `XpReward RelativePower` therefore `XpReward = SomeConstant * RelativePower`, but can be `XpReward = SomeConstant * ( RelativePower ^ SomeExpoent )`. In other words, a manner to keep same reward factor for each same relative power factor results is apply a expoent (better close to one, higher incites stronger enemies and lower induces weaker searching) on relative power.

Back to the example. The average relative power per level is

\\$RelativePower ≈ (8+2Lv)^2\*(((4+Lv)^2)^{1.25})\*\sqrt{4+Lv} \space = \space 4\*(4+Lv)^5\\$

thus

\\$XpReward \space = \space SomeConstant\*RelativePower^{SomeExpoent}\\$ \\$XpReward \space ≈ \space SomeConstant\*( 4\*(4+Lv)^5 )^{SomeExpoent}\\$.

Best is `SomeExpoent=1`. If `C=SomeConstant*4` and `E=5*SomeExpoent` then best is `E=5` and

\\$XpReward \space ≈ \space C\*(4+Lv)^E\\$.

If `E=5` and `C=0.0032` then `XpReward = C*(4+Lv)^E ⇒ 10, 24.9, 53.8, 104.9, 189, 320, 515.4, 796.3, 1188.1, 1721}` but if you want rewards from 20 to 3000 uses `E≈4.8665` and `C≈1/126.0383` (with that approachs the sequency is `20, 48.6, 102.8, 197, 349.4, 583.4, 927.8, 1416.9, 2091.7, 3000.1`).

We has a lot of ways to define the formula. A important data to do it is initial xp reward (to set initial values magnitudes of xp) and new formula can be

\\$XpReward=XpReward\_{Initial}\*(RelativePower/RelativePower\_{Initial})^{SomeExpoent}\\$

that uses `C = InitialXpReward/( InitialRelativePower^SomeExpoent )` and must solve to find expoent. We can set `SomeExpoent=1`. We can find value that set a reward condition. We can postpone the solution to set by a total xp condition (or level up xp condition). When solve `SomeExpoent` variable we have specific mean leveled xp reward to bases specific rewards in game.

# Set Total Xp

We know that

\\$LevelUpXp(Lv) = TotalXp(Lv+1) - TotalXp(Lv)\\$

\\$TotalXp(Lv+1) = TotalXp(Lv) + LevelUpXp(Lv)\\$

therefore

\\$TotalXp(Lv)=TotalXp(InitialLv)+LevelUpXp(InitialLv)\\$ \\$+LevelUpXp(InitialLv+1)+...+ LevelUpXp(Lv-1)\\$.

The total xp table and progression speed depends on each level up xp. Level up xp depends on data that we have, then the point is the level up xp. Usually it's defined by

\\$LevelUpXp = ExpectedTimeToLevelUp * MeanXpGainPerTimeUnit\\$.

Since `MeanXpGainPerTimeUnit = MeanXpReward / MeanRewardTime` and `ExpectedTimeToLevelUp = LevelUpRewards * MeanRewardTime`, it gives us the onus of set

\\$LevelUpRewards = ExpectedTimeToLevelUp / MeanRewardTime\\$

properly (also consider `LevelUpRewards = LevelUpEnemies` and its equivalences with quests, missions, items, equips bonus, performance bonus) and apply to

\\$LevelUpXp = LevelUpRewards * MeanXpReward\\$

from initial level to final but one level. Yup, we don't need final level data.

If levels are from 1 to 10, initial total xp is zero, mean enemy xp sequence is `10, 24.9, 53.8, 104.9, 189, 320, 515.4, 796.3, 1188.1` (levels from 1 to 9) and level up enemies sequence is `1, 5, 20, 60, 120, 180, 240, 300, 300` (levels from 1 to 9 and values from `LevelUpEnemies` question example formula) then level up xp sequence is `10, 124.5, 1076, 6294, 22680, 57600, 123696, 238890, 356430` (levels from 1 to 9) and total xp sequence is `0, 10, 134.5, 1210.5, 7504.5, 30184.5, 87784.5, 211480.5, 450370.5, 806800.5` (levels from 1 to 10).

But if we includes the xp bonus sequence `0%, 0%, 0%, 5%, 10%, 15%, 20%, 25%, 25%` then mean enemy xp sequence is `10, 24.9, 53.8, 110.1, 207.9, 368, 618.5, 995.4, 1485.1`, level up xp sequence is `10, 124.5, 1076, 6606, 24948, 66240, 148440, 298620, 445530` (levels from 1 to 9) and total xp sequence is `0, 10, 134.5, 1210.5, 7816.5, 32764.5, 99004.5, 247444.5, 546064.5, 991594.5` (levels from 1 to 10).

But...
When we don't set `E`...
What will we do?

If `E` is unset then is because we decided to set using a xp condition, for example `TotalXp(10)=1000000`. Yeah, you know, `TotalXp(10) = LevelUpRewards(9) * MeanXpReward(9) + LevelUpRewards(8) * MeanXpReward(8) + ... + LevelUpRewards(2) * MeanXpReward(2) + LevelUpRewards(1) * MeanXpReward(1)` (initial level is one) and each `MeanXpReward(?)` is (not defined value but) a formula with `E` variable as power expoent to solve.

A root finder method (like secants, newton, halley) can find `E` that `E -> TotalXp(10)-1000000` is zero (`E≈5.2457` with no bonus or `E≈5.0097` with bonus) and tables building is possible. Using xp bonus example with `E=5.0097` (inexact), mean enemy xp sequence is `10, 24.9, 54, 110.6, 209, 370.5, 623.2, 1003.8, 1499`, level up xp sequence is `10, 124.5, 1080, 6636, 25080, 66690, 149568, 301140, 449700` (levels from 1 to 9) and total xp sequence is `0, 10, 134.5, 1214.5, 7850.5, 32930.5, 99620.5, 249188.5, 550328.5, 1000028.5` (levels from 1 to 10).

### Rounding Tables Values

You saw not integer values and can simply round each one (digits of your choice) but need caution because it modifies the tables with no previously addressed criteria.

For example, if `TotalXp(6) = 32930.5`, `TotalXp(7) = 99620.5` and `MeanXpReward(6) = 370.5` then `LevelUpRewards(6) = (99620.5-32930.5)/370.5 = 180` but if modify `TotalXp(6) = 30000` and `TotalXp(7) = 100000` then `LevelUpRewards(6) = (100000-30000)/370.5 = 188.9` (about 5% difference, can be worse).

A extreme case is `TotalXp(59) = 834776.7`, `TotalXp(60) = 915416.7` and `TotalXp(61) = 1003364.4`. If rounds to nearest integer then `TotalXp(59) = 834777`, `TotalXp(60) = 915417` and `TotalXp(61) = 1003364` thus `LevelUpXp(59) = 80640` and `LevelUpXp(60) = 87947`. If rounds to nearest multiple of 10000 then `TotalXp(59) = 830000`, `TotalXp(60) = 920000` and `TotalXp(61) = 1000000` thus `LevelUpXp(59) = 90000` and `LevelUpXp(60) = 80000` (yes, needed xp to level up down from `90000` to `80000` on grow from level `59` to `60`, it's a crescent level up xp breaking).

The xp tables often manifest a air of normality properties like `0 < LevelUpXp(Lv) < LevelUpXp(Lv+1)` (I never saw not manifest this), `2*LevelUpXp(Lv) < LevelUpXp(Lv-1) + LevelUpXp(Lv+1)` (rarely not manifest) and `LevelUpXp(Lv)^2 > LevelUpXp(Lv-1) * LevelUpXp(Lv+1)` (not so rarely not manifest). The challenge is to make a algorithm that rounds until can't do it with no property crash (conserve present property).

The unique way that I think that does it is to repetitively

* select a level,
* see the holded properties on it and neighbords,
* does a rounding,
* see if it breaks some property and
* decide to keep rounded or revert it.

All values can start rounded to near integer and get more digits to round when algorithm is running. Selection can be a crescent level loop or decrescent (I don't know what is the best) and a extern loop can continue it until don't find more roundings to do.

# Code And Test

I coded in C++ (incomplete) here: https://ideone.com/Vgvh0U. I like the results for now. After that I coded in Maple 15 with more satisfactory features. Maple code shown below. I intend to code in Java with graphic interface but I don't guarantee post here. Did you see that I called hardness the relative power (to simplify)?

As code...

```
BuildXpTables := proc ({ InLv::posint := 1, InTotalXp::nonnegint := 0, RoundDivisor::posint := 1, RoundOffError%::numeric := 0, InCond::`=` := RewXpFct = 10, FinCond := RewXpExp = 1, ExHardnessSeq::(nonemptylist(positive)) := [seq(32e-5*(4+_tmp)^5, _tmp = 1 .. 9)], ExRewsToLvUpSeq::(nonemptylist(positive)) := [seq(60*(2/factorial(max(1, 6-_tmp))+min(max(_tmp-5, 0), 3)), _tmp = 1 .. nops(ExHardnessSeq)-1)], ExRewXpPosBonAndPen::procedure := ((Lv, ExRewXp) -> ExRewXp) })
    local h, c, w, r, n, u, p, v, a, b, e, f, i, l, m, t, d, x;
    h, c := sort(ExHardnessSeq), 1-InLv;
    w := unapply(ExRewXpPosBonAndPen(l, f*piecewise(cat(``, "nargs") = 1, h[l+c], a)^e), l, a);
    r := sort(ExRewsToLvUpSeq);  n := nops(r);  u := unapply(r[min(i, n)]*w(i-c), i);
    p := unapply(InTotalXp+('add')(u(t), t = 1 .. i-1), i);
    v := unapply(('eval')(t, fsolve(eval({InCond, FinCond}, {ExRewXp = w, LvUpXp = u, TotalXp = p, 'RewXpExp' = e, 'RewXpFct' = f}))), t);
    d := [RoundDivisor];
    x := (t -> proc (i, d) t[i] end proc)((proc ()
        n := nops(h); 0; [InTotalXp]; while `%%` < n do d := [d[], d[-1]]; `%%%`+1; [`%%%`[], `%%%`[-1]+v(u(%))] end do;
        p, r := proc (j) piecewise(i = j, m*d[j], d[j]); round(x(j)/%)*% end proc, proc (i) round(x(i)/d[i])*d[i] end proc;
        return `%%` end proc
    )());
    for m in 10, 5, 2 do b := true; while b do b := false; for i from n+1 by -1 to 1 do if (proc (e, i, m)
        local t, a, f, s, u; a := 0; f := i; s := i; u := proc ()
            local t;
            a, f, s := a+1, min(n, f)+1, max(s-1, 1);
            return [seq(t .. t+a, t = s .. f-a)]
        end proc;
        max(x(i), 1e-999999); abs(p(i)-%); if `not`(% <= `%%`*e or % < abs(r(i)-`%%`)) then return false end if;
        u();
        if % = [] then return true end if;
        for t in % do
            p(rhs(t))-p(lhs(t));
            if % < 1 then return false end if;
            x(rhs(t))-x(lhs(t));
            abs(`%%`-%);
            if `not`(% <= `%%`*e or % < abs(r(rhs(t))-r(lhs(t))-`%%`)) then
                return false
            end if
        end do;
        u();
        if % = [] then return true end if;
        for t in % do
            `~`[p]([seq(t)]);
            %[3]-2*%[2]+%[1];
            if `not`(0 <= % or r(rhs(t))-2*r(rhs(t)-1)+r(lhs(t)) < %) then
                return false
            end if
        end do;
        u();
        if % = [] then return true end if;
        for t in % do
            `~`[p]([seq(t)]);
            if `not`(0 <= %[4]-3*%[3]+3*%[2]-%[1] or r(rhs(t))-3*r(rhs(t)-1)+3*r(rhs(t)-2)-r(lhs(t)) < 0) then
                return false
            end if;
            (%[3]-%[2])^2-(%[4]-%[3])*(%[2]-%[1]);
            if `not`(0 <= % or (r(rhs(t)-1)-r(rhs(t)-2))^2-(r(rhs(t))-r(rhs(t)-1))*(r(rhs(t)-2)-r(lhs(t))) < 0) then
                return false
            end if
        end do;
        return true end proc
    )(0.01*RoundOffError%, i, m) then b, d[i] := true, d[i]*m end if end do end do end do;
    `~`[r]([seq(1 .. n+1)], d); %[2 .. ()]-%[() .. -2], `~`[v](`~`[w]([seq(InLv .. n-c)]));
    Levels = InLv .. InLv+n, Table[TotalXp] = `%%`, Table[LevelUpXp] = %[1];
    return unapply(('eval')(cat(``, "args"), [%, Table[ExRewsToLvUp] = `~`[`/`](`%%`[1], `%%`[2]), Table[ExRewXp] = `%%`[2], ExRewXp = v(w(Lv, Hardness))]))
end proc

```

All parameters have standard arguments.

* `InLv (1)` = initial character level,
* `InTotalXp (0)` = initial character total xp,
* `RoundDivisor (1)` --\> all levels character total xp is multiple of it,
* `RoundOffError% (0%)` --\> round divisor only grows if it don't break relative error limit,
* `InCond (RewXpFct=10)` = first equation to find `SomeConstant (RewXpFct)` and `SomeExpoent (RewXpExp)` with fsolve procedure (can use `RewXpFct`, `RewXpExp`, `TotalXp(Lv)`, `LvUpXp(Lv)` and `ExRewXp(Lv)`, recommended `RewXpFct` or low `Lv`),
* `FinCond (RewXpExp=1)` = second equation to find `SomeConstant` and `SomeExpoent` with fsolve procedure (can use `RewXpFct`, `RewXpExp`, `TotalXp(Lv)`, `LvUpXp(Lv)` and `ExRewXp(Lv)`, recommended `RewXpExp` or high `Lv`),
* `ExHardnessSeq ([1.00000, 2.48832, 5.37824, 10.48576, 18.89568, 32.00000, 51.53632, 79.62624, 118.81376])` = challenge relative power sequence (standard is the example sequence),
* `ExRewsToLvUpSeq ([1, 5, 20, 60, 120, 180, 240, 300, 300])` = number of rewards to level up sequence (standard is the example sequence),
* `ExRewXpPosBonAndPen ((Lv, ExRewXp) -> ExRewXp)` = final reward xp after calculate bonuses and penalties effects.

The procedure returns other procedure that applies eval on argument with `Levels = InLv..FinLv`, rounded `Table[TotalXp]`, `Table[LevelUpXp]` from rounded total xp, `Table[ExRewsToLvUp]` from rounded level up xp and reward xp table, `Table[ExRewXp]` and formula `ExRewXp`. The rounding process verify if round divisor rising make some present property in some near level be absent on same level. I can make optional specific properties keeping but I haven't done that yet.

Using all standard arguments except `RoundOffError = 0.5%` and `ExRewXpPosBonAndPen = (Lv, ExRewXp) -> ExRewXp * [1.00, 1.00, 1.00, 1.05, 1.10, 1.15, 1.20, 1.25, 1.25][Lv])` the procedure returns it.

When `InCond = (TotalXp(2)=10)` or `InCond = (LvUpXp(1)=10)` or `InCond = (ExRewXp(1)=10)` replaces standard argument the result is the same thing. Like the examples, if `FinCond = (TotalXp(10)=1000000)` then that happens.

Finally a great test. The code

prints it.

```
Lv   1 | Xp          0 | LvUpXp         5 | LvUpXpGrow x 3.000000 | RewXp       5.6 | LvUpRews    0.891
Lv   2 | Xp          5 | LvUpXp        15 | LvUpXpGrow x 2.333333 | RewXp       6.8 | LvUpRews    2.205
Lv   3 | Xp         20 | LvUpXp        35 | LvUpXpGrow x 2.000000 | RewXp       8.2 | LvUpRews    4.251
Lv   4 | Xp         55 | LvUpXp        70 | LvUpXpGrow x 1.714286 | RewXp       9.9 | LvUpRews    7.038
Lv   5 | Xp        125 | LvUpXp       120 | LvUpXpGrow x 1.541667 | RewXp      12.0 | LvUpRews   10.006
Lv   6 | Xp        245 | LvUpXp       185 | LvUpXpGrow x 1.432432 | RewXp      14.4 | LvUpRews   12.814
Lv   7 | Xp        430 | LvUpXp       265 | LvUpXpGrow x 1.358491 | RewXp      17.4 | LvUpRews   15.273
Lv   8 | Xp        695 | LvUpXp       360 | LvUpXpGrow x 1.333333 | RewXp      20.8 | LvUpRews   17.293
Lv   9 | Xp       1055 | LvUpXp       480 | LvUpXpGrow x 1.239583 | RewXp      24.9 | LvUpRews   19.249
Lv  10 | Xp       1535 | LvUpXp       595 | LvUpXpGrow x 1.201681 | RewXp      29.8 | LvUpRews   19.950
Lv  11 | Xp       2130 | LvUpXp       715 | LvUpXpGrow x 1.188811 | RewXp      35.6 | LvUpRews   20.077
Lv  12 | Xp       2845 | LvUpXp       850 | LvUpXpGrow x 1.188235 | RewXp      42.5 | LvUpRews   20.018
Lv  13 | Xp       3695 | LvUpXp      1010 | LvUpXpGrow x 1.183168 | RewXp      50.5 | LvUpRews   19.980
Lv  14 | Xp       4705 | LvUpXp      1195 | LvUpXpGrow x 1.200837 | RewXp      60.1 | LvUpRews   19.887
Lv  15 | Xp       5900 | LvUpXp      1435 | LvUpXpGrow x 1.177700 | RewXp      71.3 | LvUpRews   20.119
Lv  16 | Xp       7335 | LvUpXp      1690 | LvUpXpGrow x 1.183432 | RewXp      84.5 | LvUpRews   19.990
Lv  17 | Xp       9025 | LvUpXp      2000 | LvUpXpGrow x 1.182500 | RewXp     100.1 | LvUpRews   19.986
Lv  18 | Xp      11025 | LvUpXp      2365 | LvUpXpGrow x 1.181818 | RewXp     118.3 | LvUpRews   19.995
Lv  19 | Xp      13390 | LvUpXp      2795 | LvUpXpGrow x 1.177102 | RewXp     139.6 | LvUpRews   20.019
Lv  20 | Xp      16185 | LvUpXp      3290 | LvUpXpGrow x 1.177812 | RewXp     164.6 | LvUpRews   19.990
Lv  21 | Xp      19475 | LvUpXp      3875 | LvUpXpGrow x 1.175484 | RewXp     193.8 | LvUpRews   20.000
Lv  22 | Xp      23350 | LvUpXp      4555 | LvUpXpGrow x 1.174533 | RewXp     227.8 | LvUpRews   19.995
Lv  23 | Xp      27905 | LvUpXp      5350 | LvUpXpGrow x 1.172897 | RewXp     267.5 | LvUpRews   20.001
Lv  24 | Xp      33255 | LvUpXp      6275 | LvUpXpGrow x 1.171315 | RewXp     313.7 | LvUpRews   20.003
Lv  25 | Xp      39530 | LvUpXp      7350 | LvUpXpGrow x 1.169388 | RewXp     367.4 | LvUpRews   20.003
Lv  26 | Xp      46880 | LvUpXp      8595 | LvUpXpGrow x 1.169284 | RewXp     429.9 | LvUpRews   19.995
Lv  27 | Xp      55475 | LvUpXp     10050 | LvUpXpGrow x 1.166667 | RewXp     502.3 | LvUpRews   20.009
Lv  28 | Xp      65525 | LvUpXp     11725 | LvUpXpGrow x 1.165458 | RewXp     586.2 | LvUpRews   20.002
Lv  29 | Xp      77250 | LvUpXp     13665 | LvUpXpGrow x 1.164288 | RewXp     683.4 | LvUpRews   19.997
Lv  30 | Xp      90915 | LvUpXp     15910 | LvUpXpGrow x 1.163734 | RewXp     795.7 | LvUpRews   19.995
Lv  31 | Xp     106825 | LvUpXp     18515 | LvUpXpGrow x 1.161761 | RewXp     925.5 | LvUpRews   20.006
Lv  32 | Xp     125340 | LvUpXp     21510 | LvUpXpGrow x 1.159926 | RewXp    1075.2 | LvUpRews   20.006
Lv  33 | Xp     146850 | LvUpXp     24950 | LvUpXpGrow x 1.159319 | RewXp    1247.8 | LvUpRews   19.995
Lv  34 | Xp     171800 | LvUpXp     28925 | LvUpXpGrow x 1.158168 | RewXp    1446.5 | LvUpRews   19.996
Lv  35 | Xp     200725 | LvUpXp     33500 | LvUpXpGrow x 1.156716 | RewXp    1675.1 | LvUpRews   19.999
Lv  36 | Xp     234225 | LvUpXp     38750 | LvUpXpGrow x 1.155484 | RewXp    1937.8 | LvUpRews   19.997
Lv  37 | Xp     272975 | LvUpXp     44775 | LvUpXpGrow x 1.155221 | RewXp    2239.4 | LvUpRews   19.995
Lv  38 | Xp     317750 | LvUpXp     51725 | LvUpXpGrow x 1.152731 | RewXp    2585.2 | LvUpRews   20.008
Lv  39 | Xp     369475 | LvUpXp     59625 | LvUpXpGrow x 1.152201 | RewXp    2981.5 | LvUpRews   19.999
Lv  40 | Xp     429100 | LvUpXp     68700 | LvUpXpGrow x 1.151383 | RewXp    3435.1 | LvUpRews   20.000
Lv  41 | Xp     497800 | LvUpXp     79100 | LvUpXpGrow x 1.149178 | RewXp    3953.8 | LvUpRews   20.006
Lv  42 | Xp     576900 | LvUpXp     90900 | LvUpXpGrow x 1.149065 | RewXp    4546.5 | LvUpRews   19.994
Lv  43 | Xp     667800 | LvUpXp    104450 | LvUpXpGrow x 1.147918 | RewXp    5223.0 | LvUpRews   19.998
Lv  44 | Xp     772250 | LvUpXp    119900 | LvUpXpGrow x 1.146372 | RewXp    5994.6 | LvUpRews   20.001
Lv  45 | Xp     892150 | LvUpXp    137450 | LvUpXpGrow x 1.145871 | RewXp    6873.8 | LvUpRews   19.996
Lv  46 | Xp    1029600 | LvUpXp    157500 | LvUpXpGrow x 1.144762 | RewXp    7874.8 | LvUpRews   20.001
Lv  47 | Xp    1187100 | LvUpXp    180300 | LvUpXpGrow x 1.143095 | RewXp    9013.4 | LvUpRews   20.004
Lv  48 | Xp    1367400 | LvUpXp    206100 | LvUpXpGrow x 1.142649 | RewXp   10307.4 | LvUpRews   19.995
Lv  49 | Xp    1573500 | LvUpXp    235500 | LvUpXpGrow x 1.142251 | RewXp   11776.9 | LvUpRews   19.997
Lv  50 | Xp    1809000 | LvUpXp    269000 | LvUpXpGrow x 1.140149 | RewXp   13444.2 | LvUpRews   20.009
Lv  51 | Xp    2078000 | LvUpXp    306700 | LvUpXpGrow x 1.139550 | RewXp   15334.4 | LvUpRews   20.001
Lv  52 | Xp    2384700 | LvUpXp    349500 | LvUpXpGrow x 1.138913 | RewXp   17475.6 | LvUpRews   19.999
Lv  53 | Xp    2734200 | LvUpXp    398050 | LvUpXpGrow x 1.137420 | RewXp   19899.3 | LvUpRews   20.003
Lv  54 | Xp    3132250 | LvUpXp    452750 | LvUpXpGrow x 1.136941 | RewXp   22640.4 | LvUpRews   19.997
Lv  55 | Xp    3585000 | LvUpXp    514750 | LvUpXpGrow x 1.135891 | RewXp   25738.2 | LvUpRews   19.999
Lv  56 | Xp    4099750 | LvUpXp    584700 | LvUpXpGrow x 1.134855 | RewXp   29236.3 | LvUpRews   19.999
Lv  57 | Xp    4684450 | LvUpXp    663550 | LvUpXpGrow x 1.134805 | RewXp   33183.6 | LvUpRews   19.996
Lv  58 | Xp    5348000 | LvUpXp    753000 | LvUpXpGrow x 1.132537 | RewXp   37634.3 | LvUpRews   20.008
Lv  59 | Xp    6101000 | LvUpXp    852800 | LvUpXpGrow x 1.132387 | RewXp   42649.0 | LvUpRews   19.996
Lv  60 | Xp    6953800 | LvUpXp    965700 | LvUpXpGrow x 1.131821 | RewXp   48295.0 | LvUpRews   19.996
Lv  61 | Xp    7919500 | LvUpXp   1093000 | LvUpXpGrow x 1.130375 | RewXp   54647.2 | LvUpRews   20.001
Lv  62 | Xp    9012500 | LvUpXp   1235500 | LvUpXpGrow x 1.130312 | RewXp   61788.8 | LvUpRews   19.996
Lv  63 | Xp   10248000 | LvUpXp   1396500 | LvUpXpGrow x 1.128894 | RewXp   69812.3 | LvUpRews   20.004
Lv  64 | Xp   11644500 | LvUpXp   1576500 | LvUpXpGrow x 1.128449 | RewXp   78820.3 | LvUpRews   20.001
Lv  65 | Xp   13221000 | LvUpXp   1779000 | LvUpXpGrow x 1.127038 | RewXp   88926.6 | LvUpRews   20.005
Lv  66 | Xp   15000000 | LvUpXp   2005000 | LvUpXpGrow x 1.126683 | RewXp  100257.5 | LvUpRews   19.998
Lv  67 | Xp   17005000 | LvUpXp   2259000 | LvUpXpGrow x 1.125719 | RewXp  112952.9 | LvUpRews   19.999
Lv  68 | Xp   19264000 | LvUpXp   2543000 | LvUpXpGrow x 1.124853 | RewXp  127167.5 | LvUpRews   19.997
Lv  69 | Xp   21807000 | LvUpXp   2860500 | LvUpXpGrow x 1.124803 | RewXp  143072.7 | LvUpRews   19.993
Lv  70 | Xp   24667500 | LvUpXp   3217500 | LvUpXpGrow x 1.123543 | RewXp  160858.2 | LvUpRews   20.002
Lv  71 | Xp   27885000 | LvUpXp   3615000 | LvUpXpGrow x 1.122822 | RewXp  180733.4 | LvUpRews   20.002
Lv  72 | Xp   31500000 | LvUpXp   4059000 | LvUpXpGrow x 1.121828 | RewXp  202929.7 | LvUpRews   20.002
Lv  73 | Xp   35559000 | LvUpXp   4553500 | LvUpXpGrow x 1.121665 | RewXp  227702.8 | LvUpRews   19.998
Lv  74 | Xp   40112500 | LvUpXp   5107500 | LvUpXpGrow x 1.120411 | RewXp  255334.7 | LvUpRews   20.003
Lv  75 | Xp   45220000 | LvUpXp   5722500 | LvUpXpGrow x 1.120140 | RewXp  286136.3 | LvUpRews   19.999
Lv  76 | Xp   50942500 | LvUpXp   6410000 | LvUpXpGrow x 1.118955 | RewXp  320450.5 | LvUpRews   20.003
Lv  77 | Xp   57352500 | LvUpXp   7172500 | LvUpXpGrow x 1.118508 | RewXp  358655.1 | LvUpRews   19.998
Lv  78 | Xp   64525000 | LvUpXp   8022500 | LvUpXpGrow x 1.117794 | RewXp  401165.7 | LvUpRews   19.998
Lv  79 | Xp   72547500 | LvUpXp   8967500 | LvUpXpGrow x 1.117647 | RewXp  448440.2 | LvUpRews   19.997
Lv  80 | Xp   81515000 | LvUpXp  10022500 | LvUpXpGrow x 1.116238 | RewXp  500981.9 | LvUpRews   20.006
Lv  81 | Xp   91537500 | LvUpXp  11187500 | LvUpXpGrow x 1.115531 | RewXp  559344.2 | LvUpRews   20.001
Lv  82 | Xp  102725000 | LvUpXp  12480000 | LvUpXpGrow x 1.115385 | RewXp  624135.1 | LvUpRews   19.996
Lv  83 | Xp  115205000 | LvUpXp  13920000 | LvUpXpGrow x 1.114583 | RewXp  696022.4 | LvUpRews   19.999
Lv  84 | Xp  129125000 | LvUpXp  15515000 | LvUpXpGrow x 1.114083 | RewXp  775739.2 | LvUpRews   20.000
Lv  85 | Xp  144640000 | LvUpXp  17285000 | LvUpXpGrow x 1.112815 | RewXp  864089.7 | LvUpRews   20.004
Lv  86 | Xp  161925000 | LvUpXp  19235000 | LvUpXpGrow x 1.112685 | RewXp  961955.7 | LvUpRews   19.996
Lv  87 | Xp  181160000 | LvUpXp  21402500 | LvUpXpGrow x 1.112370 | RewXp 1070303.8 | LvUpRews   19.997
Lv  88 | Xp  202562500 | LvUpXp  23807500 | LvUpXpGrow x 1.111204 | RewXp 1190193.0 | LvUpRews   20.003
Lv  89 | Xp  226370000 | LvUpXp  26455000 | LvUpXpGrow x 1.110754 | RewXp 1322782.8 | LvUpRews   20.000
Lv  90 | Xp  252825000 | LvUpXp  29385000 | LvUpXpGrow x 1.110430 | RewXp 1469342.3 | LvUpRews   19.999
Lv  91 | Xp  282210000 | LvUpXp  32630000 | LvUpXpGrow x 1.109409 | RewXp 1631259.8 | LvUpRews   20.003
Lv  92 | Xp  314840000 | LvUpXp  36200000 | LvUpXpGrow x 1.109116 | RewXp 1810053.4 | LvUpRews   19.999
Lv  93 | Xp  351040000 | LvUpXp  40150000 | LvUpXpGrow x 1.108344 | RewXp 2007382.5 | LvUpRews   20.001
Lv  94 | Xp  391190000 | LvUpXp  44500000 | LvUpXpGrow x 1.108090 | RewXp 2225059.7 | LvUpRews   19.999
Lv  95 | Xp  435690000 | LvUpXp  49310000 | LvUpXpGrow x 1.107280 | RewXp 2465064.5 | LvUpRews   20.004
Lv  96 | Xp  485000000 | LvUpXp  54600000 | LvUpXpGrow x 1.106227 | RewXp 2729557.3 | LvUpRews   20.003
Lv  97 | Xp  539600000 | LvUpXp  60400000 | LvUpXpGrow x 1.655629 | RewXp 3020895.5 | LvUpRews   19.994
Lv  98 | Xp  600000000 | LvUpXp 100000000 | LvUpXpGrow x 3.000000 | RewXp 3341649.8 | LvUpRews   29.925
Lv  99 | Xp  700000000 | LvUpXp 300000000 | LvUpXpGrow x infinity | RewXp 3694622.2 | LvUpRews   81.199
Lv 100 | Xp 1000000000 | LvUpXp  infinity | LvUpXpGrow x infinity | RewXp  infinity | LvUpRews infinity

```

---
Tags: mathematics, game-design, algorithm, progression
---


# Question
Title: Design pattern for menu transitions in C# (Unity)
I am working on my first project in Unity using C# and I am currently trying to design a menu system that does the following sequence of events when a user clicks a button:

1. Button does some effect for some milliseconds (for example, flashes)
2. Menu1 does its closing sequence for some milliseconds (for example, buttons fly off screen)
3. Menu2 does its opening sequence for some milliseconds (for example, buttons fly on screen)

The exact animations of the UI elements don't matter for the purpose of my question.

So far, the only design pattern I've found to achieve this kind of sequence is by using coroutines. So I ended up with something like the following:

```
void OnStartButtonClick()
{
    StartCoroutine(_OnStartButtonClick());
}

IEnumerator _OnStartButtonClick()
{
    yield return start_button.GetComponent<ButtonController>().DoEffect();
    StartCoroutine(MenuTransition(main_menu, data_menu));
}

IEnumerator MenuTransition(GameObject menu1, GameObject menu2)
{
    // main menu to data select
    if (menu1 == main_menu && menu2 == data_menu)
    {
        yield return CloseMainMenu();
        yield return OpenDataMenu();
    }
}

public Coroutine OpenMainMenu()
{
    return StartCoroutine(_OpenMainMenu());
}

IEnumerator _OpenMainMenu()
{
    main_menu.SetActive(true);
    // main menu opening sequence here
    yield return null;
}

public Coroutine CloseMainMenu()
{
    return StartCoroutine(_CloseMainMenu());
}

IEnumerator _CloseMainMenu()
{
    // main menu closing sequence here
    main_menu.SetActive(false);
    yield return null;
}

public Coroutine OpenDataMenu()
{
    return StartCoroutine(_OpenDataMenu());
}

IEnumerator _OpenDataMenu()
{
    data_menu.SetActive(true);
    // open data menu sequence
    yield return null;
}

public Coroutine CloseDataMenu()
{
    return StartCoroutine(_CloseDataMenu());
}

IEnumerator _CloseDataMenu()
{
    // data menu closing sequence here
    data_menu.SetActive(false);
    yield return null;
}

```

And the code on my button likewise utilizes coroutines:

```
public Coroutine DoEffect()
{
    return StartCoroutine(_DoEffect());
}

IEnumerator _DoEffect()
{
    // imagine some code that does the effect
    yield return new WaitForSeconds(1f);
}

```

This seems to work well enough and allows me to completely control the effect--\>close--\>open sequence. But it's getting a bit unwieldy as I build it out for more menus and transitions between them, resulting in a ton of methods with Coroutine return type wrapping IEnumerators (which I've been prefixing with underscore). I can't help but feel like there's a more elegant way to do this, and that I am using coroutines as a crutch ...

**So my question is whether there is a more suitable or efficient design pattern that can allow me to achieve the kind of sequencing of events that I want without the proliferation of Coroutines & IEnumerators? Or are Coroutines & IEnumerators exactly the devices to solve this kind of problem?**

# Answer
The main thing you should change is not hardcoding references to specific menus.

```
public class Menu : MonoBehaviour {
    public IEnumerator Open() {
        //animation code here
    }
    public IEnumerator Close() {
        //animation code here
    }
}

IEnumerator MenuTransition(Menu menu1, Menu menu2)
{
    yield return StartCoroutine(menu1.Close());
    yield return StartCoroutine(menu2.Open());
}

```

The above solution lets us open and close any combination of menus without needing to write separate functions for each menu.
> 1 votes

---
Tags: unity, c#, animation, gui, coroutines
---


# Question
Title: Get all components from a GameObject? including children
i'm making an Enemy Death, and for that i need to get every CapsuleCollider2D from a specific GameObject, including all his children. What i'm trying to do is create an Array, which every capsule collider, and then destroy everyone when the enemy dies. I've searched through several forums but i didn't got the key. Any help?

# Answer
> 1 votes
> What i'm trying to do is create an Array, which every capsule collider, and then destroy everyone when the enemy dies.

This is all you need:

```
var colliders = GetComponentsInChildren<Collider>();
foreach (var collider in colliders) {
    collider.enabled = false;
}

```

---
Tags: unity
---


title: Star glowing shader graph

text:
# Question
Title: Star glowing shader graph
How could I make a shader graph that makes spheres that look like on this image? I'm new to shaders and I don't know how to do this. Also, if it's possible I would like a property to change the glowing intensity

# Answer
So I know this is old, but a few weeks ago we found a solution and I think it would help some people to post it here. Using the VFX graph and the HYG database, it is possible to render hundreds of thousands of stars without any large performance impact. it works by encoding the stars into a texture. The RGB represents the position relative to the earth, and the alpha is the magnitude. Then, the graph read the texture and generate 2D stars. I am not taking credits for this solution, Glurth made 99% of it. This is just a part of the system, but an experienced programmer will be able to easily make the script.
> 1 votes

---
Tags: unity, shaders, graphic-effects, unity-shader-graph
---


# Question
Title: How can I generate roads such as those in the game Twisty Road?
Here is a link to see the gameplay: https://www.youtube.com/watch?v=03PzsgO-uAM

How could I procedurally generate the path upon which the ball rolls in Unity/C#?

I know I could model distinct pieces of the road in Blender and import them into Unity as prefabs. My problem is, I genuinely have no idea where to start when it comes to programmatically generating the whole road out of those prefab sections in a cohesive manner, such that the road is built seamlessly and randomly with twists and turns in three-dimensional space.

I would appreciate any insight you could provide. Thank you.

# Answer
So, there are a few ways to do this theoretically, but I'll detail the one that you've been presented with. Firstly, you'd come up with a system for separating the roads into pieces. In Twisty Road, it looked like there were some straight strips that didn't bend much. Those are ideal locations to join the "seams" of your road gameobjects. What you would need to do is create bendy road prefabs of reasonable length that begin and end with straight portions.

Programmatically, you store these prefabs in an array. If I were you, I would give these prefabs two child gameobjects. These children will be start and end hinges. Move them to the ends of your roads, and then you'll be able to link your roads together on the fly. In your map generator code, you Instantiate a random road. Then, you Instantiate a second one and set its START hinge transform.position to the same as the previous road's END hinge transform.position. Recursively do this however many times as you'd like and voila. You have your procedurally generated bendy road map.

You could even rework this to start building more roads as the player progresses to its like a never-ending road if you wanted.
> 1 votes

# Answer
I know this question is old but there is a Unity package called the Path Creator Tool that solves this same exact problem. You can check out how to use it here: https://www.youtube.com/watch?v=saAQNRSYU9k Consider becoming a Patreon to the guy that made this because this is a pretty complex tool and he was generous to make free for us all to use. Here's the creators Patreon page.
> 0 votes

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


# Question
Title: UE4 C++ - Add generated source code folders to Visual Studio solution?
In Unreal Engine 4, using a Visual Studio solution and projects generated from the Editor using the First Person Template, the layout of the Solution looks something like the following:

I am not a fan of this flat horizontal folder structure. What I would like to do is put some new classes into a nested folder here.

I will be generating a new `GameState` subclass, and putting the sources into the `Source\GameState` folder that will also be created on the fly, using the UE4 editor:

Notice that the "Create New Folder" option is disabled.

Here I have appended the "GameState" folder to the normal source path.

However, the folder structure in the Solution Folder has not changed, and nothing I try to do is working. The things I have tried to do so far include:

* Drag the folder into the solution from the file explorer
* Right Click \> Add \> Existing Item... (Which just results in the files appearing horizontally to the other files without the new folder I have created, also add as link is not an available option)
* Create a "Filter" (what the other folders appear to be) within Visual Studio. This results in the layout I desire, but I have to add the source code files to the filter manually which just copies them to the .vcxproj file directory. I end up not modifying the actual files I added.

How can I add this folder and it's files while keeping up with the original copies?

# Answer
> 1 votes
Answering this myself because I fought this problem for a couple of hours.

After the project has been first generated from within the Editor at:

File \> Generate Visual Studio Project Files

The option changes to

File \> Refresh Visual Studio Project

I found that the easiest, most effective, and I assume intended way to have the Solution Explorer layout match the actual file/folder structure is to use this to refresh the project. This will require a reboot of Visual Studio, which will also require a reboot of the editor if it's being debugged.

---
Tags: c++, unreal-4, visual-studio
---


# Question
Title: Stopping the texture2D from stretching in RawImage
I am working with a RawImage texture which is fully stretched, filling up the entire scene. I am using some code to download images from website and then show them on the RawImage, the code is simple, I use `WWW` to start a download, use `WWW.texture` as the Image I want to show in RawImage, I do `RawImage.texture = WWW.texture;` and then I get the image but the Image is getting scrteched, I don't want to stretch the image but just fill instead, Just like a windows Wallpaper setting. Not to stretch or tile the image but to just fill it. I tried an approach to rotate the image via code but that still leaves some stretching in the image, if I use a portrait image( height is greater than width) I rotate the image from showing in landscape mode(which you can imagine, stretches the image a lot) to portrait mode by using some pixel conversion code, nothing special. Some images are displayed ok, because they fit the native size of the scene but for some stretching occurs. Is it possible to completely remove this stretching? I am surprised Unity doesn't have an option for changing how a texture can be displayed in RawImage. Maybe I am missing something,

# Answer
> 0 votes
Answer by Esildor works nice, but it doesn't make it fit inside the Parent scene. It does fill it nicely, but chances are that you may find your RawImage.texture a bit cropped from all sided, so this adjusted method will let you keep the Image in a nice aspect ratio will fitting it inside the RawImage.

```
public static Vector2 SizeToParent(this RawImage image, float padding = 0) {
        float w = 0, h = 0;
        var parent = image.GetComponentInParent<RectTransform>();
        var imageTransform = image.GetComponent<RectTransform>();

        // check if there is something to do
        if (image.texture != null) {
            if (!parent) { return imageTransform.sizeDelta; } //if we don't have a parent, just return our current width;
            padding = 1 - padding;
            float ratio = image.texture.width / (float)image.texture.height;
            var bounds = new Rect(0, 0, parent.rect.width, parent.rect.height);
            if (Mathf.RoundToInt(imageTransform.eulerAngles.z) % 180 == 90) {
                //Invert the bounds if the image is rotated
                bounds.size = new Vector2(bounds.height, bounds.width);
            }
            //Size by height first
            h = bounds.height * padding;
            w = h * ratio;
            if (w > bounds.width * padding) { //If it doesn't fit, fallback to width;
                w = bounds.width * padding;
                h = w / ratio;
            }
        }
        imageTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, w);
        imageTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, h);
        return imageTransform.sizeDelta;
    }

```

# Answer
> 3 votes
Use native unity component: Use AspectRatioFilter on the gameObject containting the rawImage, and tweek parameters as you wish.

# Answer
> 1 votes
Found a topic on the Unity forum that it looks like it might be what you need. Here's a copy of the post:

Here's a handy little script I came up with, so you can tell any `RawImage` to fill its parent's `Rect`, while maintaining the aspect ratio of the src texture. It also supports percentage based padding, and images that have been rotated by 90 degree increments.

```
static class CanvasExtensions {
public static Vector2 SizeToParent(this RawImage image, float padding = 0) {
    var parent = image.transform.parent.GetComponentInParent<RectTransform>();
    var imageTransform = image.GetComponent<RectTransform>();
    if (!parent) { return imageTransform.sizeDelta; } //if we don't have a parent, just return our current width;
    padding = 1 - padding;
    float w = 0, h = 0;
    float ratio = image.texture.width / (float)image.texture.height;
    var bounds = new Rect(0, 0, parent.rect.width, parent.rect.height);
    if (Mathf.RoundToInt(imageTransform.eulerAngles.z) % 180 == 90) {
          //Invert the bounds if the image is rotated
          bounds.size = new Vector2(bounds.height, bounds.width);
    }
    //Size by height first
    h = bounds.height * padding;
    w = h * ratio;
    if (w > bounds.width * padding) { //If it doesn't fit, fallback to width;
        w = bounds.width * padding;
        h = w / ratio;
    }
    imageTransform.sizeDelta = new Vector2(w, h);
    return imageTransform.sizeDelta;
}
}

```

---
Tags: unity, image, scale, rotate
---


# Question
Title: Checking if player is grounded using tilemap collision detection
beginner here just trying to learn the basics. I was following this tutorial but I ran into some trouble. Heres a screenshot of unity

So the tutorial calls for tagging the terrain with "Grounded" and essentially checks if the 2D collision box for GroundCheck collides with anything with a "Grounded" tag using the Move2D and Grounded scripts below. Note that the Move2D script is a component of the Player gameobject.

**Move2D**

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

public class Move2D : MonoBehaviour
{
    public float movespeed = 5f;
    public float jumpforce = 10f;
    public bool isGrounded = false;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        Jump();
     Vector3 movement = new Vector3(Input.GetAxis("Horizontal"),0f, 0f);
     transform.position += movement * Time.deltaTime * movespeed;
    }
    void Jump(){
        if (Input.GetButtonDown("Jump") && isGrounded == true){
        gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, 5f), ForceMode2D.Impulse);
        }
    }
}

```

**Grounded.cs**

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

public class Grounded : MonoBehaviour
{
    public GameObject Player;
    // Start is called before the first frame update
    void Start()
    {
         Player = gameObject.transform.parent.gameObject;
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if(collision.collider.tag == "Ground")
        {
            Player.GetComponent<Move2D>().isGrounded = true;
            Debug.Log("test");
            print("GROUNDED");
        }
    }

    private void OnCollisionExit2D(Collision2D collision)
    {
        if(collision.collider.tag == "Ground")
        {
            Player.GetComponent<Move2D>().isGrounded = false;
        }
    }
}

```

The error I'm running into is that it appears unity isn't recognizing that the player has collided with the tilemap collision box, so the bool isGrounded is just perpetually false and the player is unable to jump. Any help would be appreciated!

EDIT: below are screenshots of configs of Grid, gound, and GroundCheck in that order

# Answer
> 2 votes
The middle screenshot is a duplication of the first, but assuming it is your grounded script, try to do the following changes.

1. First you should relocate your tilemap. Currently you have it on the grid (which will work) but if you really want it as a child of the grid. The grid does not need to be tagged with Ground. If it is a child of the grid, you can have a second tilemap with things like background, a third maybe with foreground. You get the point.
2. The grounded script should be on the player. Just place it on GroundedCheck. Fix the start method. Either you assign the Player in the editor OR load the player in your start method (if you load it from start, make it private)
3. It should work now but the character will hover over the ground. Your groundCheck should be marked isTrigger and your code should change from `OnCollisionEnter2D(Collision2D collision)` to `OnTriggerEnter2D(Collider2D other)`. collider can be deleted in the condition to `if(collision.tag == "Ground")`

---
Tags: unity, c#, collision-detection, tilemap
---


# Question
Title: How do I make my character attack on the side of the character that I click the LMB on (Unity)?
This is a top-down game, I guess I should also mention that the character is not centred on the screen and the attack should be in 4 different directions. The attack's direction should be based on which side of the character(up, down, left, right) that you click on(this should also be universal on the screen, the only deciding factor should be the character and the mouse). I really have no clue where to start on this problem.

# Answer
Unfortunately I can not provide you with a copy&paste code snippet, because too many details depend on how exactly you set up your scene. So I can only give you a few pointers of what you have to do and what tools you might use to do these things.

What you need to do is:

1. Find the pixel-position of the mouse cursor on the screen.
2. Convert it to a position in world space
3. Calculate the directional vector between player position and cursor position in world space
4. Convert that vector into a more simple up-down-left-right vector
5. Use that directional vector for your projectiles

**Step 1** is very simple. The `Input.mousePosition` property gives you the screen coordinates of the mouse cursor.

**Step 2** depends on how you set up your camera. When your camera uses orthographic projection, your world is 2d and the camera is looking straight at it, then the z-coordinate does not matter. That means you can just use the `Camera.main.ScreenToWorldPoint` method. But when you are using a perspective camera, then it gets a bit more complicated, because the position in world-space depends on the distance between the camera and the object the player is pointing at. You need to perform a raycast from the camera through the mouse cursor. Thankfully, there is a handy utility method for calculating that ray: `Camera.main.ScreenPointToRay(Input.mousePosition)`. You can then feed that ray into `Physics.Raycast` / `Physics2D.Raycast` to find the point the cursor is pointing at. Or when your game mechanics takes place on a 2D plane, you can store its definition in a `Plane` object and use the method `plane.Raycast` to find where the mouse-ray intersects that plane.

This, of course, all assumes that you have exactly one camera in your scene which is tagged as the "Main Camera". When this is not the case, then you of course need to specify which camera you want to use to translate its perspective to the game world. So you have to substitute `Camera.main` with the respective Camera component.

**Step 3** is again much more straight-forward:

```
Vector3 mouseDirection = (mouseCursorWorldPosition - player.transform.position).normalized

```

But now you got a vector which points in the exact direction. You said you only want up, down, left or right. So **step 4** would be to simplify that vector. This code snippet assumes that you set up your camera that x is the left-right axis and y the up-down axis. Again, there are other ways to do it, and if you did, you need to modify this accordingly.

```
Vector3 simpleShootingDirection = Vector3.zero;
if( Mathf.Abs(mouseDirection.y) > Mathf.Abs(mouseDirection.x)) {
    // we got a direction which is more up-down than left-right
    if(mouseDirection.y > 0) {
        simpleShootingDirection = Vector3.up;
    } else {
        simpleShootingDirection = Vector3.down;
    }
} else {
    // we got a direction which is more left-right than up-down
    if(mouseDirection.x > 0) {
        simpleShootingDirection = Vector3.right;
    } else {
        simpleShootingDirection = Vector3.left;
    }
}

```

And in **step 5**, you just need to apply that shooting direction to the projectiles. Now there are again at least a dozen different ways to make a projectile move through the game world in Unity. About half of them start with rotating the projectile into the shooting direction. Which you can do by simply changing the `transform.forward` property:

```
projectile.transform.forward = shootingDirection;

```

About the other half involve move the object by a vector, either directly by changing its position or indirectly by applying a velocity of force. But in any case, you need a vector which multiplies the direction vector by the desired speed/acceleration/force of the projectile:

```
projectileVector = shootingDirection * projectileSpeed

```
> 1 votes

---
Tags: unity, movement, combat
---


# Question
Title: Unity's Profiler doesn't specify which of my methods take how much time?
I'm working on a **map generator**, which is used in **Awake()**, so I couldn't see it in the profiler.

So I created a **new scene**, where **right clicking generates the map**.

Now I can see the generation process (**Update method**), but **not the specific parts** of it.

Only **GC.Alloc**-s, **GC.Collect**-s and **Mono.JIT**-s.

Why?

# Answer
I would like to drop my trick for **Deep Profile** in addition to OP's answer. I also got **thrown out of memory** when using Deep profile.

## What is problem?

The problem become clear if developer were to Deep Profile on logic-heavy part, **that's happen in single frame**, let's say, also in my case, **map generation**. Which has several O^2 or worse stuff that would result in calling over something in magnitude of 100,000 times. Deep Profile will try to document **EVERY function calls (!)** which can bring editor or your entire PC to its knee.

The screenshot below demonstrate what happen when I record only 1 frame that happen to contain very logic heavy stuffs.

## Solution

The only workaround is to **divide your logic-heavy part into coroutine**, and have it run over several frames, so that profiler does not cough up in one go. Between it you could "Clear" profiler anytime and that will also release memory.

Convert your function into coroutine. Divide and conquer until you can isolate heaviest part that you want to profile or cause profiler to crash.

My trick here is to use `Debug.LogError` which will print error to console. If Console has **Error Pause** option on, editor will auto-pause, with the help of `yield return null` which jump out of coroutine and wait for next frame, effectively it will pause just before that code part will run. So you can easily press **Step** in editor to advance frame manually.

```
IEnumerator MapGeneration( )
{
    Debug.LogError( "Before part 1" );
    yield return null;
    /* Code part 1 here */

    Debug.LogError( "Before part 2" );
    yield return null;
    /* Code part 2 here */

    ... // And more, you get the idea

    // If there is subfunction that need to break down
    // You could also convert it to Coroutine too and call it this way
    yield return SubFunction( );
}

```
> 2 votes

# Answer
I had to turn on **Deep Profile.**

Also, if it's too heavy for you computer, then instead add **profile markers** to the sections you want to inspect.
> 0 votes

---
Tags: unity, profiler
---


# Question
Title: Why are there aliasing artifacts with my text?
I am using a World Space Canvas, with a UI Text on it, using the Outline script, to produce the following text. I'm noticing a number of strange artifacts on the text, as seen below. Note for instance the yellow/black blog next to Tortuga, and the a in Tortuga not looking correct. There are others as well.

The same artifacts appear in my Scene view, so it leads me to suspect that it might be something Unity is doing that is odd. I've tried removing the outline, but I still see artifacts. Here is the text settings:

And here is the Canvas, which is the parent of the text:

Any idea how to remove these compression type artifacts? Thanks!

EDIT A few things tried:

1. Removed outline: See photo below.
2. Using an imported font with a high font size (64) set.
3. Changing the font size from low (1) to high(50) in the Text window.
4. Set all scaling to 1.

# Answer
That is because the way the Unity Outline works, it will put a bunch of gross artifacts around your original text.

You can reduce the number of artifacts by raising your font quality, and making sure that you set the Outline alpha to 1.

Also try changing the Outline distance to negative values, which may help alleviate the artifacts.

Bottom line is, the Unity Outline implementation is pretty bad. I also stumbled upon this but I opted to not use it as it seems to be quite expensive in terms of CPU usage:

https://github.com/n-yoda/unity-vertex-effects
> 1 votes

# Answer
The Unity rendering issue was known to have issues, I reported this as a bug and it was accepted. The real solution is to use TextMeshPro, which Unity has since purchased, it is a much cleaner text rendering engine.
> 0 votes

---
Tags: unity, text
---


# Question
Title: How to create an obstacle that sends the player in the air?
I'm making a game in UE4.25 and I have several obstacles in there. I want them to send the player in the air if the player walks or stumbles into them. (Kind of like a Fall Guys effect, like if you get hit by a nearby falling ball, you fall into the void or something.)

Is there a possible way to do this?

# Answer
> 0 votes
You can apply a force to the character when they trigger the obstacle. Use AddForce if you are using blueprints or UPrimitiveComponent::AddForce if you are in C++.

---
Tags: unreal-4, unreal
---


# Question
Title: Is collision detection with static environment necessary for npcs
I can't find any information on this topic. I'm wondering about the differences between the collision detection approach for player as opposed to npcs.

Basically NPCs will move strictly along the navigation mesh (constructed for static environment) with a pathfinding algorithm. And should in theory not collide with any static obstacles. In that case do we really need to check for collision against the static environment?

As opposed to NPCs, players are not bounded by navigation mesh. So we would definitely have to handle collision with static environment.

I'm wondering what the general consensus is around this in game development?

# Answer
Summarizing my comment above:

You can forego collision-checking/handling between NPCs and static geometry **if and only if NPCs can never leave the navmesh**.

If an external force can throw NPCs off the navmesh, then they could potentially get into a situation where they'd collide with static geometry outside the navmesh area.

In some games this can cause a glitch where an NPC knocked back by a dynamic collision or explosion becomes stranded and can't find their way back to the navmesh, or just passes straight through the static objects entirely and falls out of the level.

If this can happen in your game, you may want to enable collision-checking anytime something pushes or ragdolls an NPC, and then disable it again once the NPC is safely back in control of their motion on the navmesh.

If you have no outside forces or other influences that can push NPCs off the mesh, or you enforce the navmesh bounds in such a way that they override these other influences, then you may be safe skipping static collision checks with them entirely.
> 0 votes

# Answer
In many games, the player is in fact following the navmesh. The player says the direction they would like to go and the character agent determines whether or not it is possible. This is much less computationally heavy than calculating collisions with the static environment. By following the navmesh, the NPCs are also able to move where the player can.
> 0 votes

---
Tags: collision-detection, navmesh
---


# Question
Title: Deserialize only some fields from a JSON file
I'm trying to parse a *very large* JSON string in Unity. I do not need all the fields and I can't create a class with all the members.

It appears that all examples I have found, including the official docs, always deserialize and map every field to class members, which I cannot do for my application.

I tried creating a class that is similar to the JSON string, meaning that it has some members of the target JSON, just not all of them. But it's not working as desired: all members of my class are always undefined after deserializing.

Here's part of the string:

```
{
    "Robots":[{"CanReset":false,
    "CycleTime":123.875,
    "Info":null,
    "LevelInfo":null,
    "Name":"FTF_10033",
    "State":0,"
    ...
    }, ...
}

```

So I tried creating these classes:

```
[Serializable]
public class jsonData
{
    public Robot[] robots;
}

[Serializable]
public class Robot
{
    public string Name = "Unknown AGV";
}

```

And printing the results:

```
var jsonString = www.downloadHandler.text;
jsonData jsonData_ = JsonUtility.FromJson<jsonData>(jsonString);
Debug.Log("Json data: " + jsonData_);
Debug.Log("Robots: " + jsonData_.robots);

```

jsonData\_ prints `Json data: jsonData_`, and `jsonData_.robots` prints nothing (just `Robots:`).

**Is there any way to parse just these particular fields out of the JSON string?**

I would be content with something like jsonString\["robots"\]\[0\]\["name"\] or something.

# Answer
It looks like your problem is just a typo.

In the JSON, your array of robots is called `"Robots"` (uppercase R), but in your class you named it `robots` (lowercase R).

As long as the fields you want to deserialize are an exact character-for-character match in name, and a compatible type (ie. not trying to map an array to an integer or something silly like that), then what you're trying to do should work, even though you're not using all the fields specified in the JSON.
> 1 votes

---
Tags: unity, serialization, json
---


# Question
Title: Change the min width/height of a LayoutElement to scale with the screen size
I want to change the Min Width and Min Height configured in my LayoutElement so that they scale proportionate to the screen size.

For example, at a screen resolution of 1920x1080, the min width is 300. Then if I reduce my screen size to 1280x720 (one-third smaller), then the min width should become 200.

How can I do this?

# Answer
> 1 votes
Presumably you tried writing a script that sets the `minWidth` property on the `LayoutElement` attached to the same object, something like this?

```
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(LayoutElement))]
public class LayoutElementAdjuster : MonoBehaviour
{
    [Tooltip("What fraction of the screen width/height should be used as the minimum?"
             +"\n-1 = Don't scale with screen size.")]
    public Vector2 minSizeRatio = new Vector2(-1, -1);

    [SerializeField, HideInInspector]
    LayoutElement _layout;
    Vector2 _cachedScreenSize;

    private void OnValidate() {
        _layout = GetComponent<LayoutElement>();
    }

    void Update()
    {
        Vector2 screenSize = new Vector2(Screen.width, Screen.height);

        // Avoid dirtying the layout if the screen size has not changed.
        if (_cachedScreenSize == screenSize)
            return;

        // Change the min size only if the layout element is controlling that axis
        // and our inspector configuration says we should scale it (ie. non-negative).
        if(_layout.minWidth >= 0f && minSizeRatio.x >= 0f)
            _layout.minWidth = minSizeRatio.x * screenSize.x;

        if(_layout.minHeight >= 0f && minSizeRatio.y >= 0f)
            _layout.minHeight = minSizeRatio.y * screenSize.y;

        // Save our current screen size, so we can react only when it changes.
        _cachedScreenSize = screenSize;
    }
}

```

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


# Question
Title: In Unity, how can I read the color from _LightColor0 in a shader?
I have a scene with a point light and alpha textured (RGBA) triangle strips. I want to apply the point light color with a shader.

```
Shader "Custom/Test02" {
    Properties {
        _MainTex("Texture (RGBA)", 2D) = "gray" {}
    }
    SubShader {
        Tags { "Queue"="Transparent" "RenderType"="Transparent"  }

        Blend SrcAlpha OneMinusSrcAlpha

        Pass {
            Tags { "LightMode" = "ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D   _MainTex;
            uniform float4      _LightColor0;

           struct vertexInput {
                float4 vertex   : POSITION;
                float4 texcoord : TEXCOORD0;
             };

            struct vertexOutput {
                float4 position : SV_POSITION;
                float4 color    : COLOR;
                float2 uv       : TEXCOORD0;
            };

            vertexOutput vert(vertexInput input) {
                vertexOutput result;

                result.position = mul(UNITY_MATRIX_MVP, input.vertex);
                result.uv       = input.texcoord;
                result.color    = float4(_LightColor0.rgb, 1.0f);
                // result.color    = float4(1.0, 1.0, 1.0, 1.0);
                return result;
            }

            float4 frag (vertexOutput input) : COLOR {
                float4 color = tex2D(_MainTex, input.uv);
                return color * input.color;
            }
            ENDCG
        }
    }
}

```

The color in `_LightColor0` is always black. How do I get the proper point light color? If the color is set to `float4(1.0, 1.0, 1.0, 1.0);` everything appears but without color from the point lights.

# Answer
> 1 votes
I was thinking wrong. I do not more passes to receive every light in the scene. I took a shortcut and used a surface shader in the end. I post it here for reference

```
Shader "Custom/Test01" {
    Properties {
        _MainTex ("Texture (RGBA)", 2D) = "white" {}
    }

    SubShader {
        Tags {
                "Queue" = "Transparent"
                "RenderType" = "Transparent"
        }

        Cull Back
        Offset 0, -1

        CGPROGRAM
        #pragma surface surf BlinnPhong alpha noforwardadd
        #include "UnityCG.cginc"

        struct Input {
                float4 color : COLOR;
                float2 uv_MainTex;
        };

        uniform sampler2D _MainTex;
        void surf(Input IN, inout SurfaceOutput o) {
                float4 texel = tex2D(_MainTex, IN.uv_MainTex);
                o.Albedo = texel.rgb * IN.color.rgb;
                o.Alpha = texel.a;
        }
        ENDCG
    }
}

```

# Answer
> 0 votes
`_LightColor0` is part of `Lighting.cginc`. It's an automatic include for surface shaders. In order to add it to your frag shader you need to put `#include "Lighting.cginc"`in your `Pass`

From the docs:

> Lighting.cginc - standard surface shader lighting models; automatically included when you’re writing surface shaders.

---
Tags: unity, shaders, cg
---


title: Start array of finding objects at 1

text:
# Question
Title: Start array of finding objects at 1
I have gameObjects that I need to find in my script that are having naming conventions such as "Obj\_1", "Obj\_2", "Obj\_3" and so on. Now I am using an array to find the objects that is given below:

```
public GameObject[] Positions;

void Start()
    {
        for(int j=0; j<Pos.Length; j++)
        {
            {
                Pos[j] = GameObject.Find("Obj_"+j);
            }

        }
    }

```

So the problem is `Pos[0] = null` whereas I want `Pos[0] = Obj_1`, how do I achieve this?

# Answer
Did you mean to write:

```
// Form a name that's Obj_1 when j is 0,
// Obj_2 when j is 1, etc...
string name = "Obj_" + (j + 1);

// Find the object with that name.
Pos[j] = GameObject.Find(name);

```

But honestly I recommend that you never use this code at all. Looking up game objects by name is brittle and error prone, and not particularly efficient. There is almost always a better solution to the problem.

In future, try asking about the root problem you want to solve instead. What game feature are you implementing that leads to needing an array of game object references that can't be populated directly as those objects are created, either by the designer at edit time, or by a spawner script at runtime?

It's very likely *something* in your pipeline knows what these objects are without searching for them, so zoom out enough that we can see how they fit into the wider scope of your game's features and we may be able to propose better solutions.
> 0 votes

# Answer
I created another variable and incremented it.

```
int i = 1;
for(int j=0; j<Pos.Length && i<Pos.Length+1; j++, i++)
        {
           Pos[j] = GameObject.Find("Obj_"+i);
        }

```
> 0 votes

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


# Question
Title: Procedural... house with rooms generator
I've been looking at some algorithms and articles about procedurally generating a dungeon. The problem is, I'm trying to generate a house with rooms, and they don't seem to fit my requirements.

For one, dungeons have corridors, where houses have halls. And while initially they might seem the same, a hall is nothing more than the area that isn't a room, whereas a corridor is specifically designed to connect one area to another.

Another important difference with a house is that you have a specific width and height, and you have to fill the entire thing with rooms and halls, whereas with a dungeon, there is empty space.

I think halls in a house is something in between a dungeon corridor (gets you to other rooms) and an empty space in the dungeon (it's not explicitly defined in code).

More specifically, the requirements are:

* **There is a set of predefined rooms**
I cannot create walls and doors on the fly.
* **Rooms can be rotated but not resized**
Again, because I have a predefined set of rooms, I can only rotate them, not resize them.
* **The house dimensions are set and has to be entirely filled with rooms (or halls)**
I.e. I want to fill a 14x20 house with the available rooms making sure there is no empty space.

Here are some images to make this a little more clear:

As you can see, in the house, the "empty space" is still walkable and it gets you from one room to another.

So, having said all this, maybe a house is just a really really tightly packed dungeon with corridors. Or it's something easier than a dungeon. Maybe there is something out there and I haven't found it because I don't really know what to search for.

This is where I'd like your help: **could you give me pointers on how to design this algorithm?** Any thoughts on what steps it will take? If you have created a dungeon generator, how would you modify it to fit my requirements? You can be as specific or as generic as you like. I'm looking to pick your brains, really.

# Answer
So, here is how I solved this problem. But first, I'd like to thank both @Shadows In Rain and @egarcia for their answers. They gave me a good direction which helped me get some results.

I used Shadows In Rain's space partitioning to generate a basic house and then followed egarcia's advice to fill in the area with rooms.

The space partitioning was pretty straightforward since 90% of the code was done by Shadows. The "fill in the rooms" part was a little more challenging. I decided to use a pseudo AI Planning system that uses A\* to position the rooms appropriately. The good thing about using planning instead of just A\* is that the preconditions help cut down the search space significantly.

Here are some screenshots with the results:

Floor plan generation phase

Room placement phase

Now with connecting doors!
> 16 votes

# Answer
I think this is good case for using either binary or ternary space partition.

On first pass, split house space into halls and {blocks of rooms}. Get next big chunk, split it into {hall and chunk} or {2 chunks and hall between them}. On every step, rotate slicing direction by 90 degrees. Stop when {no more big chunks left} or {total hall area reached limit}.

On second pass, split remaining chunks into rooms. Get next big chunk and split it. Skip splitting some not-so-big chunks at random, to have some big rooms.

If any hall is facing much older hall, place wall (or wall with door) there.

Connect rooms with halls directly or through other already-connected rooms.

For example, you can see C++-alike partly-done pseudo-code. Final shot:
> 56 votes

# Answer
You can take advantage from the fact that your desired design lumps the rooms in rectangular rooms surrounded by corridors. With that in mind, I would do this:

1. Design the corridors and the "big spaces" for rooms
2. Fill in each "big space" with rooms

Filling up the big spaces with rooms can be done easily if you start with the rooms at the borders - they have specific constraints, for example the rooms facing a corridor can have a door on that wall, but the rooms facing the "outer walls" can not (they could have windows, perhaps). Rooms "inside" the big blocks of rooms will need at least one entrance.
> 25 votes

# Answer
Dahl & Rinde have a thesis paper on Procedural Generation of Indoor Environments which uses a skeleton & regions approach to fill building interiors with rooms and hallways. The paper includes class diagrams for their prototype. There's also some good references in their bibliography, including the aforementioned *A Pattern Language*.

Their work was designed around the following simplifying assumptions:

* only dealing with apartment buildings
* no split levels
* limiting the shape of buildings (envelope) must be polygonal
* no holes in envelope
* similar or linearly changing envelope thickness (I.E. no hourglass shapes)
* only dealing with buildings that need corridors

Here's a brief overview of their process:

* Find the skeleton for the envelope. Corridors are then placed along the skeleton based on distance from envelop, proximity to doors or stairs & proximity to previously placed corridors.
* Next, the remaining non-corridor space is partitioned into maximum connected areas, each with a single continuous boundary. In some cases, this will require the insertion of a wall.
* These regions are then divided into apartments attempting to allocate at least one window per apartment. In some cases smaller divisions will merge to avoid overly small apartments. Regions with no windows are simply ignored.
* Finally, the apartments are divided into rooms using a weighted Voronoi-like diagram as a basis as follows:

+ Seed weights are used to influence the room size. Seeds are added at doors and windows. Additional seeds are added, generally one per desired room; while not explicitly stated, it looks as if the seeds are placed along the outer walls of the apartment.
    + Starting with the farthest point, a line between the given seed & all other points is calculated and then bisected a distance relative to the respective weights of the end points (E.G. if A & B had weights of 1 & 4, the bisecting point would be 1/4 of the way from A to B). The collection of bisecting lines, along with the outer wall then forms the cell for the seed.
    + Next, an S-Space wall skeleton (as per Peponis et al 1997) is created by partitioning the area with lines originate perpendicularly from the mid points between neighboring pairs of outer wall features (windows or doors).
    + Finally, walls are selected from the S-space skeleton that 'correspond as well as possible to the Voronoi cell walls.'
> 13 votes

# Answer
I am trying to design procedural spaceships for a game of mine, and I came across a similar problem, with the added issue that I needed to be able to generate irregular layouts (not bounded to a square or rectangular outline). My solution was as follows:

1. start with an empty square or rectangular map of tiles
2. generate random room center points; each point has a position and parameters for the room width and height; eg, a point at (13, 3) on the map that is the center of a room that is 8 * 2 tiles, thus tiles with a horizontal distance of 4 and a vertical distance of 1 will be inside the room.
3. move the room centers until they are spaced out by a specified hall width or they are adjacent; determine which to do by each room. eg, room 1 moves over until its edges/walls are at least 2 tiles apart from those of room 2
4. fill in the tiles above, below, or to either side of each room with hallways; choose which sides to fill in based on the position relative to the center of the map, eg a room up and to the left of the origin fills the space below and to the right of it with hallway tiles.
5. draw in the walls of both the house and each room, and doors where needed. First change any empty space tiles that border room or hallway tiles into walls. Then change any hallway tiles that border room tiles into walls.

So in theory it should look like this (periods are empty space, numbers are rooms, w is walls, h is hallways), although I haven't actually tried to implement it just yet; I apologize if this looks really bad in text I tried to make it look good:

(room one is 2x2 tiles, room 2 is 4x3, and room 3 is 3x2, hall width is four)

Step 1:

```
. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

```

Step 2:

```
. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . 1 1 . . . 2 2 2 2 . . . .

. . . . . . . 1 1 . . . 2 2 2 2 . . . .

. . . . . . . . . . 3 3 3 . . . . . . .

. . . . . . . . . . 3 3 3 . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

```

Step 3:

```
. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . 2 2 2 2 . . . .

. . . . . . . . . . . . 2 2 2 2 . . . .

. . . . . . . . . . . . 2 2 2 2 . . . .

. . . . . 1 1 . . . . . . . . . . . . .

. . . . . 1 1 . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . 3 3 3 . . . . . .

. . . . . . . . . . . 3 3 3 . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

```

Step 4:

```
. . . . . . . . . . . . . . . . . . . .

. . . . . . . . h h h h 2 2 2 2 . . . .

. . . . . . . . h h h h 2 2 2 2 . . . .

. . . . . . . . h h h h 2 2 2 2 . . . .

. . . . . 1 1 h h h h h h h h h . . . .

. . . . . 1 1 h h h h h h h h h . . . .

. . . . . . . h h h h h h h h h . . . .

. . . . . . . h h h h h h h h h . . . .

. . . . . . . h h h h 3 3 3 . . . . . .

. . . . . . . h h h h 3 3 3 . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

```

Step 5:

```
. . . . . . . w w w w w w w w w w . . .

. . . . . . . w h h h w 2 2 2 2 w . . .

. . . . . . . w h h h w 2 2 2 2 w . . .

. . . . w w w w h h h w 2 2 2 2 w . . .

. . . . w 1 1 w h h h w w w w w w . . .

. . . . w 1 1 w h h h h h h h h w . . .

. . . . w w w w h h h h h h h h w . . .

. . . . . . w h h h w w w w w h w . . .

. . . . . . w h h h w 3 3 3 w w w . . .

. . . . . . w h h h w 3 3 3 w . . . . .

. . . . . . w w w w w w w w w . . . . .

. . . . . . . . . . . . . . . . . . . .

```

from here you could add doors randomly in walls between rooms and hallways.

This would in theory be a great way to generate these ships, but I have yet to test it, and just in this example I noticed one potential unwanted artifact; there is one hallway space jutting out of the actual hall like this (capital H):

```
h h h h h w .

w w w w H w .

3 3 3 w w w .

3 3 3 w . . .

```

which is unwanted if you want rectangular hallways as well. A potential solution would be to take any hallway space surrounded on three sides by walls and replace it with a wall, and then remove all walls that are only bordering (including by diagonal) other walls and empty space because they are not necessary.

If you want a tile based solution, especially one not bound to a specific shape (although if you generate too many rooms in too small a rectangle they will spread outwards and become stuck at the edges in a rectangular shape, so make sure to generate a large enough map of empty space that the rooms won't hit the borders) then this should work :)
> 2 votes

---
Tags: algorithm, procedural-generation
---


# Question
Title: How to scale our multiplayer support, similar to Among Us
We are a small team with the goal of creating our first multiplayer game, and we want to support multiplayer that can rapidly scale up as Among Us has successfully done.

We don't have a huge budget and we are struggling to find an appropriate way to implement multiplayer, including peer to peer (although it would be exhausting to combat cheating and make a smooth experience). Our game has no more, no less than 50 players in a very tight space.

As an example, we're looking at the indie game Among Us. They went from such a small game with barely any players, to maintaining well over 3 million CCU (concurrent users). How can we achieve similar scalability?

# Answer
You are in luck: game servers scalability is relatively straightforward nowadays and not that expensive. All major cloud providers today offer both fully-managed Kubernetes and serverless environments, all with auto-scaling so that you can only pay for what you need and use. The system will easily scale up and down, serving a hundred or a billion CCU seamlessly.

Now, what to choose among those services depends on how your backend works, how it's built. For instance, if you are on Photon Server, you have already a ton of options and Azure would be the best fit as a cloud provider. If you are on SmartFox Server then you should go for a managed Kubernetes, so just pick any of your liking among AWS, Azure and GCP. If your server is running on a headless instance of Unity then is a tad more complicated because of the way Unity works, so you must run separate servers for lobbies/matchmaking logic and actual games. Otherwise, scalability and user experience will go down the drain. This because Unity is a game engine, not a backend server, while the others I mentioned were designed to be backend servers: it's a matter of architecture.

One more thing you have to take into account is the regional separation. If your game is either turn-based or in case it can take a tad of additional latency; then you can get away with a single region. Otherwise, you have to go for at least two regional servers, Europe and the Americas. Maybe you need also Asia, depending on your users' distribution across macro-regions.
> 1 votes

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


# Question
Title: In Unity how do I easily snap modular building pieces to the grid without overlaps or gaps?
I'm new to Unity and purchased a set of modular building pieces from the asset store. I'm trying to arrange pieces of wall. The pieces are 5 x 5 x 0.5, so I've set my world grid size to 5 units and am using align to grid to make them line up nicely. I'm running into an issue when I try to make a corner. When I align the pieces to the grid, there is some gap and overlap, as seen in this picture:

I then tried to manually move the end piece inwards, which resulted in this:

That looks slightly better, but needed a manual adjustment so I don't think doing this everywhere scales very well, and plus there is some kind of visual/lighting artifact where the pieces overlap (hard to see in the screenshot but very obvious when I move around in game mode). Then I tried resetting that end piece back to the grid and pushing the two side pieces inwards, which resulted in this:

This looks good and has no overlap, but required a bit of manual adjustment and brought the sides off of the grid.

Assuming a set of wall pieces that are 5x5x0.5, how can I configure my grid and snap settings so that everything fits together nicely?

# Answer
What you are looking for is Vertex Snapping: you hold V selecting the vertex you want to snap and click and drag on the vertex you want it to snap. See the Snapping Section on this page of Unity documentation for other snapping techniques.
> 2 votes

---
Tags: unity
---


title: Minimax Algorithm Scoring Mechanism

text:
# Question
Title: Minimax Algorithm Scoring Mechanism
I'm basically trying to understand the chronology/sequence of the algorithm and where should I call the scoring mechanism function that calculates the score of each move and returns an int. For example, this code is an implementation of the Minimax algorithm in the Tic-Tac-Toe game:

```
function bestMove() {
// AI to make its turn
let bestScore = -Infinity;
let move;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
  // Is the spot available?
  if (board[i][j] == '') {
    board[i][j] = ai;
    let score = minimax(board, 0, false);
    board[i][j] = '';
    if (score > bestScore) {
      bestScore = score;
      move = { i, j };
    }
  }
}
}
board[move.i][move.j] = ai;
currentPlayer = human;
}

let scores = {
X: 10,
O: -10,
tie: 0
};

  function minimax(board, depth, isMaximizing) {
  let result = checkWinner();
  if (result !== null) {
  return scores[result];
  }

  if (isMaximizing) {
  let bestScore = -Infinity;
  for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    // Is the spot available?
    if (board[i][j] == '') {
      board[i][j] = ai;
      let score = minimax(board, depth + 1, false);
      board[i][j] = '';
      bestScore = max(score, bestScore);
    }
  }
}
return bestScore;
} else {
let bestScore = Infinity;
for (let i = 0; i < 3; i++) {
  for (let j = 0; j < 3; j++) {
    // Is the spot available?
    if (board[i][j] == '') {
      board[i][j] = human;
      let score = minimax(board, depth + 1, true);
      board[i][j] = '';
      bestScore = min(score, bestScore);
    }
  }
}
return bestScore;
}
}

```

The only implementation of the scoring mechanism is when the board identifies a win situation for one of the players. In complex games there are too many combinations so the depth will be restricted to let's say 3. the scoring mechanism needs to be called for each "move" that is being examined, otherwise we will get back 0 for each move, and the algorithm will just go for the next open spot, since the depth doesn't reach a possible wining series of moves.

If I planned a scoring mechanism function that compensate and "punishes" each move (for every i,j) minimax goes through and returns an int (the score), how should I fit it correctly in the algorithm?

It sounds simple but honestly nothing makes sense to me at this point...

P.S My game is pretty complex to explain and would take a long time, therefore, I'm looking for the more logic answer so I can implement it myself.

Thanks in advance, Omer

# Answer
You invoke your scoring method anytime you are not recursing further into the game tree.

That could be when you've reached an end state, like in the Tic-Tac-Toe case, in which case you can score the move with total certainty about who benefits most from this outcome.

It can also be when you've hit your recursion limit:

> In complex games there are too many combinations so the depth will be restricted to let's say 3

So you will recurse three times. Then when you arrive at a new unevaluated game state at a depth of 3 and can't recurse any further to evaluate it based on future moves, you fall back on a scoring heuristic.

Here you score the game state using some estimation of who has an advantage in this state — like which player has more powerful pieces on the board, or the most health, or the most victory points or resources, etc.

This estimation is crude, but it's just one data point in your search — it benefits from aggregation with all the other recursive branches you tried. So the deeper you can recurse before falling back on the scoring heuristic, the better the judgments you'll tend to reach by this method.
> 1 votes

---
Tags: ai, turn-based
---


# Question
Title: How to transfer the player into a new scene, loaded in the background?
I'm porting an old BuidBox 2 game to the Godot game engine. I already added all assets and scenes to the Godot project. The game is a 2.5D (isometric) endless runner. What I want now is to add a mechanism to load the next scene offscreen, remove the player's character from the current scene, and add it to the next scene seamlessly, without breaking the game physics or causing the player character to go behind or in front of other game objects that it's not supposed to.

For instance if I have this scenes:

```
Scene1
|-bg
|-player
└-fg

Scene2
|-bg
|-player
└-fg

```

I would like to load `Scene2`, remove player from `Scene1` and replace `player` from `Scene2` with the player node I removed from `Scene1`, without the player node changing its velocity or position abruptly in the physics world or appearing behind the `bg` node in `Scene2` or in front of the `fg` node in `Scene1`.

# Answer
> load the next scene offscreen

Usually we switch scenes with `get_tree().change_scene("res://Main.tscn");`. We are not going to do that. Instead we will load the new scene as a resource (`PackedScene`) and then switch.

You can load the scene in a single call of `load` on the `resource_loader`, but that could mean a noticeable hiccup.

Instead, you could use background loading as hinted by rawburt.

The abstract is that you `load_interative` instead of `load`. Calling `load_interative` returns a `ResourceInteractiveLoader`.

Then, on `_process` call `poll` on the `ResourceInteractiveLoader`. Do this until `poll` returns `ERR_FILE_EOF`, meaning it is done loading. *Meanwhile, you can use `get_stage` and `get_stage_count` to know the load progress, for example to show a progress bar.*

When loaded, the new scene will be available by calling `get_resource` of the `ResourceInteractiveLoader`.

---

Now, to switch to the new scene, we will mimic `change_scene`. Simply by instantiating the `PackedScene` resource, add it the scene tree and remove the old one.

Example:

```
var root = get_tree().get_root(); # Assuming you want to use the root

# Add the scene level
var next_scene = next_scene_resource.instance();
root.add_child(next_scene);

# Remove the old scene
var scene = root.get_node("Level"); # Node name may vary
root.remove_child(scene);
scene.queue_free();

```

Where to put that code? You can place it on the scene you will change itself. However, it will be handy to have this code in an AutoLoaded scene. See AutoLoad.

---

> remove the player's character from the current scene, and add it to the next scene seamlessly

Alright, so you will first instantiate the new scene, then remove the avatar from the old scene and add it to the new one, finally you can remove the old scene.

The avatar, just as the scene, is another child in the tree. Remove it from the scene with `remove_child`. Usually we would then `queue free`, instead add it to the new scene.

Something like this:

```
var root = get_tree().get_root(); # Assuming you want to use the root

# Add the scene level
var next_scene = next_scene_resource.instance()
root.add_child(next_level)

# Get the old scene
var scene = root.get_node("Level"); # Node name may vary

# Get the avatar
var avatar = scene.get_node("Avatar"); # Node path may vary

# Remove the avatar from the old scene
scene.remove_child("Avatar"); # avatar.get_parent().remove_child("Avatar");

# Add it to the new one
next_scene.add_child(avatar);

# Remove the old scene
root.remove_child(scene);
scene.queue_free();

```

> without breaking the game physics

Then you probably want to do this in `_process_physics` instead of `_process`.

> or causing the player character to go behind or in front of other game objects that it's not supposed to

After adding the avatar, you can set its position in the new scene with `move_child`. Or you can add it directly in the position you want with `add_child_below_node`.

---

Be careful with what you put on the `_ready` of - any of the nodes of - the new scene. If the new scene needs to pre-load something, consider using AutoLoad or doing it lazily.
> 1 votes

# Answer
This resource might help you begin to find a solution https://docs.godotengine.org/en/stable/tutorials/io/background\_loading.html
> 0 votes

---
Tags: 2d, isometric, godot, gdscript
---


title: Can't set the correct camera to current

text:
# Question
Title: Can't set the correct camera to current
There are three cameras in my scene - Camera1, Camera2, Camera3. I want to have Camera1 as the only current camera. But whenever I remove the "current" tick from Camera2, Camera3 becomes current, and vice versa. No matter what ticks I tick and in what order, I cannot reach the desired state - Camera1 as current, Camera2, and Camera3 as not current. What's going on?

# Answer
> 1 votes
The effective current camera will be the last camera marked current. Where last means lower in the scene tree.

Thus, if you have three cameras: Camera1, Camera2 and Camera3 (in that order), and they are all marked current… The effective current camera is Camera3.

If you unmark Camera3, the effective current camera is Camera2.

If you want Camera1 to be the current, you must unmark both Camera2 and Camera3, because they are after Camera1.

---

What if there is no Camera marked current? Then Godot picks one, and Godot marks it current. I think this is what is happening to you.

You have three cameras: Camera1, Camera2 and Camera3 (in that order), and only Camera3 is marked current.

If you unmark Camera3, that leaves no camera marked current. Godot picks another camera, in this case Camera2 and Godot marks it current.

Afterwards, you unmark Camera2, that leaves no camera marked current (again). Godot picks another camera (again), in this case Camera3 and Godot marks it current.

So, by unmarking the current camera, the current camera will be going back and forth between Camera2 and Camera3. It will never be Camera1.

---

What should you do to make Camera1 current?

1. Mark Camera1 as current. Which has no immediate effect because some other camera placed after it is current… But the mark is saved.
2. Whatever camera is effectively current, unmark it. Now the effective current camera is Camera1

For abstract: avoid leaving no camera marked as current. If you are going to switch cameras, mark the next camera current first, then unmark the old camera.

---

There are other ways to work with this. I'd advice to make the first camera the default camera. Leave it marked current always. Then you can simply mark another camera current and unmark it when you are done, leaving the effective current camera fallback to the first camera.

From the above follows that you want to sort your cameras by priority (where lower in the scene means higher priority). Leave a "default" camera always marked current as a default fallback. Then you can add other cameras below. Have scripts that marke them current or unmark them when it makes sense. The scripts that handle this does not need to know about the other scripts handling cameras, how many cameras are there, or which camera is the effective current. The effective current camera will be the camera marked current that has more priority (the one lower in the scene tree).

Oh, and if you need cameras that should never be the effective current camera (for example, to get what they see as a texture), they can be before the default one.

One more thing: sometimes it is useful to put a camera in a `RemoteTransform` or (`RemoteTransform2D` if we are talking 2D). So that the camera can be on one branch of the scene and what it follows in another. `RemoteTransform` is also useful if you only want the position, but not the orientation, or viceversa.

---
Tags: camera, godot
---


# Question
Title: How to apply object transformations in Godot UI?
E.g I have changed the scale and rotation of a `MeshInstance` and I want the editor and GDscripts to accept new settings as scale 1 and rotation 0 degrees in all axes.

# Answer
You put the `MeshInstance` inside of a `Spatial` node. Then place the `MeshInstance` as needed. Then you can manipulate the `Spatial` node.

Furthermore, you can save the `Spatial` node as a scene. The scene will have an internal tree where the `MeshInstance` exists.

Then you can add that scene in another parent scene, and it will appear as a single node, with the fact that is has a `MeshInstance` and that said `MeshInstance` was moved hidden from view.

You can do that to create an scene that has all the nodes you need for your particular game object (eg. `KinematicBoy`/`RigidBody`/`StaticBody`, lights, camera, and so on), and then use it as a single node in scene that represent a stage.
> 2 votes

---
Tags: godot
---


title: Sound Management Help

text:
# Question
Title: Sound Management Help
I just learned how to implement a Sound Manager and put sounds into it. The problem is, I'm making a platformer and I have a player, and two different types of enemies who all have footstep sounds. The main issue is that I'm playing all the sounds from the same sound manager and I made the footstep sounds of the player to play like this:

```
  public void PlayMoveSound()
{
    if(audioSrc.isPlaying == false)
    {
    randomMoveSound = Random.Range(0,5);
    audioSrc.PlayOneShot(moveSounds[randomMoveSound]);
    }
}

```

I don't know how else to make it NOT sound like its playing 100 times per second so I did this. This gave birth to the issue that the looping audio which is the player's movement sound now blocks me from doing the same thing for the other characters' footstep sounds since it uses the same "audioSrc" AudioSource. Any hints on how different I can create a system for semi-looping audio?

# Answer
> 1 votes
A single Sound Manager is good for non-diegetic sounds like background music or interface sounds. It is usually not so good for diegetic sounds emitted by entities actually present in the game world.

When you want to add footsteps to a game object, then it's usually the better choice to add those footsteps as an audio source to that game object. The neat advantage of this is that this makes the sounds directional. So objects on the left side of the screen are louder on the left speaker while those on the right side are louder on the right speaker. This increases the grade of immersion of your game.

You should also use a separate audio source for every sound effect an entity can make. This prevents conflicts between looping and non-looping effects like you experience them right now. It also allows you to tune the audio source settings of each sound effect individually and send different sounds to different inputs of your audio mixer.

When you need to control those audio sources via script, then that controller script should be attached to the same game object as the audio sources.

But note that the Unity animation system can also be used for controlling audio sources. So when you are already using an animation controller, then you might have the walk animation control the footstep audio source as well.

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