ID:2933186
 
Not a bug
BYOND Version:515
Operating System:Windows 10 Home
Web Browser:Chrome 126.0.0.0
Applies to:Dream Maker
Status: Not a bug

This is not a bug. It may be an incorrect use of syntax or a limitation in the software. For further discussion on the matter, please consult the BYOND forums.
Descriptive Problem Summary:
Running the code results in runtime error: bad index
Code Snippet (if applicable) to Reproduce Problem:
#define ADD_STAT(ID,VALUE) stats[ID] = new/value_range(VALUE,VALUE)

value_range
var min
var max
New(min,max=min)
src.min = min
src.max = max
proc
operator+=(value=0)
min += value
if(min > max){min = max}
return min
operator-=(value=0)
min -= value
world << "value is now [min]"
if(0 > min){min = 0}
return min

stats
var list/stats = new
proc
operator[](ID)
return stats[ID]
//
player/New()
ADD_STAT("Health", 99)
ADD_STAT("Attack", 99)
ADD_STAT("Strength", 99)
ADD_STAT("Defense", 99)
ADD_STAT("Cooking", 99)
ADD_STAT("Woodcutting", 99)
ADD_STAT("Firemaking", 99)
npc/New()
ADD_STAT("Health", 3)
ADD_STAT("Attack", 1)
ADD_STAT("Strength", 1)
ADD_STAT("Defense", 1)

mob/var/stats/stats = new/stats/player

mob/Login()
var min = stats["Health"].min
var max = stats["Health"].max
world << "Your Health is [min]/[max]"
stats["Health"] -= 10


Expected Results:
No runtime
Actual Results:
Runtime
In addition to the above

var min = stats["Health"].min
var max = stats["Health"].max


can be replaced with

var min = stats["Health"]["min"]
var max = stats["Health"]["max"]


And still works O_O
Have you tried adding an override for []= in your stats list? I think that might well be the problem.

But it would help to know which line produces the runtime error.
stats["Health"] -= 10

That is the line producing the error, adding a override for []= fixes it, even tho it's just a empty override. It's also not being accessed anywhere via []= so I'm confused on why it would be needed.
So here's the long explanation (for posterity since this was brought up in BYONDiscord):

When you override [] it only overrides the read, but []= overrides the write operation. BYOND doesn't have reference pointers like C++, where in C++ you'd override an operator like this:

Thing& operator[](int index) {return my_array[index];}

Pointers didn't exist when operator overloading was added to BYOND, but even now there isn't a concept equivalent to a pointer that's already dereferenced so you can just assign to it. (Having operator[] able to return a pointer would be pretty sweet though.) So that's why separate overrides are used for [] and []=.

Anyway stats["Health"] -= 10 does this:

1) Read stats["Health"] using the operator[] override.
2) Perform - 10 or -= 10 on the value that was read; in this case -= since you have an operator defined for that. Your operatior-= returns src by default.
3) Assign the result of the operation, which in this case is the same object you read, back into stats["Health"]. Since there's no []= override, that's why the bad index error pops up.
Lummox JR resolved issue (Not a bug)