ID:1780103
 
(See the best response by DarkCampainger.)
Code:
world
New()
..()
OnlineList()

proc
OnlineList()
var/counter=0
for(var/mob/Player/M in world)
winset(M,"onlineusers","current-cell=[++counter]")
M << output("[M] ([M.key])","onlineusers")
spawn(10) OnlineList()


Problem description:

I'm very very new to this system and have seen no threads, no demos, and no libraries on these forums which breach this particular scenario, which makes me think doing this is either impossible, impractical, or so incredibly easy that I should feel dumber than a monkey for not understanding why this isn't working, despite being nearly copypasta from one of the "tutorial" threads that exist by Lummox JR.

All I want to do is have a grid called "onlineusers" in my game update every second on all players' screens with a list of all players who are currently logged in, with their name, key, and an icon view of their "avatar" (which I have not included here because god help me I can't even place simple text let alone images next to it).

I'm going to wind up needing similar things for other "lists" in my game that update every second (granted those will be for objects, not mobs), and I can't even get one to work right. Pls send help.
Best response
Your problem is likely that you're only outputting the current mob's name to the current mob itself:
M << output("[M] ([M.key])","onlineusers")

Also, a new syntax has become available since Lummox JR's tutorials that lets you specify the cell in the output() command itself:

You can send output to a particular grid cell without having to use winset() first to change the current-cell. Instead of just using the grid's ID in output(), use "[id]:[column],[row]" instead. Or if the grid is using is-list, "[id]:[item]" will do.

Once you've output the names, you'll want to update the cell count. The grid will automatically grow to fit whatever you output, but it won't shrink. So, if someone leaves and the list length decreases, the old names at the end of the list won't be cleared.

With those things taken into account, you get something like this:
proc
OnlineList()
var/counter=0
for(var/mob/Player/M in world)
if(M.client)
world << output("[M.name] ([M.key])","onlineusers:[++counter]")
for(var/mob/Player/M in world)
if(M.client)
winset(M,"onlineusers","cells=[counter]")
spawn(10) OnlineList()


Later on, especially if you're going to be outputting more lists like these, you might want to consider only updating them when someone joins/leaves the game, instead of every second.
I think this part right here is the MVP. I was completely unaware that "world <<" could be used in such a manner.
world << output("[M.name] ([M.key])","onlineusers:[++counter]")

I think that'll come in handy down the line with other lists. I haven't dropped it into my code yet, but I trust that it'll work.

I have seen some comments regarding only updating things in an ad-hoc manner, rather than having a constantly updating loop, but I feel as though that leaves too many doors open for weird situations that I cannot account for, not to mention having to implement a bunch of calls back to the same proc.

Why should actively displaying the contents of a list at all times be considered bad? The only thing I'm able to really take home from those discussions is questionable efficiency. Is there really no efficient way of accomplishing realtime displays?
In response to BladePwnsYou
BladePwnsYou wrote:
I have seen some comments regarding only updating things in an ad-hoc manner, rather than having a constantly updating loop, but I feel as though that leaves too many doors open for weird situations that I cannot account for, not to mention having to implement a bunch of calls back to the same proc.

Why should actively displaying the contents of a list at all times be considered bad? The only thing I'm able to really take home from those discussions is questionable efficiency. Is there really no efficient way of accomplishing realtime displays?

As you become better at code design and organization, you'll find the number of situations and edge cases you have to account for become smaller and smaller. You'll write code to be encapsulated from other systems, so there's only one, well-controlled path of interaction with it. Then you can more easily make assertions such as "if a player ever enters the game, leaves, or changes their name, this proc is guaranteed to run and update my lists".

It's mostly for efficiency's sake, both in terms of CPU and network bandwidth. Why have a bunch of loops spewing out data every second when that data rarely changes? Realistically, how often will a player leave or join the game? Maybe every five minutes? That's 299 unnecessary updates you're uploading to all of your players. Updating a grid cell can also occasionally cause a flicker as it refreshes. Further, updating data when it changes could be seen as more responsive/realtime, as the update is sent immediately instead of up to one second later with a loop.

All that said, at the end of the day, you just want to get your game done. Unless it gets out of hand and starts causing problems, you shouldn't feel a need to change it. Resist the urge for premature optimization, it has killed many a project. But, if you start seeing those loops in the profiler taking up significant CPU time, or you're maxing out your bandwidth, it might be worth keeping in mind as a possible optimization point.