wiki info on custom commands?

wiki info on custom commands?

Various things about Spring that do not fit in any of the other forums listed below, including forum rules.

Moderator: Moderators

Post Reply
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

wiki info on custom commands?

Post by gajop »

Are custom commands explained in the wiki anywhere?
EDIT: This is the closest I've come to an example: https://springrts.com/wiki/SetMoveTypeDataExample
I didn't find any manual/reference for this, just random callins.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Re: Wiki: issues + quick questions/answers

Post by FLOZi »

Looks like not, there was some good stuff on the Q&A about this, but that is gone of course :(
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Wiki: issues + quick questions/answers

Post by Silentwings »

I think that this https://github.com/SpringCabal/Corrupti ... h_life.lua (which we just made for LD) would make a good simple example of how to make a custom command & could be easily made into a wiki article.
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Wiki: issues + quick questions/answers

Post by gajop »

Silentwings wrote:I think that this https://github.com/SpringCabal/Corrupti ... h_life.lua (which we just made for LD) would make a good simple example of how to make a custom command & could be easily made into a wiki article.
Is that actually correct though? I've coded the logic of this one to happen in the AllowCommand callin, but it seems odd to me that the effect should be there too -> I just assumed AllowCommand is a "OK, you can do this command, add it to the queue", where the UnitCommand callin would actually execute it.
Maybe it depends on the type of the command. I assume most state-change (e.g. fire/move state) commands would be executed immediately in the AllowCommand and others (attack, patrol, build, cast spell) would be executed somewhere else.

Also how does one control the following:
- range (if unit, area or a position is a target)
- cooldown
- ^ how these two can be dynamically changed (by putting the command on/off cooldown or extending/shortening range, if possible)
- facing (whether or not a unit needs to face the target)
- extensibility with lups or ceg (which while it might seem out of scope to define here, users should still know where to add it)

Imo, the above is what a wiki article needs, and I'm not offering to make it right now due to lack of experience.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Wiki: issues + quick questions/answers

Post by Silentwings »

In some ways it would be better to action the command in UnitCommand, since then UnitCommand can also be used elsewhere to see that the command happened. But in this case we want to the command to be actioned instantly (at least, that's what I thought you wanted) and only one other place needs to be told what happened, so I decided it was simpler to block the command in AllowCommand (so as it doesn't go into the queue, but also doesn't go through UnitCommand) and instead broadcast its effect (i.e. the corruption level) in a TeamRulesParam. Updated link with comment to say that: https://github.com/SpringCabal/Corrupti ... h_life.lua

In general handling queueing for custom commands is not easy, because iirc there is no callin that tells you when a unit has finished doing a command. I've even seen custom commands which implemented their own queue in lua, in parallel to the normal command queue. I'm not sure what is best to put in a simple example there.

Not entirely sure what you mean by cooldown, but there are callouts to handle all the other things you mention. I don't think it's worth trying to guess what a user implementing a custom command would want it to actually do, since there are so many different things one could want, and it's better just to rely on them finding the necessary stuff for whatever they want to action elsewhere in the wiki.
8611
XTA Developer
Posts: 242
Joined: 29 Dec 2014, 08:22

Re: Wiki: issues + quick questions/answers

Post by 8611 »

iirc there is no callin that tells you when a unit has finished doing a command.
There is UnitCmdDone()

I've coded the logic of this one to happen in the AllowCommand callin, but it seems odd to me that the effect should be there too -> I just assumed AllowCommand is a "OK, you can do this command, add it to the queue", where the UnitCommand callin would actually execute it.
Maybe it depends on the type of the command. I assume most state-change (e.g. fire/move state) commands would be executed immediately in the AllowCommand and others (attack, patrol, build, cast spell) would be executed somewhere else.
https://springrts.com/wiki/SetMoveTypeDataExample is a state-change command, so AllowCommand seems okay.
On other hand the life-leech gadget seems more like an action similiar to attack, that should not be immediately.
Player can select a target etc, unit probally has to move into range before it can execute the attack, the action should be queue-able and so on.
Imo best handled with CommandFallBack() ,it is documentated in wiki.

Any way is to put the all actual logic (setting unit health/states, moving in range, spawning effects, animations,..) of an action that takes a while to complete into GameFrame() and CommandFallBack() merely returns "finished=true" once the action is complete.

Also how does one control the following:
- range (if unit, area or a position is a target)
- cooldown
- facing (whether or not a unit needs to face the target)
It comes down to question: "How can a command be blocked based on a condition?"
The life-leech gadget already does some check:

Code: Select all

if not Spring.ValidUnitID(targetUnitID) or Spring.GetUnitIsDead(targetUnitID) then return false end
So the action is already limited to target only not-dead units.
Limiting by range or cooldown works no different, so just add more conditions in similiar way

Code: Select all

if (distance (unit, target) > 400) then ... 
if getUnitMana (unit) < 20 then ...
- ^ how these two can be dynamically changed (by putting the command on/off cooldown or extending/shortening range, if possible)
In above conditions replace the numbers constants with values read from UnitRulesParam(unitID) or some table or whatever.

Code: Select all

if (distance (unit, target) > spGetUnitRulesParam(unitID, "lifeLeechRange"))then ...  
To change button descriptions or disabling buttons: EditUnitCmdDesc()
extensibility with lups or ceg
"Extensibility" seems like bit strange word: Such things become clear when writing a gadget.
If the gadget makes a unit lose/gain health with SetUnitHealth() then author naturally understands where to call SpawnCEG("blood-splatter") to make the blood-splatter-effect (or whatever) appear at good moment.
gajop
Moderator
Posts: 3051
Joined: 05 Aug 2009, 20:42

Re: Wiki: issues + quick questions/answers

Post by gajop »

8611 wrote:https://springrts.com/wiki/SetMoveTypeDataExample is a state-change command, so AllowCommand seems okay.
On other hand the life-leech gadget seems more like an action similiar to attack, that should not be immediately.
Player can select a target etc, unit probally has to move into range before it can execute the attack, the action should be queue-able and so on.
Yeah, this was my intuition as well.
8611 wrote: Imo best handled with CommandFallBack() ,it is documentated in wiki.
I thought so too, but something wasn't working when I tried it. Maybe because I didn't have the AllowCommand, or maybe I just had a bug elsewhere. I'll try again when I have time.
8611 wrote: Any way is to put the all actual logic (setting unit health/states, moving in range, spawning effects, animations,..) of an action that takes a while to complete into GameFrame() and CommandFallBack() merely returns "finished=true" once the action is complete.
Aha, OK, I think I understand this now.
8611 wrote:
Also how does one control the following:
- range (if unit, area or a position is a target)
- cooldown
- facing (whether or not a unit needs to face the target)
It comes down to question: "How can a command be blocked based on a condition?"
The life-leech gadget already does some check:

Code: Select all

if not Spring.ValidUnitID(targetUnitID) or Spring.GetUnitIsDead(targetUnitID) then return false end
So the action is already limited to target only not-dead units.
Limiting by range or cooldown works no different, so just add more conditions in similiar way

Code: Select all

if (distance (unit, target) > 400) then ... 
if getUnitMana (unit) < 20 then ...
This is maybe because I misunderstood something, but I guess I also wanted to communicate to the Lua widget about the range of the command, the required facing and the cooldown. For the range and the facing, this is so it would be displayed in the UI (the range) and so the unit would get into range/proper facing when this command is given.
The question about the cooldown is basically on how to communicate to the widgets (UI) that the command was successfully done (if it's a state-changing command). State-changing commands would be immediately executed in AllowCommand and would return false, which basically means that they were denied, and it's not clear if they were denied because some condition wasn't met, or if they were actually executed.

Basically, regardless if they failed because of

Code: Select all

if (distance (unit, target) > 400) then ... 
if getUnitMana (unit) < 20 then ...
or succeeded,
false will be returned.

Maybe instead AllowCommand should still return true and be executed in the CommandFallBack immediately?
8611 wrote: In above conditions replace the numbers constants with values read from UnitRulesParam(unitID) or some table or whatever.

Code: Select all

if (distance (unit, target) > spGetUnitRulesParam(unitID, "lifeLeechRange"))then ...  
To change button descriptions or disabling buttons: EditUnitCmdDesc()
This might be a better option for the above problem maybe? Is this how gadgets tell widgets that state-changing command was executed?
8611 wrote:"Extensibility" seems like bit strange word: Such things become clear when writing a gadget.
If the gadget makes a unit lose/gain health with SetUnitHealth() then author naturally understands where to call SpawnCEG("blood-splatter") to make the blood-splatter-effect (or whatever) appear at good moment.
You're probably right, this is out of scope.
Post Reply

Return to “General Discussion”