Jump to content


Photo
- - - - -

Ai Command Stack


  • Please log in to reply
55 replies to this topic

#31 duaccelsostat

duaccelsostat

    GMC Member

  • New Member
  • 7 posts

Posted 12 December 2009 - 02:24 PM

IMHO it would be better to convert this all to a database structure. Stefano already made a nice concept for that.
but this is probably something that never gets done anyway, so.....EXCELLENT LIST

Roel
  • 0

#32 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 13 August 2011 - 08:24 PM

From another topic....

You don't realy need a command stack or list and I would not jump in this sort of thing before having done a few AIs first...

I can tell you about script switching which is how the command stack started and it's much more managable than a bunch of case statements

AI object
on create
curscript = WalkArround;

on step
script_execute(curscript);

script WalkArround
xx = random(room_width)
yy = random(room_height)
curscript = WalkToXY;

script WalkToXY
direction = point_direction(x,y,xx,yy);
speed = 3;
if(point_distance(x,y,xx,yy)< 10)
	curscript = WalkArround;


So now you have 2 scripts that switch between each other. One decides where to go, the other goes to it and when it's done, ressets the script to the original;

This method uses instance variables curscript and xx,yy, so no parameters to confuse you.

Now you can elaborate to a patrol and enemy (player) hunt

AI object
on create
curscript = PatrolArround;

on step
script_execute(curscript);

script PatrolArround
xx = random(room_width)
yy = random(room_height)
curscript = PatrolToXY;

script PatrolToXY
speed = 3;
player = instance_nearest(x,y,PlayerObj)
if(player)
{
	if(point_distance(x,y,player.x,player.y)<200)
	{
		curscript = AttackPlayer;
		exit;
	} 
}
direction = point_direction(x,y,xx,yy);
if(point_distance(x,y,xx,yy)< 10)
	curscript = PatrolArround;

scrip AttackPlayer
if(!instance_exists(player))
{
	curscript = PatrolToXY;
	exit;
}
if(point_distance(x,y,player.x,player.y)>200)
{
	curscript = PatrolToXY;
	exit;
}
speed = 5;
direction = point_direction(x,y,player.x,player.y)


The setup selects a random spot to patrol to. Patrols to it while checking if the player is near. If the player is near, he is attacked until he move too far. at that point, the patroltoXY continues and then when the patrol point is reached, another patrol point is randomly selected.


Hope it helps.

The command stack is a huge elaboration of this method and, in retrospect, this simpler method should have been explained first. It's much easier to implement, even if it does not allow for parameters (that can be remembered), you can use instance variables instead...
  • 0

#33 AtaKVeKtoR

AtaKVeKtoR

    GMC Member

  • New Member
  • 2 posts

Posted 18 November 2011 - 02:41 AM

Hi,

Just wondering if someone can help me, I get the following error when trying to use the script:

___________________________________________
ERROR in
action number 1
of Step Event
for object obj_orb_drone_cs:

Illegal argument count calling script "CommandStackPush".
Script requires 16 arguments, 6 have been supplied.

I have copied in all the CommandStack scripts into my project + the cmdComandObj.

I see that the CommandStackPush requires 16 arugments, however when checking out the tutorials, only the arguments used by the function to be put on the stack are used (ie. not 16 of them are required). Why can't I seem to replicate this in my scripts? do I need to pass 16 dummy arguments to the function?

Many thanks in advance.
  • 0

#34 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 18 November 2011 - 03:22 AM

pass 0s for the missing arguments. darn gm8.1 broke the flexible argument system... or change the way the arguments are referenced inside
  • 0

#35 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 17 December 2011 - 11:08 PM

pass 0s for the missing arguments. darn gm8.1 broke the flexible argument system... or change the way the arguments are referenced inside


I am attempting to use your suggestion, but its not working... Can you specify what you mean by passing 0's?
  • 0

#36 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 18 December 2011 - 12:22 AM

GM6,7,8 allowed passing a variable number of arguments, if one (trailing) argument was committed, 0 was assumed.

It sort of like in c++ where you can specify a default value from omitted arguments in the function declaration, but the default is 0 in GM


For example

Script DoIt

var count; count = argument0;

if(count == 0) count = 1;

repeat(count) ShowMessage("Hello")


if you call
DoIt(10), you would see a message 10 times
DoIt(1), you would see it 1 time
DoIt(), you would see it 1 time because the missing argument0 is converted to 0 in the script and the if in there sets it to default to 1.


Now gm8.1 broke this variable number of arguments feature to the detriment of many 3rd party extensions. So, CommandStackPush CAN takes up to 16 arguments. But most commands only take a few, like MoveToXY takes x,y,speed... that is 3, plus the script id, 4... so add ,0,0,0,0,0,0... as many as are missing to abide by the 16 argument gm8.1 thinks the script needs.

change
CommandStackPush (MoveToXY, destx, desty, speed)

to
CommandStackPush (MoveToXY, destx, desty, speed,0,0,0,0,0,0,0,0,0,0,0,0)

There is a way to fix the CommandStackPush And CommandListAdd and in another few places I think.

change
data.arg1 = argument1;
data.arg2 = argument2;
and so on

to
data.arg1 = 0;
if (argument_count > 1) data.arg1 = argument[1];
data.arg2 = 0;
if (argument_count > 2) data.arg2 = argument[2];

and so on all the way to 15... for all core functions that set the data.args using argumentN naming convention...


I cant test this as I am afraid to update my earlier release of gm8.1 to the latest release and loose my key. My gm8.1 does not have this bug... I mean feature.
  • 0

#37 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 22044 posts
  • Version:GM:Studio

Posted 18 December 2011 - 12:38 AM

Icuurd, this can be turned off in the global game settings... it was changed to permit backwards compatibility in just this type of scenario.
  • 0

#38 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 18 December 2011 - 01:13 AM

I can uploud a new, edited version just for GM81 if you want. I fully edited it. But i wont be able to host it indefinitly. You will have to find a mirror... Here

http://dl.dropbox.co...mmandstack.gm81

Edited by SirGuy, 18 December 2011 - 01:36 AM.

  • 0

#39 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 18 December 2011 - 02:05 AM

Since i got it working, Can you please post an example of a more "complex" command stack? The ones you have in your example seem very basic. I need something far more advanced to see what I can actually do with it. Please and thank you.
  • 0

#40 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 18 December 2011 - 03:38 AM

Desktop Death Match is a good example, see main post


Here is a very complicated setup

http://www.host-a.ne...2/station16.gmk


arrows move, shift and z to shoot, t to tractor on and off

Move to the bottom, tag a cylinder with your tractor beam. then use the tractor beam to move and attach another cylinder to the first one, tractor and push it and release before it hits the cylinder, both should snap together. add modules (on top of the cylinders) to your station, a power source, a radar (it will tag you as friendly if you avoided the already built station at the top), a asteroid beam, a processing platform.... Once tagged by your station, the other ships should attack you if too close. Meanwhile they gather resources.

The AI ships are controlled with the command stack. The player ship also is. that way you could take control of another ship byt simply adding the pleyer control script to the ai ship stack.
  • 0

#41 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 18 December 2011 - 08:17 PM

Desktop Death Match is a good example, see main post


Here is a very complicated setup

http://www.host-a.ne...2/station16.gmk


arrows move, shift and z to shoot, t to tractor on and off

Move to the bottom, tag a cylinder with your tractor beam. then use the tractor beam to move and attach another cylinder to the first one, tractor and push it and release before it hits the cylinder, both should snap together. add modules (on top of the cylinders) to your station, a power source, a radar (it will tag you as friendly if you avoided the already built station at the top), a asteroid beam, a processing platform.... Once tagged by your station, the other ships should attack you if too close. Meanwhile they gather resources.

The AI ships are controlled with the command stack. The player ship also is. that way you could take control of another ship byt simply adding the pleyer control script to the ai ship stack.


Ok, im looking at the shipobj, and this is in the beggining of the step event

if(CommandsPerform() = 0) 
{
    CommandStackPush(MainScript);
}

VelocityStep();
RotationStep();

So, if i understand correctly, You initialize the com stack in the create event, Then in the step event for the AI, you make
if(CommandsPerform() = 0) 
{
    CommandStackPush(MainScript);
}
Then you list the scripts you want exocuted, in the line you want them done in?

Edited by SirGuy, 18 December 2011 - 08:20 PM.

  • 0

#42 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 18 December 2011 - 09:15 PM

MainScript is a variable than can hold either cmdPlayerControlor cmdPatrolForRocksRandom. as an initiator. Look at cmdPatrolForRocksRandom (or whatever I named it) this is the start of the AI brain.


Basically, if it's the player controlling the ship, that code in the step just calls cmdPlayerControl every step, but in a round about way. (I was planing to allow player control on all ships, that is why it's like that)


However, for AIs it's cmdPatrolForRocksRandom, the command list and stacks will grow and shrink and grow and shrink until everything is resolved.... Then it starts all over again.

I think I forget to add the state to attack enemy... you can push cmdPatrolToXY self.x,self.y in the AIship in an alarm that check every second. Or just set the Mainscript to patrol random if you want to see a fight.

I was planing for the station to issue orders to ships, play with each of their commands list and stack remotely to issue attack orders. And to have wing leader (the player) issue command to wing squad. So the basic behavior was to gather resources until someone told them to attach (push the attack script in the stack)

You can loose you mind pretty fast if you dont document your behavior.
  • 0

#43 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 18 December 2011 - 09:49 PM

I am loosing my mind. I have no idea what i am missing, but i am missing something. I am still not understanding what this is doing! Like, i see no clear indacation in the code where you are doing

:start
(1)Go to 5,43
(2)mine
(3)Return
(4)Dump what you mined
(5)goto start

EDIT:

Wait a second. I thought you had the scripts all seperate, so the master script would call one, when that one was over it would call the next, and so on. But the way you have it, One script calls the next, yes?

Edited by SirGuy, 18 December 2011 - 10:29 PM.

  • 0

#44 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 18 December 2011 - 11:47 PM

The main command script, the foundation of the AI mind is usually in charge of deciding what to push in the stack.


on create, you create a command stack space

on step, you call the command stack to perform it's <current> action, if the return says it's done, you reset/re-add the default behavior. It can be a single script, a main command script, or you could add a few things to do, like say define a set of patrol points to go to... I prefer to have the main script do that.

on destroy, you destroy the command stack


That is really only 3 things you object need doing

create
CommandsCreate();

step
//Perform the AI task list
if(CommandsPerform() = 0) 
{
    CommandListAdd(AIMainScript, whatever, arguments, that, script, needs);
or
    CommandStackPush(AIMainScript, whatever, arguments, that, script, needs);
}
The difference between list and stack, list items are done one after the other, stack items are performed last in first out. But this is discussed in the main post

on destroy
CommandsFree();

oh, room end event
on room end
if(!persitent and !room_persitent) CommandsFree();

That is the core of the system.

AIMainScript is the core of your system. If you simply put all your AI code in there, without using the system anymore, not pushing more of your smart scripts, then might as well not use the command stack at all.

That said, say you want to make a capture the flag AI, I wont talk about the script pre-processing, or about the fact you can make the script execute and pop out early, just the logic.

AIMainScript
CommandStackPush (MoveToFlag, thespeed);
MoveToFlag
if(global.FlagHolder != id and instance_exists(global.FlagHolder)) CommandStackPush (FindFlagHolder, thespeed), exit;
MoveTowardsWhileFighting( flag.x, flag.y, thespeed)
FindFlagHolder
MoveTowardsWhileFighting( FlagHolder.x, FlagHolder.y, thespeed)
MoveFlagToBase
MoveTowardsWhileFighting (base.x, base.y, thespeed)
On AI Collision With flag
with(flag) instance_destoy();
global.FlagHolder = id;
CommandStackPush (MoveFlagToBase, thespeed);
On AI destroy
if(global.FlagHolder == id) instance_create(x,y,flag)
CommandsClear();

  • 0

#45 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 19 December 2011 - 11:23 PM

Where is the command stack supposed to stop? I figured out how to use it, but it keeps giving this error when the AI hits the waypoint that i made...

ERROR in
action number 1
of Step Event
for object obj_military:

Trying to execute non-existing script.

Why? It doesnt give this error when the AI goes for an enemy before going for the waypoint, so why isnt it working?
  • 0

#46 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 19 December 2011 - 11:54 PM

is it possible you have a script name that has the same name as a sprite or an object
  • 0

#47 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 20 December 2011 - 12:38 AM

No, all our sprites are named spr_something, and all our obj's are named obj_something. What gives? I can pm you the gmk if you want to take a closer look at it.
  • 0

#48 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 20 December 2011 - 07:55 PM

No, all our sprites are named spr_something, and all our obj's are named obj_something. What gives? I can pm you the gmk if you want to take a closer look at it.


quite simply

change
CommandListAdd(AIMilitary());

to
CommandListAdd(AIMilitary);

See you need to pass the script id, you were calling CommandListAdd passing AIMilitary()... GM executed AIMilitary() right there and CommandListAdd added the return result of AIMilitary()
  • 0

#49 Sir

Sir

    Jedi Poodoo

  • GMC Member
  • 384 posts
  • Version:GM:Studio

Posted 20 December 2011 - 10:10 PM

Worked like a charm. Thank you.
  • 0

#50 4 KINGS

4 KINGS

    BioThirst Studio

  • New Member
  • 549 posts
  • Version:GM8

Posted 27 January 2012 - 05:57 AM

sabotage?

P.S. I was talking about the spam above me that is now gone.
P.S.S. I'm not insane...... ...... it really was there!

Edited by 4 KINGS, 27 January 2012 - 08:01 AM.

  • 1

#51 yodamerlin

yodamerlin

    GMC Member

  • GMC Member
  • 179 posts
  • Version:GM8.1

Posted 25 December 2012 - 09:13 PM

I don't know if anyone will read this. However I want to have pathfinding in a topdown however I don't get how to use the pathfinding at all. I have seen the demo but it makes no sence to me, anyone, help.
  • 0

#52 yodamerlin

yodamerlin

    GMC Member

  • GMC Member
  • 179 posts
  • Version:GM8.1

Posted 25 December 2012 - 09:14 PM

I don't know if anyone will read this. However I want to have pathfinding in a topdown however I don't get how to use the pathfinding at all. I have seen the demo but it makes no sence to me, anyone, help.
  • 0

#53 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 26 December 2012 - 06:54 AM

I don't know if anyone will read this. However I want to have pathfinding in a topdown however I don't get how to use the pathfinding at all. I have seen the demo but it makes no sence to me, anyone, help.


If it's too intense, I find it too intense reading it now, you probably would benefit from make your own similar but less complete system
  • 0

#54 hans80

hans80

    GMC Member

  • GMC Member
  • 26 posts

Posted 04 September 2013 - 04:11 PM

links are down :(

plz reup 8.1 version, thx

 

edit: works again :)


Edited by hans80, 05 September 2013 - 08:51 AM.

  • 0

#55 TheMagician

TheMagician

    GMC Member

  • GMC Member
  • 554 posts

Posted 24 April 2014 - 11:01 PM

Thank your for your great work, icuurd!

Just as you've susgested in THIS TOPIC I use it to create a command list system for an adventure game engine.

I've just converted my favourite AGS function into GML: Wait(steps)  :thumbsup:

 

A hint for people who want to use this in GameMaker: Studio. There will be a long list of error messages when you first try to start the demo.

However, this is very simple to fix. Just find the following scripts:

  • CommandStackSequenceAdd
  • CommandListAdd
  • CommandStackPush

In each of them replace any occurence of argument0 with argument[0]. Everything works great then.


  • 1

#56 icuurd12b42

icuurd12b42

    Self Formed Sentient

  • GMC Elder
  • 16055 posts
  • Version:GM:Studio

Posted 25 April 2014 - 02:31 AM

Thanks!


  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users