• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [Solved]Display a ds_priority in the UI

B

Blaize

Guest
Hey guys,

I'm creating a turn-based combat system that displays which character is next to have their turn somewhere on the screen (as of now, it's in the top left). For this, I'm using a Priority Queue to sort the characters by their Speed stat, and then taking those values and placing them into a List which I then draw on the UI.
The issue I'm having is that the list shows the characters in id order instead of their Speed stat.
This is how it looks:
TurnOrder.jpg
Here's how I've got the code set up:
Code:
var _spawnpoints = instance_number(oSpawnPoint);
for (var i = 0; i<_spawnpoints; i++)
{
      var _point = instance_find(oSpawnPoint,i);
      instance_create_depth(_point.x,_point.y,0,oPlayer);
}
Actors = ds_priority_create();
UIList = ds_list_create();
with(bCombatActor) //Place into a priority queue based on relevant stats
{
      ds_priority_add(mCombat.Actors,id,Speed);
}
//Add the units to the UIList
while(ds_priority_size(Actors)>0)
{
      ds_list_add(UIList,ds_priority_delete_max(Actors));
}
ds_priority_destroy(Actors);
How the above code works:
- Spawn the characters(Actors)
- Place them into a ds_priority based on their Speed (random values at this stage)
- Take the max priority value and place it into a list (UIList)
I assumed that since we use ds_priority_delete_max() to place characters into the list, it would place them in order of priority (which is their Speed stat).

Here's how I'm drawing the UI. Eventually, I will have this displaying character portraits instead of text:
Code:
for (var i=0;i<ds_list_size(UIList);i++)
{
    var _id = instance_find(bCombatActor,i);
    draw_text_color(0,i*16,string(_id)+",speed: "+string(_id.Speed),c_blue,c_blue,c_blue,c_blue,1);
}
Thanks guys
 
T

Timothy

Guest
Hey guys,

I'm creating a turn-based combat system that displays which character is next to have their turn somewhere on the screen (as of now, it's in the top left). For this, I'm using a Priority Queue to sort the characters by their Speed stat, and then taking those values and placing them into a List which I then draw on the UI.
The issue I'm having is that the list shows the characters in id order instead of their Speed stat.
This is how it looks:
View attachment 24618
Here's how I've got the code set up:
Code:
var _spawnpoints = instance_number(oSpawnPoint);
for (var i = 0; i<_spawnpoints; i++)
{
      var _point = instance_find(oSpawnPoint,i);
      instance_create_depth(_point.x,_point.y,0,oPlayer);
}
Actors = ds_priority_create();
UIList = ds_list_create();
with(bCombatActor) //Place into a priority queue based on relevant stats
{
      ds_priority_add(mCombat.Actors,id,Speed);
}
//Add the units to the UIList
while(ds_priority_size(Actors)>0)
{
      ds_list_add(UIList,ds_priority_delete_max(Actors));
}
ds_priority_destroy(Actors);
How the above code works:
- Spawn the characters(Actors)
- Place them into a ds_priority based on their Speed (random values at this stage)
- Take the max priority value and place it into a list (UIList)
I assumed that since we use ds_priority_delete_max() to place characters into the list, it would place them in order of priority (which is their Speed stat).

Here's how I'm drawing the UI. Eventually, I will have this displaying character portraits instead of text:
Code:
for (var i=0;i<ds_list_size(UIList);i++)
{
    var _id = instance_find(bCombatActor,i);
    draw_text_color(0,i*16,string(_id)+",speed: "+string(_id.Speed),c_blue,c_blue,c_blue,c_blue,1);
}
Thanks guys
You are drawing them by order of instance id because you are pulling from instance_id array... you should be pulling from your list you made.

EDIT: Also, I can almost guarantee that the way you are using your priority_queue is likely slower than simply ordering the list yourself as you place the instances in it.
 
B

Blaize

Guest
You are drawing them by order of instance id because you are pulling from instance_id array... you should be pulling from your list you made.

EDIT: Also, I can almost guarantee that the way you are using your priority_queue is likely slower than simply ordering the list yourself as you place the instances in it.
Yeah, I realized it as soon as I posted it lol. The draw code now looks like:
Code:
for (var i=0;i<ds_list_size(UIList);i++)
{
    var _id = UIList[|i];
    draw_text_color(0,i*16,string(_id)+",speed: "+string(_id.Speed),c_blue,c_blue,c_blue,c_blue,1);
}
Hmm the speed of it hadn't occurred to me. Would you happen to have any suggestions?
 
T

Timothy

Guest
Yeah, I realized it as soon as I posted it lol. The draw code now looks like:
Code:
for (var i=0;i<ds_list_size(UIList);i++)
{
    var _id = UIList[|i];
    draw_text_color(0,i*16,string(_id)+",speed: "+string(_id.Speed),c_blue,c_blue,c_blue,c_blue,1);
}
Hmm the speed of it hadn't occurred to me. Would you happen to have any suggestions?
If you only are dealing with a few instances, then its not an issue. If you are dealing with a lot and/or the sorting is happening often, then i would ditch the priority_queue and just insert into your list directly (keeping it ordered)
 
B

Blaize

Guest
If you only are dealing with a few instances, then its not an issue. If you are dealing with a lot and/or the sorting is happening often, then i would ditch the priority_queue and just insert into your list directly (keeping it ordered)
Ah, I see what you mean. At this stage, I don't think it'll be an issue since the max will be 10 instances and sorting is happening only once all active instances have had a turn (basically at the end of a round). I will keep your suggestion in mind though as it might actually be worth it after some more testing and implementation.
 
T

Timothy

Guest
Ah, I see what you mean. At this stage, I don't think it'll be an issue since the max will be 10 instances and sorting is happening only once all active instances have had a turn (basically at the end of a round). I will keep your suggestion in mind though as it might actually be worth it after some more testing and implementation.
Yeah 10 instances is nothing. But if you do decide to ditch the priority queue, its pretty simple to write a binary search algorithm to find which index you should insert at.

EDIT: I actually did a quick test. With my implementation, it was faster slightly faster to use a ds_priority for a smaller number of instances (but still in the 1000s) and magnitudes faster to do a binary search insert for larger number of instances (10s of 1000s)... which means its not beneficial in your case... with my implementation anyway.
 
Last edited by a moderator:
Top