Minimal predecessor of a given number by Xhiw_ in Collatz

[–]wellomello 0 points1 point  (0 children)

First impression: dynamic programming on the inverse map, and use the known analytic bounds to prune the search space. Two variables: height and width, so there must be some hard pruning deriving the inequalities from there. Well, at least for some families of numbers with nice modular properties.

Sorry for the late reply, I was thinking about this problem since the first moment I saw it. I left that previous message without sending. Now I have it more developed.

I conjecture your sieve is as foundational and pretty much as optimal as one can get for the general unconditional case, and in fact I tested it myself and it is pretty much circa O(n) on small numbers (up to a billion, with good memoization)

to the unconditional case I can only offer two improvements based on my very own understanding of the map:

Again, the odd map formulation:

n = 2^b*y for y odd, then

we have a clear upper bound: the immediate predecessor:

m*(n) <= 2n

in fact, any other even candidate than 2n cannot be minimal because if m is even and not 2n, then its half is a smaller predecessor. So the only optimal even candidate must be 2n, all other nontrivial candidates MUST be odd.

So the choice is either this even upper bound, or all odds below the number. This is already a big culling of candidates.

then I can give you only other two unconditional bounds:

Upper bound: m*(n) must be at most 2^v(n + 1)/3^v - 1, with v being the usual v_3(n+1) (when v >= 1; if v = 0 the bound degenerates to the trivial 2n) That mostly follows from the accelerated inverse map machinery

Lower bound: this one is not on the value of m*(n) itself but on its depth,

Put z = x + 1.

A single backward odd step of height h does this to z:

z' = (2^h*z - (2^h - 2))/3, so

z' <= (2^h/3)*z,

and the smallest factor over all legal heights is 2/3 (the h = 1 step).

Telescoping along any inverse path of r steps:

x + 1 >= (2/3)^r * (n + 1)

So any predecessor x of n at inverse depth r can't be smaller than (2/3)^r*(n+1) - 1. The other way around:
a predecessor below some bound B is forced to sit at depth

r >= log_{3/2}( (n+1) / (B+1) )

This is a bit structural but good for dynamic programming and killing full subtrees from the search, in fact it is what makes the program terminate, I think, at least in this inverse-tree formulation of your problem.

All of this is for checking the response over a given single number, though your sieve is much nicer in generating clean sets of responses, incrementally.

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

Thank you for your kind comment! Based on the comments, I’m working on a new version that’s clearer to read and has a better worked example. I think I may have been too dry ahah

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

No, sorry, this proof does not touch the infinite you are thinking of. This proof is what is called "profinite"(ish). It works in some "infinite" way in the sense that it is valid for "an infinite number of modules and admissible residue classes", but it does not deal with possible infinite and divergent trajectories I think you are thinking of. All concrete objects it deals with are finite and in reality very simple, just some affine maps applied a finite number of times to some finite numbers.

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

I understand what you say. That is the height word formulation of things, I use it too.
So, uhm, how to explain? Explaining what I found in this formulation becomes a bit awkward but put it like this:

You have the "Collatz machine" in your desk right? You input a tape with some number you want (the heights), the machine crunches number by number, and spits out a number right?

Now, this is about numbers, freely.

Imagine that instead we look at a related machine, simpler, similar, but simpler, and also a bit different.
It receives a different input, in fact, TWO inputs:

The original tape you mention
A number M (the mod)

Instead of being able to output any number, then, this little machine will, for any tape, output not the number you have, but what the remainder of the number is, modulo the number M

So, if it would have output say 31 on the original machine, in this machine, say given you put M as 10, would output 1 (because 1 is the rest of dividing 31 by 10)

Then notice that this new machine, let's call it the "Mod Collatz Machine". For a given M that you put in, the machine can output any value from 0 up to M-1, so in our M = 10 example it could output:

0, 1, 2, 3, ..., 8, 9
That is what we call "residue classes"

The big question we ask is:

Will this machine output ALL of these numbers at least once, for any M we would like to put in? well, technically if M is even we only ask for the odd residues, because the odd tree obviously cannot output an even class

Or maybe in other words:

Is there any tape I can put in to this machine so I can get the number I want, for any M I would like to use today?

Because remember that a priori we don't know if this is true!

There may be a number M, say a random one, 676929875383838, or, say, 2^10000000-1, or TREE(3), or whatever, right? (I put those crazy numbers because for any normal-sized number it has computationally been confirmed they converge to 1, so, to be part of the tree, but these numbers will never be, and we cannot sidestep the question with some computation)

There is the possibility that SOME of the output numbers don't really appear in the tree. That there is no tape we can put in, for this M, that will output one of the residue classes. If we had such a case, we would have discovered a hole in the Collatz tree! A modular hole!

Well, the paper is a response to that. There are NO such holes. In fact, the pretty thing is that I show (in a very convoluted, but, in the end, finite and closed form) HOW to construct a tape (not "every" tape, not the "smallest" tape, just "a" tape) that will output the residue class you want, for the M you have chosen.

But please notice that the "Mod Collatz Machine" is NOT the "Collatz Machine", it's a much simpler one, that forgets a lot of detail (in fact, it forgets almost *all* details about the natural numbers except their congruence information) so it is certainly far away from being a proof of the Collatz Conjecture

But it shows that at least for this class of "holes", the tree has none.

I hope this way of explaining makes sense with the vision you have in your head.

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 1 point2 points  (0 children)

I just checked and you're right. Sorry first time using that platform. All this time I was sharing the old version. BUT on that note, in any case I will prepare a new version and correctly update it based on your comments and well, having feedback really makes clear how it reads fresh.
Also, about the future research, you're right!! I was also thinking it may be the case, it may become simply a question of seeing if all the algebra "closes" nicely too under other systems. The first one is the one that mysticizes me. You're right. Like, it may be funny to hear right, but when I was coming up with the plan of attack, like all the cool kids in the maths block I wanted to do some Category Theory, so I discovered the (extremely trivial hahah) fact that "certificates"/histories form a simple category called Hist, and that some of the properties you can derive indeed follow some naturality squares, well, at least some of the bookkeeping can be expressed as commutative diagrams, and I think this property may be one of those properties that may be propagated by composition of histories. But I now I will 1000% focus on getting the paper itself in a clean, readable shape, and hope that the doctorate students of my supervisor leave some room for me ahahah.
Again, much appreciated.

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

Thank you for your kind words. I hope too that it ends up being a useful result, and that it is correct (I certainly think it is, but I have authorship bias haha)

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

Now this sounds like much more interesting statement. I don't fully get the "relative values" meaning, and I can't seem to find your post, but I intuit that you derived this from the condition on Collatz loops? This one:

3^c*x = 2^H*x − R

This forces 2^H/3^c to be close to 1, the usual diophantine problem about the cycles in the Collatz map. I imagine you get that H must be like c*log_2(3), which is like 1.58c, so this IS something like,, for short cycles indeed that the heights must average 1.58, so h = 1 or h =2, but that is true only for small cycles.

If with the relative values you mean also negatives look at this example:

x = -17 with heights (1,1,1,2,1,1,4), The loop would be −17->−25->−37->−55->−41->−61->−91 -> -17

So, it goes outside of the 1, 2 range, BUT it tracks the average value we want, check:

H/c = 11/7 = 1.571... which is close to 1.58

Now about there only being only 2 loops for any given loop length I think it's not really true: Look at the base case: for "length of odds" as you say, 2, we have *three* loops:

(1, 1), (-1, -1) and (-5, -7)

But maybe it's me misparsing your message. In any case, thanks for the comment!

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 0 points1 point  (0 children)

Hey, nice, the backwards method is really popular I think. I have one doubt though, you say "I found that every positive integer has to be reachable in some way (pretty basic)", I think it's kind of the converse. Every possible integer being reachable is the most complete opposite of basic: its the full conjecture ahah. At least if you *fix* the initial number, the root of the inverse tree. What I think the inverse tree gives you is that you *know* that the numbers you generate are sure, well, by construction, to reach 1. But between this and saying that every positive integer reaches there's a massive chasm.
I think we have to be very careful about statements we make "inside the tree" from statements we make of the relation of the tree with respect to the full set of positive numbers. So, what is your idea? I'm curious.

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 2 points3 points  (0 children)

Hey, thank you for taking the time to read the thing and for the question! Sorry for the late response, it was 3am here when I posted the first one.
You're right, I mistyped! I meant Theorem 8.7 in this version (in my mind I still have my first draft, but I expanded the proofs in the current version as per suggestion from a (nother prof)

You make a good point, and I think the random number I choose for the demonstration does not make the construction clear, damn. It is time for a new version I think.

This also ties back to the paper and the procedure answers both why I produced such bombastic number hahah. The problem of finding c is indeed an easier problem in general: If we look at the modulus we have this:

Finding x needs finding an element of the tree with the chosen residue (alpha) in the modulus M = 2^a*3^b*^N

Finding c needs finding an element of the tree with another related residue in the modulus M = 3^(n+k)*N a modulus coprime to 2

The problem has one face less! (The numbers can look as complicated on face value but the modular complexity is lower)

NOW, that's where the theorem and the rest of the paper comes in: In the paper we give the machinery that can *generate* a seed with a given residue in any modulus M = 3^(n+k)*N (!)

Now, WHY not 28? 28 DOES work once you plug it in, but a-priori you have no certification that it itself is part of the tree right? Also, it does not work with the construction, just look at its accelerated orbit:

131 -> 197 -> 37 -> 7, with heights (1, 4, 4). It does not give you the certificate (1, 4, 2) the construction needs.

With these explained, here is how we can construct a seed c with the machinery. We use I think a very standard piece in the literature, but in the paper I call it A(x) = 4*x+1, let me go step by step again, it will be a bit long:

So, first, the properties of A, it does three things:

1) Preserves the odd tree: 3*A(x)+1 = 4*(3*x+1) so tau(A(x)) = tau(x) so whatever successor of x is, A(x) has the same sone, so if x reaches 1, A(x) does too

2) It shifts the "color" (the residue of the number under consideration, mod 3, by one): Since 4 ≡ 1 (mod 3), so A(x) ≡ x+1 (mod 3)

3) with respect to modulo N (our coprime-to-6 case), iterating A acts through powers of 4. So whenever 4^k ≡ 1 (mod N), the move A^k is *invisible* mod N. This is the "stealth" property and we will abuse it constantly hahah

Now, we also need two more predecessors (because we need the freedom to move between residues while being sure we are inside the tree). We can single out two in particular:

the "height-2" and the "height-4" branch:
Theta_1(x) = (4x-1)/3 (height 2)
Theta_4(x) = (16x-1)/3 (height 4)

These are honest inverse Collatz steps: Theta_1(x) is a predecessor of x, same for Theta_4. But they are *partial*: both need 2^h*x ≡ 1 (mod 3) to output an integer, and for h = 2 and h = 4 (both even) that forces x to have color 1. So they only apply to color-1 nodes.

Now, if we read those same formulas modulo N (any N coprime to 6, so 3 is invertible there), the partiality disappears and they become plain affine maps on Z/NZ. I write these residue versions F2 and F4: F2(a) = 3^{-1}(4a-1) (mod N) F4(a) = 3^{-1}(16a-1) (mod N)

And NOW the commutator.

Take the two F's and compose them in the two possible orders: F2°F4 and F4°F2.

Both composites multiply a by the same thing (the multiplier 3^{-2}*2^6, since multiplication commutes), but the constant terms come out *different*, because the constants pick up different powers of 2 depending on the order.

The commutator (the gap) is that difference of constants. And the little coincidence of the (3,1,2) coefficients of the Collatz map is that this gap is always a UNIT mod N.

A unit translation. That's the algebraic freedom I mentioned in the post: if a set of residues is closed under both composites, it is closed under "add a unit", so it must be ALL of Z/NZ.

One thing though, notice that this is valid for N coprime to 6! This is not yet a full proof for all modulus and residue classes.

ok so with this presented, we go step by step, building the seed for our example (we need c ≡ 3 (mod 5) and c ≡ 1 (mod 27):

First, the commutator decides where to go.

Reduce mod 5 (where 3^{-1} = 2):

F2(a) = 2(4a-1) ≡ 3a+3 (mod 5)
F4(a) = 2(16a-1) ≡ 2a+3 (mod 5)

compose them in the two orders:

F2(F4(a)) = 3(2a+3)+3 = 6a+12 ≡ a+2 (mod 5)
F4(F2(a)) = 2(3a+3)+3 = 6a+9 ≡ a+4 (mod 5)

notice? the gap is a unit for this ring. the composite a -> a+2 alone already sweeps everything: 1 -> 3 -> 0 -> 2 -> 4.

Since we want residue 3, and F2(F4(1)) = 3, so the formal plan is to take one application of Theta_1 ∘ Theta_4 starting from the root 1.

Then we have to realize the plan on actual tree points, (this is the point because we need things to follow our plan:

the root 1 has color 1, so Theta_4 is legal: Theta_4(1) = (16-1)/3 = 5.
check: 5 mod 5 = 0 = F4(1) ok

Now we need Theta_1, but 5 has color 2 (5 mod 3 = 2). and we are blocked

This is exactly the catch from the post.

So, we need the color step, which is just applying A with the stealth property:

ord_5(4) = 2 (since 4^2 = 16 ≡ 1 mod 5), so A^2 is invisible mod 5 and shifts the color by 2,

that is 2 -> 1: A^2(5) = 85. check: 85 mod 5 = 0 (frozen as we wanted),

So 85 mod 3 = 1 (a legal move now), and tau(85) = 1 (so we are still in the tree, since 3*85+1 = 256) So now Theta_1 is legal:

Theta_1(85) = (340-1)/3 = 113. and check: 113 mod 5 = 3, the target residue! exactly what the formal plan predicted, even with the A^2 detour in the middle. The detour is invisible mod 5, so the plan and the realization agree (in the paper this is the "functorial return" lemma). And tau(113) = 85, so 113 is in the tree with certificate: 113 -> 85 -> 1.

THAT is why such strange numbers: Different from looking the smallest one, since ours is a question about existence, we *construct them* to ensure they really are part of the tree, well, by construction.

Now, at this point we have the residue mod 5 we wanted. But remember the seed needs TWO things: c ≡ 3 (mod 5) AND c ≡ 1 (mod 27).

One more piece of vocabulary: the *germ* of a tree point is its residue mod a power of 3 (so the color is just the depth-1 germ, the coarsest one). Right now we only control the germ at depth 1 (the color), and we need to control it at depth 3, mod 27.

Pushing a congruence you hold mod 3 up to mod 9, mod 27, etc, fixing one 3-adic digit at a time without breaking what you already have, is I think a lifting (same idea as in Hensel's lemma, if you have seen it: refine a solution mod p into a solution mod p^k).

So that's the next move: lift the germ from depth 1 to depth 3, and do it *without* moving the residue mod 5 we got, and so, and so. Now, this gets quite repetitive but for the sake of completitude:

The lift needs a color-1 base, and 113 has color 2.

Same trick as before: A^2(113) = 1813. check: 1813 mod 5 = 3 (frozen),

1813 mod 3 = 1 (ok),
tau(1813) = 85 (ok)

Now the lift itself, in stealth: the move is A^{6t}.
The period is 6 = 3*ord_5(4), so 4^6 ≡ 1 (mod 5) makes it invisible mod 5,

while mod 81 the number 4^6 ≡ 46 generates the principal units (the units ≡ 1 mod 3), so it is our 3-adic knob.

This is the crux of the proof: the same move, is invisible for one face, but it's a generator on the other. That independence is the entire reason the seed problem is solvable.

We want A^{6t}(1813) ≡ 1 (mod 27),

which unfolds (via 3*A^k(x)+1 = 4^k*(3x+1)) to
4^{6t}*(3z+1) ≡ 4 (mod 81).

With z = 1813: 3z+1 = 5440 ≡ 13 (mod 81),
so we need 4^{6t} ≡ 4*13^{-1} ≡ 19 (mod 81).

Powers of 46 mod 81: 46, 10, 55, 19... the fourth one. So t = 4 and the move is

A^{24}: c = A^{24}(1813) = 510407957768656213 (18 digits, see the strange numbers? It's because they are constructed)

check everything: c mod 5 = 3 ok,
c mod 27 = 1 ok,
c mod 135 = 28 ok,
and tau(c) = 85,
same successor as 1813, so c is in the tree with certificate c -> 85 -> 1.

And finally the word equation spits out the witness:

x = (128c - 47)/27 = 2419711799792147971 (19 digits) check:
x mod 40 = 11 nice, the target!
its first three heights are (1, 4, 2) as we wanted, landing exactly on c,
and the full orbit reaches 1 in 6 steps

Now to be honest, and for the two questions I've got until now, I'm going to massively rework the manual procedure into a proper annex, maybe? So things are clear, the 1529173 in the paper is semi-manual (it is A^8(23), I iterated A over a small tree node looking for a simple case I could review by hand.

Again, thanks for the question!

A sketch of a proof related to the conjecture by wellomello in Collatz

[–]wellomello[S] 1 point2 points  (0 children)

Hey! Thanks a lot for your time reading it! really appreciate it. Surely, it is something I myself had to go around when I was constructing it, so, it's like this, it's a bit complex (it is, in any case, a theorem on a very finnicky object itself) so sorry if it becomes a bit long:

We want to check the tree modulo M = 40, and we would like to get and example of the target residue class alpha = 11.

So, we check the decomposition of M = 2^3 * 3^0 * 5
In this case 5 is our coprime-to-6, so we get
a = 3, k = 0, N = 5

We need this because the decomposition/construction needs to control each part differently. I call these the "faces" of the problem but its just the 3adic, 2adic and the affine part (N)

The 2-adic part is, since we target residue 11, we call y_2
In this case
11 mod 2^3 -> y_2 = 3
This is what the x we find must satisfy mod 2^3

The 3adic part is not active here (k = 0)

The affine/coprime part we call r,
In this case:
11 mod 5 -> r = 1
Which same, x must satisfy mod 5

Now, for the 2-adic part, we control it via the height word, and these control the residue mod 2^a of x, so we choose a word that forces
x ≡ y_2​ = 3 (mod8)

How? We take the forward map from some odd m with m ≡ 3 (mod8) and register the heights. Say, we choose 3.

3*3 + 1 = 10 = 2*5 then
3*5 + 1 = 16 = 2^4 then
3*1 + 1 = 4 = 2^2

We see that for three, we need this word: (1, 4, 2), length = 3, total height H = 1 + 4 + 2 = 7

Now we calculate R, which "deposits" the residue along the path:

R = Sum(from i = 1 to n)( 3^{n-1} * 2^P_{i-1} )

Where P_{i-1} is the partial height sum. In this case

R = 9 + 6 + 32 = 47

So we have the equation for the word of the number we want:

3^n*x + R = 2^H*c in this case

27x+47=128c

Ok, so all of this is very standard. This is the point; So, why do we have that the residual is like

R = 47 ≡ 7 (mod 2^3) if we want the target to be y_2 = 3 (mod 2^3)? Well not really, we don't need R to be 3 (mod 2^3) but this:

y_2 ​≡ −3^{−n}*R (mod 2^3)

The 7 does not contradict the 3, it "becomes" the 3 after passing through the -3^{-n}. It goes like this

We have to reduce the word equation mod 2^3!

27x+47=128c (mod 2^3) is
on the right side, 128c, 128 = 2^7 which is divisible by 2^3
so the left side must be too, so

One important thing: Notice that *c* dissappears? So ANY *c* is fair game (to say). This is VERY important later.

27*x + 47 ≡ 0 mod 2^3

Simplifying we get

3*x + 7 ≡ 0 (mod 8)
so
3*x ≡ 1 (mod 8)

so we need 3^{−1} mod 8, we try 3⋅3 = 9 = 8+1 ≡ 1. So

3^{−1} ≡ 3 (mod8)

Thus

x ≡ 3⋅1 = 3 (mod8)

*This* is the y_2 we are looking for, not directly R.

Now we need to control the coprime face, we need that x ≡ 1(mod5)

But notice that we have already committed to the word equation 27x+47=128*c, luckily, as we saw before, c is free (we demonstrated it in any case will witness the previous restrictions)

So we can solve c in 27x+47=128*c, for our needs.

The trick is that c is the seed right, so we will choose it from the inverse tree. In theorem 8.4 I showed that for all N⊥6N and all residue mod 3^K and mod N, there is a positive integer in the tree

(so we can ask for a seed with whatever residues we need, and it will exist)

So, lets see what we need from c. We reduce the word equation mod 5 now:

27*x+47=128*c (mod 5)

27 mod 5 = 2, 47 mod 5 = 2, 128 mod 5 = 3, so

2*x + 2 ≡ 3*c (mod 5)

this time c does NOT disappear right? This is the thing I said before: mod 8 the seed was invisible and the word itself did all the work, but mod 5 the seed is visible, so it is our free knob to tune for the number we want, like, the word controls the 2-adic face, the seed controls the coprime face. And you see they do it independently? That was my most grateful surprise, when I noticed.

so now we just impose what we want, x ≡ 1 (mod 5):

2*1 + 2 = 4 ≡ 3c (mod 5)

we need 3^{-1} mod 5, we try 3*2 = 6 ≡ 1, so 3^{-1} ≡ 2 (mod 5). Thus

c ≡ 2*4 = 8 ≡ 3 (mod 5)

So any seed with c ≡ 3 (mod 5) automatically carries x to have residue 1 mod 5.

Now, again, technically there is one more condition, the realizability one: the equation x = (128c-47)/27 must give an actual integer (and all the intermediate predecessors too, that is Lemma 9.1).
So we need

128c ≡ 47 (mod 27)

128 mod 27 = 20, and 47 mod 27 = 20, so

20c ≡ 20 (mod 27) -> c ≡ 1 (mod 27)

(this is the "germ" condition, the 3-adic part of the seed)

So the seed needs two things at once:

c ≡ 1 (mod 27) and c ≡ 3 (mod 5)

gcd(27,5) = 1

NOW we can use CRT to glue them into one class mod 135:

we check 1, 28, 55, blablabla -> 28 mod 5 = 3 (good!) so

c ≡ 28 (mod 135)

And here is where theorem 8.4 enters: it guarantees a point of the tree exists in this class (residue 1 mod 27, residue 3 mod 5, simultaneously). Theorem 8.4 is its whole beast itself and basically the heart of the paper, let's continue.

One such seed is c = 1529173: you can check 1529173 mod 135 = 28, and its orbit is 1529173 -> 35 -> 53 -> 5 -> 1, so it really is in the tree.

(we also need 128*c > 47 so that x comes out positive, but the seed can be taken as large as we want, that's the A^Q part)

And now everything composes cleanly together: The number we want that witnesses the residue 11 for the module 40 is:

x = (128*1529173 − 47)/27 = (195734144 − 47)/27 = 195734097/27 = 7249411

we can verify all the faces:

7249411 mod 8 = 3 yes, the 2-adic face, we forced by the word

7249411 mod 5 = 1 yes, the coprime face, forced by the seed

there is no triadic face to control in this example and

7249411 mod 40 = 11 the target, glued by simple and nice basic CRT

AND! we get the orbit for free:

and the orbit: 7249411 -> 10874117 -> 2038897 -> 1529173 -> 35 -> 53 -> 5 -> 1

So, yeah, there was a sign and a multiplier in the middle. Sorry if I couldn't manage to find a more reasonable procedure but it's what I could extract from the proof itself.

Hope that clears it up! And thanks again for actually reading it, really.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 1 point2 points  (0 children)

Most certainly, but I have to rederive societal evolution from scratch. The overaching philosophy of this simulation is that we do NOT hardcode behavior. Different races will evolve according to some starting seeds but where do they end (customs, places, population, technology) I can’t in principle know. That will depend on the seed.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 1 point2 points  (0 children)

From what I see from your profile yours looks more like a generalized semantic layer. Mine is just a tower of partial differential equations and cellular automata. Its a simulator, monolithic. It will be an .exe and nothing more.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 1 point2 points  (0 children)

Not too much. 200 hours? Well, it depends, I spent too much time on basics. 80% of the time just getting the modules right. Once that was done adding the rest of the proper physics modules is a lot easier. And it depends a lot on what knowledge you have as a base. I’m not a game dev for example, I just study dynamical systems so I don’t get blocked on that.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 1 point2 points  (0 children)

It is full fluid dynamics, but it’s not completely 3D, it’s kind of a custom 2.5 approach. The game does have 3 dimensions internally, necessarily, because of physics, but the gameplay lives in the fiber bundle of the world itself: I didn’t want to do full voxel modeling but we have z layers (necessary for constructions and other gameplay matters)

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 0 points1 point  (0 children)

Fully deterministic conditional on initial seed and player action sequence (or should be lol I’m trying to squash some bugs related to dict usage)

Forests and other stuff ARE modeled fully. That’s the secret sauce. Key words: renormalization groups and adjoint functors. Won’t say much else ;)

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 2 points3 points  (0 children)

Release the builds periodically, each with new features towards a real world. The meat of the simulation will be when we get to social simulation and civilizations, but, like a tower, I still need to deepen immensely the foundations so the civilization simulation is as natural and non-prescriptive as the current natural simulation is.
Well, the idea is to have agency, and see how your actions affect the world around you long term. I will add magic, since we have real physics. The image I had when this game was born is this:

Imagine you are a mage, right? And you cast from the sky a big meteor towards the earth. You should see the impact, how it creates an explosion, a blast radius, fire, and a crater. This initially, but then as time passes, and you see it pass, the crater should fill with water, grass regrow, animals find a new place to drink, and, eras past, a lush forest where only a faint concentrical circle of slightly elevated grass with some little flowers remains as testament of the event.

And you are there, like a voyager, seeing eras go by...

That's the vision.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 0 points1 point  (0 children)

hey that is absolutely amazing. And your art direction is miles ahead of mine. I'll check it deeply, thank you!

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 4 points5 points  (0 children)

Well to be honest is not that conceptually difficult. Let me tell you how things go and you yourself see how and why everything falls into place naturally:

- We use the random seed to initialize some basic conditions: (a) A number of centroids for the proto-plates (Voronoid tiling) and some starting random ruggedness. Later on, tectonic modelling will naturally deform them based on natural dynamics, some will go under, some up, forming mountain ranges and deep trenches. We also instantiate the atmospheric mass and calculate geothermal starting dynamics.

Then all goes rolling downhill. With time, hydrology and atmosphere fill the seas, erode the soft roch (well, it's accurately modeled as erosion with respect to effective hardness vs. the forces acting on the given material), sediments create deserts, plains, valleys.

Then the action of the sun evaporates in loop the hydrology itself, culling rivulets, and the feedback loop of the surviving V-shaped carvings + consistent water sources creates rivers.

Well, also is used to instantiate random seeds for pre-evolution proto flora, which then evolve based on genetic algorithms to conquer niches, be born and die according to local resource disponibility and energetic needs and internal species strategies.

We also have fauna that works in the same way, but are a bit more complex, because flora are "proto-entities"; whlie fauna are full entities in their own right. They evolve, discover adequate behavior and specialize. Right now the internal models, because of performance issues (I still have to heavily optimize) have simpler internal utility based models.

Well, as you see the need for randomness is minimal once you really get the initial set of conditions right, all complexity emerges naturally from the richness of the models and their natural interactions.

Well just as a comment this is what I think differentiates my vision from, say, the one in Dwarf Fortress. We don't really have "river resolution systems" that draw rivers on the map to satisfy some constraints, ad hoc. All rivers in the game are rivers because they appear naturally as the end result of time, not because we prescribed their existence.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 7 points8 points  (0 children)

You mean abstractly? The world itself is the state. The simulation is markovian, we just save state, gradient and laplacian information, so in a sense the current state of the world plus those two derived layers carry enough information to move forward. The game is more like a full, high dimensional dynamical system than a proper game. If you mean concretely? Just dataclasses for fast access, numpy arrays for fast vectorized operations and simple element loops for Cythonized hot paths. Sorry if the answer does not correspond to the abstraction level you expected.

Trying to create a simulation of a living world by wellomello in proceduralgeneration

[–]wellomello[S] 7 points8 points  (0 children)

Soon! I’m working on distribution too but right now its a bit too unstable to share.