this post was submitted on 01 Sep 2026
517 points (98.7% liked)

Programming

28414 readers
490 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



founded 3 years ago
MODERATORS
 

Daddy needs a new pair of RAM!

edit: the fps are way better in smaller terminal windows with lower character count but then it's hard to make out the dice. D:

edit2: code here (expires in 2 weeks)

top 50 comments
sorted by: hot top controversial new old
[–] AnarchistArtificer@lemmy.world 44 points 1 week ago (1 children)

One of my favourite things in the entire world is what I call "high effort shitposts". Running DOOM on absurd devices like pregnancy tests is the archetypical example I use when explaining this.

Well, congrats, because this is absurd enough that this makes the list too. You are ridiculous and delightful, and I am glad that you exist to create impressive horrors like this.

load more comments (1 replies)
[–] glizzyguzzler@piefed.blahaj.zone 38 points 1 week ago (2 children)

Get this on the berg I wanna render my dice rolls over SSH stat

[–] Pudutr0n@lemmy.world 15 points 1 week ago (10 children)

lol but it's not finished and everyone will see how stupid my code (and brain) is D:

[–] GeirGrusom@lemmy.world 26 points 1 week ago

It's bash. Everyone is expecting nightmare code, and that's why it's fun!

[–] promitheas@programming.dev 9 points 1 week ago (2 children)

My suggestion is do it. Its a cool project, and clearly there is interest from others who could contribute to the project by suggestions, bug fixing, or general collaboration, helping you learn. Just add some kind of disclaimer in the project that its not ready yet, and that youre still learning and it should be fine.

[–] Pudutr0n@lemmy.world 6 points 1 week ago

you make good points

load more comments (1 replies)
[–] BasedMaquisEddington@lemmy.dbzer0.com 8 points 1 week ago (4 children)

I hope you change your mind.

Most people care about features, not the implementation.

Those who dislike your code are probably going to generally dislike others’ code anyways, so in a sense they don’t even need to see your code to already disapprove of it 🤷‍♀️

[–] Pudutr0n@lemmy.world 6 points 1 week ago

Well, you guys are making some p good points. I'll probably end up sharing it, but'll give it a clean up, try to fix some bugs and improve my comments before posting it publicly. For now whoever really wants it (including you) can just ask and I'll dm it, understanding it will be a hard read and still has bugs.

load more comments (3 replies)
[–] prole@lemmy.blahaj.zone 7 points 1 week ago (1 children)

Cut yourself some slack. These days, most people would have just pasted LLM outputs

load more comments (1 replies)
load more comments (5 replies)
[–] Pudutr0n@lemmy.world 7 points 1 week ago (8 children)
load more comments (8 replies)
[–] oce@jlai.lu 37 points 1 week ago (1 children)

I'm curious why it seems the time slows down at the end compared to reality? Because more computation is needed to check if it's a stable state?

[–] Pudutr0n@lemmy.world 32 points 1 week ago (5 children)

the final resolution stage was a huge headache and as you can see, one I didn't fully solve. Basically when the dice finally settle, particularly those with more sides, lots and lots of micro collisions happen in close sequence, each one having to apply friction and bounce back. As velocities come close to be rounded to 0, the bounce back effect and force of gravity no longer provide movement, but the final angle of the bottom face may not be fully settled on the floor. So basically if i don't ignore all these tiny collisions I get the frame rate drop you see and if I do, I can arrive at not fully settled states which can become ambiguous result-wise in, say, the 20-sided die.

[–] hirihit640@sh.itjust.works 9 points 1 week ago (1 children)

Can you predict the resolution when it is close enough to settled? Worst case maybe have an algorithm that estimates the probability of each face ending up on top, and if one face is overwhelmingly more probably, choose it. Otherwise let it settle using your physics engine

[–] Pudutr0n@lemmy.world 9 points 1 week ago (2 children)

I can easily check for when motion stops, but checking for when any particular face is both parallel to the floor and at the same level can be computationally expensive, particularly in the dice with more sides. What you're suggesting is likely a good idea, but I wouldn't know how to get probabilities without doing what I just mentioned. I'm sure there's an optimization i can do with this that I can't think of rn.

[–] hirihit640@sh.itjust.works 8 points 1 week ago* (last edited 1 week ago) (1 children)

maybe just "if velocity < 0.01, find which side is closest to the floor, and if its within 1mm of the floor, take the opposite side (the one facing up) as the answer"

The only edge case I can think of is if it gets close to balancing on an edge, and then finally tips over to one side or the other. But in that case I don't think the face closest to the floor would be within 1mm of the floor, so it should still work.

[–] Pudutr0n@lemmy.world 6 points 1 week ago (1 children)

that's how it's implemented, mostly, but sometimes dice "stop" while they're still tilted and standing on a corner (and then roll back down, possibly going back more than 1 face) so there's also that.

load more comments (1 replies)
load more comments (1 replies)
load more comments (4 replies)
[–] farmgineer@nord.pub 22 points 1 week ago (1 children)

Are you often described as a masochist?

It looks neat. I can't imagine wanting to write it in bash, though, heh.

[–] Pudutr0n@lemmy.world 18 points 1 week ago

XD I am! And it was a complete nightmare. hahaha

[–] spacegoat@lemmy.world 19 points 1 week ago (1 children)

Do you think God stays in heaven because he too lives in fear of what he's created?

[–] Pudutr0n@lemmy.world 12 points 1 week ago

God comes over
creates some bullshit
stays in heaven
refuses to elaborate

[–] MonkderVierte@lemmy.zip 16 points 1 week ago (1 children)

(hopefully) Constructive critique:

  • it looks like you're handling the dice in physics as a ball? Takes forever to settle at the end.
  • the throw has a visual glitch.
[–] Pudutr0n@lemmy.world 16 points 1 week ago (1 children)

Thanks! Yeah, there's definitely A LOT of room for improvement. collisions are handled per vertex, but torque is applied to angular impulse to the dice as a whole (like a ball I guess). The settling is a huge issue, yes. the visual glitches I've been trying to get rid of but man... fix one and then another one pops up in a different case. Thanks for your critique. :)

[–] Atherel@lemmy.dbzer0.com 6 points 1 week ago

I first read it as "there's a lot of DOOM for improvement" but as the rest of your comment confirmed this, I'll keep it that way in my head!

[–] RheumatoidArthritis@mander.xyz 16 points 1 week ago (2 children)

Haha nice! How long did it take you? Integer-only math?

[–] SpaceNoodle@lemmy.world 22 points 1 week ago (1 children)

All computer math is integer math if you go deep enough

[–] RheumatoidArthritis@mander.xyz 9 points 1 week ago (3 children)

I'm sure implementing floating point directly in bash would work great

[–] RheumatoidArthritis@mander.xyz 17 points 1 week ago (1 children)

I didn't have the patience to do it myself bit wanted to see just how complex it would get:

fp32_mul() {
    local a=$1 b=$2
    local sa=$(( (a >> 31) & 1 ))
    local sb=$(( (b >> 31) & 1 ))
    local sign=$((sa ^ sb))

    local ea=$(( (a >> 23) & 0xff ))
    local eb=$(( (b >> 23) & 0xff ))
    local fa=$(( a & 0x7fffff ))
    local fb=$(( b & 0x7fffff ))

    # NaN / infinity / zero handling
    if (( ea == 255 )); then
        if (( fa != 0 )); then
            printf '%08x\n' $((0x7fc00000))
            return
        fi
        if (( eb == 0 && fb == 0 )); then
            printf '%08x\n' $((0x7fc00000))   # inf * 0 = NaN
            return
        fi
        printf '%08x\n' $(((sign << 31) | 0x7f800000))
        return
    fi

    if (( eb == 255 )); then
        if (( fb != 0 )); then
            printf '%08x\n' $((0x7fc00000))
            return
        fi
        if (( ea == 0 && fa == 0 )); then
            printf '%08x\n' $((0x7fc00000))
            return
        fi
        printf '%08x\n' $(((sign << 31) | 0x7f800000))
        return
    fi

    if (( ea == 0 && fa == 0 || eb == 0 && fb == 0 )); then
        printf '%08x\n' $((sign << 31))
        return
    fi

    # Convert subnormals to a normalized significand/exponent.
    # m is a 24-bit significand for normals.
    local ma mb
    if (( ea == 0 )); then
        ma=$fa
        ea=1
        while (( (ma & 0x800000) == 0 )); do
            ma=$((ma << 1))
            ((ea--))
        done
    else
        ma=$((fa | 0x800000))
    fi

    if (( eb == 0 )); then
        mb=$fb
        eb=1
        while (( (mb & 0x800000) == 0 )); do
            mb=$((mb << 1))
            ((eb--))
        done
    else
        mb=$((fb | 0x800000))
    fi

    # Multiply the two 24-bit significands.
    # Product is up to 48 bits.
    local p=$((ma * mb))
    local e=$((ea + eb - 127))

    # Normalize product.
    #
    # ma*mb has binary point after bit 46.  If bit 47 is set,
    # product is [2,4), otherwise [1,2).
    local shift
    if (( p & 0x800000000000 )); then
        shift=24
        ((e++))
    else
        shift=23
    fi

    # Extract 23 fraction bits plus guard/round/sticky information.
    local frac=$(( (p >> shift) & 0x7fffff ))
    local guard=$(( (p >> (shift - 1)) & 1 ))
    local round=$(( (p >> (shift - 2)) & 1 ))
    local sticky=0

    if (( shift >= 3 )); then
        local mask=$(( (1 << (shift - 2)) - 1 ))
        (( (p & mask) != 0 )) && sticky=1
    fi

    # Round-to-nearest, ties-to-even.
    if (( guard && (round || sticky || (frac & 1)) )); then
        ((frac++))
        if (( frac == 0x800000 )); then
            frac=0
            ((e++))
        fi
    fi

    # Overflow -> infinity.
    if (( e >= 255 )); then
        printf '%08x\n' $(((sign << 31) | 0x7f800000))
        return
    fi

    # Normal result.
    if (( e > 0 )); then
        printf '%08x\n' $(((sign << 31) | (e << 23) | frac))
        return
    fi

    # Underflow into the subnormal range.
    #
    # At this point the normalized significand represented by
    # (1.frac) must be shifted right by 1-e positions.
    local mant=$((0x800000 | frac))
    local rshift=$((1 - e))
    local lost=0
    local halfway=0
    local low=0

    if (( rshift >= 25 )); then
        # Everything rounds to zero (unless the exact value is
        # sufficiently close, which it cannot be here).
        mant=0
    else
        low=$((mant & ((1 << rshift) - 1)))
        mant=$((mant >> rshift))

        halfway=$((1 << (rshift - 1)))

        if (( low > halfway || (low == halfway && (mant & 1)) )); then
            ((mant++))
        fi
    fi

    # Rounding a subnormal can produce the smallest normal.
    if (( mant >= 0x800000 )); then
        printf '%08x\n' $(((sign << 31) | (1 << 23)))
    else
        printf '%08x\n' $(((sign << 31) | mant))
    fi
}
[–] RheumatoidArthritis@mander.xyz 15 points 1 week ago (1 children)

1440 multiplications per second on my computer!

[–] Womble@piefed.world 19 points 1 week ago

Wow, over a kiloflop!

[–] Pudutr0n@lemmy.world 7 points 1 week ago

hahaha you seem to be familiar with the issues I ran across

load more comments (1 replies)
[–] Pudutr0n@lemmy.world 15 points 1 week ago (2 children)

Jebus I don't even know how long I've been working on this. It started out as a way to teach myself bash, combined with my long obsession with rendering platonic solids. I previously coded a huge galaxy of hundreds of thousands of polyhedra you could fly across in python with opengl shaders and got to reuse/translate a lot of that code. The quaternion stuff I was grateful to not have to rethink that much again. haha. And yes, integer-only! Some params are "floating point" but i just parse them and add a bunch of zeroes so i can later do all the operations with equally blown up values of pi and trig stuff from "lookup tables" (case matching).

[–] MonkderVierte@lemmy.zip 6 points 1 week ago (1 children)

Btw, you could pipe it to bc for the odd float. Or even some complex math. Just in case you didn't know.

[–] Pudutr0n@lemmy.world 6 points 1 week ago

yeah, I was trying to stay as pure-bash as possible, but thanks!

load more comments (1 replies)
[–] thingsiplay@lemmy.ml 16 points 1 week ago (1 children)

I just woke up and this is the first thing I see. Did I really woke up?

[–] adhocfungus@midwest.social 15 points 1 week ago

Absolutely insane. Part of me wants to see the source code, but part of me is terrified of how complex it must be. Plus I've only been writing bash for 20 years, so it would probably look incomprehensible to me.

[–] Aqivex@fedinsfw.app 14 points 1 week ago (1 children)

@Pudutr0n@lemmy.world - You are certifiably insane. There are a million more effective ways to achieve this, with less resources... I LOVE IT.

[–] Pudutr0n@lemmy.world 8 points 1 week ago

This is exactly the kind of flattery that truly touches my heart. <3

[–] alphabethunter@lemmy.world 13 points 1 week ago (1 children)

This is beautiful, and insane! But truly beautiful hahaha

[–] Pudutr0n@lemmy.world 6 points 1 week ago

Thank you! haha

[–] mike_wooskey@lemmy.thewooskeys.com 8 points 1 week ago (2 children)

I'm viewing this thread in Lemmy and am unable to find any mention of a link to the source code or a demo, and I can't see the attached media (genetic image icon - is it an animated gif or a video?).

Based on all the comments, I appear to be in the [significant] minority. Would you mind posting a link to your source or demo or image/video?

[–] Pudutr0n@lemmy.world 19 points 1 week ago (10 children)

I haven't shared the source code yet because criticism is terrifying and I'm a horrible coder, but with the encouragement of the the community I might give it a shot. I don't even have a codeberg account yet though.

The post contains these two video links: https://files.catbox.moe/8rz9m7.mp4 https://files.catbox.moe/5d3n2k.mp4

If you still can't see them, maybe you can suggest a different hosting service, one that works for you? Or if you really really want the source code I suppose I could send it by DM on the meantime.

[–] oce@jlai.lu 12 points 1 week ago

There are millions of professional coders who couldn't do what you did there.

[–] vrek@programming.dev 6 points 1 week ago (1 children)

Just letting you know the original post video didn't load and gave a 500 error in jerboa but those two links work. Looks impressive but I'm confused on how to read the die. Yes there is a giant banner telling me the value it chose but I'm struggling to figure out how the visuals map to those values, can you give some details on how to read the die?

[–] Pudutr0n@lemmy.world 6 points 1 week ago* (last edited 1 week ago) (4 children)

Yes, the values are rendered on top of each face with "pixel" maps (ascii art) that have the character of the digit they represent as each pixel. These are later manipulated by the perspective projection.

For example on this d6 you can see the top face has 1s written down (in the shape of a sideways one) and the front one has 4s written down in the shape of a skewed and sideways 4.

In this specific color scheme there's not a lot of contrast between the values, but even in the palettes with better contrast, good readability is something I'm kind of giving up on solving well.

edit: might be clearer here:

load more comments (4 replies)
load more comments (8 replies)
load more comments (1 replies)
[–] cristian64@reddthat.com 8 points 1 week ago (1 children)

I didn't know I needed this.

load more comments (1 replies)
[–] Gsus4@mander.xyz 8 points 1 week ago* (last edited 1 week ago) (1 children)

3D dice rolling...ok...😐 ... in bash ...🤨 !?

PS: I remember seeing something vaguely like this recently...this you?

load more comments (1 replies)
[–] HeHoXa@lemmy.zip 7 points 1 week ago (1 children)
load more comments (1 replies)
[–] albbi@piefed.ca 7 points 1 week ago (1 children)

Looks like a great sl replacement! Gonna need this on every machine.

load more comments (1 replies)
load more comments
view more: next ›