ID:1355066
 
(See the best response by Ter13.)
Code:
scoreboard
addScore(mob/m)
..()
if(m.key in src.scores)
if(m.number.value > src.scores[m.key]["value"])
src.scores[m.key] = list("value"=m.number.value,\
"mob_name"=m.name,\
"date"=world.timeofday)
else
src.scores.Add(m.key)
src.scores[m.key] = list("value"=m.number.value,\
"mob_name"=m.name,\
"date"=world.timeofday)
if(src.scores.len > 5)
src.scores.Cut(src.MAX, src.scores.len)

sortScores()
//bubblesort
if(src.scores.len > 1)
for(var/i=1, i<src.scores.len, i++)
var/list/L1 = src.scores[i]
var/n1 = L1["value"]
world<<n1
var/list/L2 = src.scores[i+1]
var/n2 = L2["value"]
world<<n2
if(n1 < n2)
src.scores.Swap(i, i+1)


Problem description:
The line that poops out the bad index is the line where I define n1.

runtime error: bad index
proc name: sortScores (/scoreboard/proc/sortScores)
source file: Scoreboard System.dm,67
usr: Spunky_Girl (/mob)
src: /scoreboard/str (/scoreboard/str)
call stack:
/scoreboard/str (/scoreboard/str): sortScores()
Spunky_Girl (/mob): add score()
Best response
First of all, associative lists cannot have duplicate keys.

You need to set up your list like so:

var/list/scores = list(m.number.value,m.name,world.timeofday)


When sorting your scores, you need to interpret your list with the knowledge that every three elements is one block of values, and increment accordingly.

sortScores()
var/bubname
var/bubtime
var/bubval
for(var/i=1;i<src.scores.len-3;i+=3)
bubval = src.scores[i]
if(bubval<src.scores[i+3])
bubname = src.scores[i+1]
bubtime = src.scores[i+2]
src.scores[i] = src.scores[i+3]
src.scores[i+1] = src.scores[i+4]
src.scores[i+2] = src.scores[i+5]
src.scores[i+3] = bubval
src.scores[i+4] = bubname
src.scores[i+5] = bubtime


In addition, don't define variables inside of loops if it can be avoided. It leverages extra opcodes onto the virtual machine, which can be avoided. It's best to identify variables outside of the main loop's jump blocks.
1. I have no idea what you're talking about regarding identical IDs with my associative list. I'm not using IDs as far as I am aware.

The list structure is the following...
list("[key]" = list("[value to be sorted by]","[name of mob]","[date the value was added/changed]"))


2. You can refer to associated values with text if that's what the value is, such as...
var/list/L = list("index1"=5,"index2"=3)
world<<L["index2"]
//will output 3 to the world


3. The way I programmed it right now is for readability purposes. This is by no means how I actually code such a bubble sort haha. It's to illustrate each individual step of the accessing process to grab the value I want to compare. And since the line where I define n1 is what's giving me the error, I now know it's the associated list that is giving me the issue and not anything else.
What I do not understand, is that I can output everything in the list and its associated list just fine and received no errors using the following...

mob/verb/view_scores()
for(var/k in scoreboard.scores)
src<<"[k] - [scoreboard.scores[k]["value"]]"
//and so on for each one
Oh wow I'm an idiot haha.

Apparently when using indices to reference spots in a list, it will return what is in that spot, rather than it's associated value (y'know... like it's supposed to). But when you reference a spot in a list with a text value, it will return it's associated value. To put it simply, the following is how BYOND works...
var/list/L = list("spot1"=500, "spot2"=40)

world<<L[1] //outputs "spot1"
world<<L["spot1"] //outputs 500
world<<L[2] //outputs "spot2
world<<L["spot2"] //outputs 40


This seems rather confusing and counter-intuitive to me.
Edit: I should refresh before I reply.

You are setting a list to the value of a string (m.key).
    sortScores()
//bubblesort
if(src.scores.len > 1)
for(var/i=1, i<src.scores.len, i++)
var/Key1 = src.scores[i]
var/n1 = src.scores[Key1]["value"]
world<<"N1 : [n1]"
var/Key2 = src.scores[i+1]
var/n2 = src.scores[Key2]["value"]
world<<"N2 : [n2]"
if(n1 < n2)
src.scores.Swap(i, i+1)
Yeah that bubble sort was coded wrong anyways. But the problem was still there regardless.

Fixed.
proc
bubbleSort(list/L)
var/num1
var/num2
if(L.len > 1)
for(var/x=1 to L.len-1)
for(var/y=x+1 to L.len)
num1 = L[L[x]]["value"]
num2 = L[L[y]]["value"]
if(num1 < num2)
L.Swap(x,y)
When I said IDs, I meant value keys. There's no real reason to be using key-value pairs for a sorted list like this one. It's just causing you extra work and confusion.
It was only confusing because I had forgotten how DM worked for the time when it came to lists. Now that I understand it, looking at this code doesn't confuse me. I just find it weird is all.