ribrdb / desynced-tools

Tools for working with behaviors and blueprints from Desynced.
MIT License
4 stars 3 forks source link

Implement literals #44

Closed swazrgb closed 6 months ago

swazrgb commented 6 months ago

Scripts can assign numbers and entities using literal numbers & strings:

let num: Value = 10;
let id: Value = "c_battery";

Entity & number pairs can be assigned using the value builtin function, or as a casted object.

let pair1 = value("c_battery", 10);
let pair2 = {
  id: "c_battery",
  num: 10
} as ItemNum;

Coordinates can be assigned using the coord builtin function, or as a casted 2-element number array.

let coord1 = coord(10, 20);
let coord2 = [10, 20] as Coord;

One drawback of the new typing system is that arthimetrics aren't allowed by default, and the Value type has to be coerced to a number first. Fortunately this is easy to do:

let v: Value = "c_battery";
v = +v + +v; // prefix with +
v = v as number + 1; // cast
v = 1 + v; // reverse the expression if adding a constant
swazrgb commented 6 months ago

@ribrdb ping

I've tried various alternatives since, mostly to work around having to write const v: Value = +v + +v for math, but nothing works well while still allowing literals such as "c_battery" or 5 to be assigned to Value typed variables: const v: Value = 5.

The best alternative would be requiring the usage of the value function in all cases, so const v: Value = value("c_battery") or const v: Value = value(5)

ribrdb commented 6 months ago

I've tried various alternatives since, mostly to work around having to write const v: Value = +v + +v for math, but nothing works well while still allowing literals such as "c_battery" or 5 to be assigned to Value typed variables: const v: Value = 5.

I was thinking of just adding num: number to the BaseVar interface so you could optionally use v = v.num + v.num instead of unary-plus. I haven't tested to see if that would work though.

The best alternative would be requiring the usage of the value function in all cases, so const v: Value = value("c_battery") or const v: Value = value(5)

Actually I kind of like that

swazrgb commented 6 months ago

I was thinking of just adding num: number to the BaseVar interface so you could optionally use v = v.num + v.num instead of unary-plus. I haven't tested to see if that would work though.

That should work. It feels a bit odd to me to provide a fake property for this. Internally the .num accessor would just be a no-op, existing purely to get the typescript to compile.

Actually I kind of like that

I don't mind it for variable assignments, but it's awkward for function calls. For example having to write entitiesInRange(5, value("v_mineable")) would be unfortunate.

This seems doable to support:

let v: Value; // Declare variable/params as Value
v = 5; // numbers are directly assignable
v = v + 5; // Values & numbers can be used in math as-is
v = value("metalore"); // string assingments must be wrapped in `value` 
v = value("metalore", 5); // NumPairs need the value function as well of course

v = "metalore"; // Not allowed! Must use value("metalore");

entitiesInRange(5, "v_mineable"); // literal strings can be supported as function arguments

I'll give this a go.

swazrgb commented 6 months ago

That was pretty straightforward. Could you please take another look, @ribrdb ?

ribrdb commented 6 months ago

This looks great, thanks! Just a couple comments