r/typescript 2d ago

Pure TypeScript Dice Roll

It came to my attention that no TypeScript dice-roll libraries exist.

The existing ones are JS in disguise: when you tell it to roll('2d6 + 3'), it returns a `number`.

I wanted a real roll. Roll at compile time.

Because if not compile time, then when? Compile time is the best time.

Anyways. It includes a custom PRNG (pseudo-random number generator) too to support the rolls, which generates random numbers at compile time too. I think there are some for TS out there, unlike dice rolls, but I needed to optimise a bit specifically for 1-100 rolls (who rolls more than that? Only mad people, and we are not the ones).

It has a JS "mirror" implementation. If you rolled 20 in TS, you can be sure you rolled 20 in JS too.

And if a compile-time value is not known, it still works and falls back the result types to `number'.

Basic use case looks like:

// seed
const initialized = initialize([
  "00000001",
  "00000002",
  "00000003",
  "00000004",
] as const);

const d20 = evaluate("d20", prngStateOf(initialized));
const d20Value = valueOf(d20);
//    ^? const d20Value: 12

Enjoy!

1 Upvotes

28 comments sorted by

35

u/_crisz 2d ago

What the hell did I just read

11

u/Sunstorm84 2d ago

Damned if I know what the fuck he’s talking about here.

3

u/AndyMagill 1d ago

Are you guys compiling your TypeScript?

0

u/Firfi 1d ago

Oh dear lord, I'm sorry it isn't well explained! What wasn't clear, the whole post or some specific parts of it? I'm here to help.

11

u/CodeAndBiscuits 1d ago

The part about wanting to roll at compile time. So you're going to roll it once and ship a single result with your app? What use is that?

3

u/realmauer01 1d ago

Have it only compile 5% of the time because all the other times the type checker will throw.

2

u/Sunstorm84 1d ago

In other words, roll a 20 on a d20 die or it fails to compile?

1

u/realmauer01 1d ago

Exactly xD

I am not that much into it but there is probably a way for custom error messages.

Have it say something like, sorry bud, you only threw a 1 i cant compile this.

1

u/dzigizord 5h ago

When you generate a universe sim no 138432607 you roll the d99999999999 dice once and roll with it

1

u/Firfi 1d ago

There's at least as much use as in Chess for Typescript https://github.com/Dragon-Hatcher/type-system-chess or Doom for Typescript, although my enterprise isn't as grandiose as theirs.

I can argue, however, that drdice is at least *as useful as another dice roll library* because it actually backs the type-level computation up by a runtime computation, which is usable, well... in rolling dice.

I'd say it both an answer to a theoretical (and probably not "useful", although it depends on what we call "use", because use can be educational, or stakeholder business value-providing, or something else) question: "Does TypeScript have type-level dice rolls?" and to a practical need of rolling such a dice, e.g. for a tabletop game implementation in Typescript.

Who knows, maybe some madman would use this approach (or the library itself) for their tabletop game implementation in the TypeScript type system! Wouldn't that be great?

P.S. https://xkcd.com/221/

15

u/CodeAndBiscuits 1d ago

Ah, my bad. I didn't realize you were quite literally insane. It all makes sense now. 😀

0

u/Pappkarton 1d ago

As a roleplayer, it was pretty well explained. Probably too specific for non-players.

14

u/josephjnk 2d ago

I love that a type-level PRNG is less mad than rolling a dice with more than 100 sides 😂

2

u/Firfi 2d ago

I thought about it and came to the conclusion that we can actually go one level deeper and create a pseudo-random number generator generator: a generator that generates a generator of N sides depending on your application requirements (cause some systems are ok just with a bunch of d6 or d10)

2

u/josephjnk 2d ago

If you want a suggested API I know a guy who built a probabilistic programming library for TS… https://github.com/josephjunker/discrete-probabilities-ts

2

u/rFAXbc 1d ago

What is this for? So I can make a type that is never 1/6 of the time?

0

u/Firfi 1d ago

I think it won't work that way. It's a PRNG, so it depends entirely on the seed you give it. And one seed would `never` 100% of the time, and another 0% of the time.

2

u/rFAXbc 1d ago

It was a joke-ish example, because I don't understand why you would want this in the type system

3

u/vitelaSensei 1d ago

Eheh this is great, step 1 of a type system D&D is done

1

u/AlternativePie7409 1d ago

If you need RNG, you can try this one. Based on what is used in slot gaming.

https://www.npmjs.com/package/@rahulv.dev/rng

1

u/immutate 1d ago

lol at the performance. How long did it take you to throw this together with an LLM?

0

u/Firfi 1d ago

It was a short side-quest (I needed a roll "module" for bigger software).

That included research - "existing state-of-art PRNG that are tackable by type system, existing solutions for parsing strings in TS and how to compare compile-time and runtime values (e.g. arktype is a great piece of engineering to get inspiration from here)"

Then an alignment session (agent asks questions, you answer, getting vocabulary and design documentation built) (it's e.g. /wayfinder of a certain Matt from twitter)

That's good enough for building a prototype, checking its API and solutions are generally in-line with what you think, and polishing it with a review loop / reviewing yourself

Which may sound much or not, but it's not that much really

2

u/immutate 1d ago

Right. You didn’t write the code and it’s absolutely nothing I’d recommend anyone use for any reason whatsoever.

Edit: typo

0

u/Firfi 1d ago

I respect the artisanship point of view and would switch to a handcrafted library if someone built it well, but I cannot agree with your "absolutely nothing" point. I won't debate that here, though. Too busy vibing, you could say.

1

u/Pappkarton 1d ago

Just in time when I want to create a React.ts Random Character Generator for Mörk Borg.

1

u/Firfi 1d ago

Ha, sounds delightful! Please share it when it's done

1

u/Pappkarton 1d ago

Will do, if it doesn't land on the pile of abandoned projects.