Map Database  •  FAQ  •  RSS  •  Login

Dynamic Script Usage Questions

<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 06 Jul 2013, 02:12

Re: Dynamic Script Usage

What do you mean States.UnitPositionX and States.UnitPositionY are nasty for the Remake? They should just be simple commands that tell you where the unit is. Or did you mean UnitAt is nasty?
For example, I had this script that decreased the hunger level as a function of their movements, so much moving units get hungry more quickly than units that stand still. This implies looping through all units, store their x,y and compare and update this regularly. However, with the mentioned 2400 units and a check every 4 seconds this is unbearable. I've tried to find out what is actually so CPU-intensive; I've found that things like adding some hunger to 2400 units is much less CPU-intensive than, for example, querying a position of a unit. So, thats what I meant with 'nasty' :wink:
a) Use UnitAt to scan each tile in the area.
b) Scan through GetAllUnits and check their positions.
As told, I tried both. In the current form in my script they are both causing lags when upscaled, so I need to do smart stuff. I already have lots of 'continue' and 'break' in my loops to avoid any calculations whereas possible, but that is not sufficient so far. PlayerGetAllGroups is unsufficient, as I need citizens to be detected as well.
It is also possible to spread out processing of a) over multiple ticks. You can use tricks like processing every 2nd row of the map (e.g. Y=2,4,6 one tick, then Y=1,3,5 next tick).
I will probably do something like this. Did already tricks like this to this script that puts back the fog of war at places where units haven't been for a while. Initially VERY cpu intensive for big maps, because it needs to figure out which places of the map haven't been within the 'seeing' range of units for some period of time. I got it more efficient in three ways: 1) reducing the interval to perform calculations, 2) calculate just a part of the map each time, 3) reducing the calculations with a factor 16 by 'translating' the unit / fog data onto a virtual twodimensional array which is 4x4 as small as the map, and treating it as if it contains actual fog of war data.

For the detection of units, I am now thinking about this:
- every large interval, loop through all units and calculate any units that might come within proximity soon (like 20x20 tiles maybe) and store those into a private array for this detector
- in short intervals, only loop through the private detector array, and the first unit which is within circular range...well has a problem :mrgreen:
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 06 Jul 2013, 02:39

Re: Dynamic Script Usage

What do you mean States.UnitPositionX and States.UnitPositionY are nasty for the Remake? They should just be simple commands that tell you where the unit is. Or did you mean UnitAt is nasty?
For example, I had this script that decreased the hunger level as a function of their movements, so much moving units get hungry more quickly than units that stand still. This implies looping through all units, store their x,y and compare and update this regularly. However, with the mentioned 2400 units and a check every 4 seconds this is unbearable. I've tried to find out what is actually so CPU-intensive; I've found that things like adding some hunger to 2400 units is much less CPU-intensive than, for example, querying a position of a unit. So, thats what I meant with 'nasty' :wink:
Querying the position should take about the same amount of time as adding hunger, but if you are doing both, and storing the position, and comparing it to what it was last time, that's a lot more processing that simply adding hunger. But in general UnitHungerSet and UnitPositionX (or Y) should take about the same amount of time to run.
For the detection of units, I am now thinking about this:
- every large interval, loop through all units and calculate any units that might come within proximity soon (like 20x20 tiles maybe) and store those into a private array for this detector
- in short intervals, only loop through the private detector array, and the first unit which is within circular range...well has a problem :mrgreen:
That might work, although you might find it lags on the large update intervals. You really want to spread things out between ticks, just doing a major update every 10 seconds and a minor update every second doesn't solve the problem because the game will still lag every 10 seconds (and any lag is bad). You want to design it to do a small amount of the processing every tick, by e.g. processing rows of the area in turns (so if you have a 20x20 area, on the first tick process rows 1 and 11, then 2 and 12, 3 and 13, etc. Here's an example:
  Code:
for Y :=1 to Height do if (States.GameTime+Y) mod 10 = 0 then for X := 1 to Width do //Your progressing for tile X,Y goes here
If you run that code every tick it will cycle through every row (after 10 ticks it will have progressed all rows). That is what you should be aiming for, don't do massive amounts of processing on any one tick, but instead use every tick to do a small amount of processing.
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 08 Jul 2013, 16:42

Re: Dynamic Script Usage

Hi

I have a question. I want to give a player a group every minute. But i want this only when the tiles are not occupied. I test it with one tile but it didn't work how i want. The first group appeared, then i get a message and then a new group appeared but i don't get a message. When those first two groups appeared nothing else happened. When i send only the second group away no more groups appeared. But if i send only the first group away more groups appeared after some time. When i send the first group away a message showed directly.

Now i want to ask what the propper way is to make this.
This is my script of the map.
  Code:
var Sword: Integer; PlacedSword: Boolean; Procedure OnMissionStart; begin PlacedSword := False; end; Procedure OnTick; begin if (States.GameTime mod 600 = 0) and not (States.PlayerDefeated (0)) and not PlacedSword then begin PlacedSword := True; Sword := States.GroupAt (4, 5); Actions.GiveGroup (0, 16, 4, 5, 4, 9, 3); end; begin if Sword = States.GroupAt (4, 5) then Exit; if PlacedSword then begin PlacedSword := False Actions.ShowMsg (0, 'Hello') end; end; end;
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 09 Jul 2013, 02:58

Re: Dynamic Script Usage

Why do you have that "begin..end" block with nothing before it? (above the line "if Sword = States.GroupAt (4, 5) then") It would run exactly the same if you deleted the "begin" and "end" lines. Maybe that's not what you wanted?

I don't understand what the variable Sword and PlacedSword are supposed to do. Maybe you could write some comments in your code?
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 11 Jul 2013, 14:24

Re: Dynamic Script Usage

How can i make a delay in script? I want when enemy groups died, destroy a house and put a new house right there with script. I think this can't at the same time. :?
Would someone tell my how to make a delay?
<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 11 Jul 2013, 14:42

Re: Dynamic Script Usage

No you cannot do it immediately at the same time, that's correct. What I do personally is defining a global variable like TimeOfHouseDestruction and set this to zero. When the house is destroyed (you can use OnHouseDestroyed) you should store the GameTime in that variable. Now you only have to create a script within OnTick that says something like this: when (GameTime > (TimeOfHouseDestruction + DelayTime)) and (TimeOfHouseDestruction <> 0) then... You can define any DelayTime or just use 0 if it should be the first new tick after destruction. Don't forget to set TimeOfHouseDestruction to 0 in that script, otherwise it will repeat that action every tick after house destruction.

Off course, this is one possibility, but this is roughly how I do it. Good luck!
<<

Islar

Pikeman

Posts: 180

Joined: 22 Apr 2013, 20:18

KaM Skill Level: Average

Location: The Netherlands

Post 11 Jul 2013, 15:48

Re: Dynamic Script Usage

I have now this but the actions do not trigger.
  Code:
var TimeOfHouseDestruction, GameTime, DelayTime: Integer; procedure OnMissionStart; begin GameTime := States.GameTime; DelayTime := 10; TimeOfHouseDestruction := 0; end; procedure OnTick; Begin If (GameTime > (TimeOfHouseDestruction + DelayTime)) and (TimeOfHouseDestruction <> 0) then begin TimeOfHouseDestruction := 0; Actions.GiveHouse (0, 11, 43, 44); Actions.ShowMsg (0, 'Test') end; end; procedure OnHouseDestroyed (aHouseID: Integer; aDestroyerIndex: Integer); begin If States.HouseDestroyed (Store2) then begin TimeOfHouseDestruction := States.GameTime; end; end;
Could you tell my were i misunderstood you :|
<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 11 Jul 2013, 17:03

Re: Dynamic Script Usage

You say: If States.HouseDestroyed (Store2) but I don't see you defining Store2 somewhere. So, define Store2 by saying Store2 := States.HouseAt(x,y) for example. Also, when that storehouse is destroyed, the OnHouseDestroyed event is triggered automatically with its parameters aHouseID and aDestroyerIndex known, so you can say: if aHouseID = Store2 instead of if States.HouseDestroyed (Store2). And you should use States.GameTime instead of GameTime. Also store States.GameTime into your variable upon house destruction.

* EDIT: Islar's script has been fixed.
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 11 Jul 2013, 23:57

Re: Dynamic Script Usage

There are other problems with your script Islar, you only set the variable "GameTime" during OnMissionStart, so for the entire mission it will be equal to 0 (so the script would be the same if you replaced GameTime with 0). Why do you need that global variable? Just use States.GameTime instead.

Actually, at the moment I think you can destroy houses and rebuild them instantly, but this could change in the future because it could be a source of errors if the house is not ready to be destroyed. Units are not killed instantly, they take 1 tick before they start dying.
<<

Duke Valennius

User avatar

Militia

Posts: 44

Joined: 10 Jul 2013, 11:01

KaM Skill Level: Average

Post 19 Jul 2013, 16:46

Re: Dynamic Script Usage

Hello, is there a way to find out if player has permanently left multiplayer game? (lost connection - reconnect doesn't count)
It seems that PlayerEnabled and PlayerDefeated both return as if he was still playing. (enabled and not defeated)
I'm sorry if I missed something in reference.
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 19 Jul 2013, 19:26

Re: Dynamic Script Usage

Hello, is there a way to find out if player has permanently left multiplayer game? (lost connection - reconnect doesn't count)
It seems that PlayerEnabled and PlayerDefeated both return as if he was still playing. (enabled and not defeated)
I'm sorry if I missed something in reference.
No, you can't tell that from the script. Players leaving is not something that affects the game play, (e.g. it's not recorded in replays) so the script must not have access to it. Currently the players keep working as if nothing happened even if their owner has left the game.

What did you want to use it for?
<<

Duke Valennius

User avatar

Militia

Posts: 44

Joined: 10 Jul 2013, 11:01

KaM Skill Level: Average

Post 20 Jul 2013, 07:35

Re: Dynamic Script Usage

Hello, is there a way to find out if player has permanently left multiplayer game? (lost connection - reconnect doesn't count)
It seems that PlayerEnabled and PlayerDefeated both return as if he was still playing. (enabled and not defeated)
I'm sorry if I missed something in reference.
No, you can't tell that from the script. Players leaving is not something that affects the game play, (e.g. it's not recorded in replays) so the script must not have access to it. Currently the players keep working as if nothing happened even if their owner has left the game.

What did you want to use it for?
I constantly resupply players with weapons and recruits, with same amount going for each team (so that if there is 1 player in team A, and 4 players in team B, both teams receive same amounts). If player is defeated, everything goes well. However, if he disconnects, weapons are still given to him, and his team is in disadvantage. If he could be proclaimed defeated when he disconnects, it would work fine.
I guess it is same problem as in regular multiplayer games, but it would be nice to solve it.
<<

Lewin

User avatar

KaM Remake Developer

Posts: 3822

Joined: 16 Sep 2007, 22:00

KaM Skill Level: Skilled

ICQ: 269127056

Website: http://lewin.hodgman.id.au

Yahoo Messenger: lewinlewinhodgman

Location: Australia

Post 20 Jul 2013, 07:52

Re: Dynamic Script Usage

I constantly resupply players with weapons and recruits, with same amount going for each team (so that if there is 1 player in team A, and 4 players in team B, both teams receive same amounts). If player is defeated, everything goes well. However, if he disconnects, weapons are still given to him, and his team is in disadvantage. If he could be proclaimed defeated when he disconnects, it would work fine.
I guess it is same problem as in regular multiplayer games, but it would be nice to solve it.
We are planning to count players who have quit (or the host chose to continue playing without them when they disconnect) as defeated, it's been on the todo list for a while. That should solve it for you :)
<<

Tef

User avatar

Lance Carrier

Posts: 64

Joined: 15 Apr 2013, 15:12

KaM Skill Level: Skilled

Post 05 Aug 2013, 22:20

Re: Dynamic Script Usage

Bug? -> It seems impossible to add a tree to a woodcutter's through Actions.HouseAddWaresTo().
<<

Ben

User avatar

Former Site Admin

Posts: 3814

Joined: 08 Jan 2009, 23:00

Location: California - Pacific Time (UTC -8/-7 Summer Time)

Post 06 Aug 2013, 04:52

Re: Dynamic Script Usage

That's because you cannot place a "product" in a building. You can only place the raw material. For example, you can only place pigs in butchers, and not sausages ;)

Why? I have no idea. Maybe it will be fixed one day :)
I used to spam this forum so much...

Return to “Dynamic Scripting”

Who is online

Users browsing this forum: No registered users and 2 guests